Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.beans.property.adapter;
027
028import com.sun.javafx.property.adapter.ReadOnlyPropertyDescriptor;
029import javafx.beans.property.ReadOnlyIntegerPropertyBase;
030
031import java.lang.reflect.InvocationTargetException;
032import java.lang.reflect.UndeclaredThrowableException;
033import sun.misc.Cleaner;
034
035import java.security.AccessController;
036import java.security.AccessControlContext;
037import java.security.PrivilegedAction;
038
039import sun.reflect.misc.MethodUtil;
040
041/**
042 * A {@code ReadOnlyJavaBeanIntegerProperty} provides an adapter between a regular
043 * read only Java Bean property of type {@code int} or {@code Integer} and a JavaFX 
044 * {@code ReadOnlyIntegerProperty}. It cannot be created directly, but a 
045 * {@link ReadOnlyJavaBeanIntegerPropertyBuilder} has to be used.
046 * <p>
047 * As a minimum, the Java Bean must implement a getter for the
048 * property. If the getter of an instance of this class is called, the property of 
049 * the Java Bean is returned. If the Java Bean property is bound (i.e. it supports
050 * PropertyChangeListeners), this {@code ReadOnlyJavaBeanIntegerProperty} will be 
051 * aware of changes in the Java Bean. Otherwise it can be notified about
052 * changes by calling {@link #fireValueChangedEvent()}.
053 * 
054 * @see javafx.beans.property.ReadOnlyIntegerProperty
055 * @see ReadOnlyJavaBeanIntegerPropertyBuilder
056 */
057public final class ReadOnlyJavaBeanIntegerProperty extends ReadOnlyIntegerPropertyBase implements ReadOnlyJavaBeanProperty<Number> {
058
059    private final ReadOnlyPropertyDescriptor descriptor;
060    private final ReadOnlyPropertyDescriptor.ReadOnlyListener<Number> listener;
061
062    private final AccessControlContext acc = AccessController.getContext();
063
064    ReadOnlyJavaBeanIntegerProperty(ReadOnlyPropertyDescriptor descriptor, Object bean) {
065        this.descriptor = descriptor;
066        this.listener = descriptor.new ReadOnlyListener<Number>(bean, this);
067        descriptor.addListener(listener);
068        Cleaner.create(this, new Runnable() {
069            @Override
070            public void run() {
071                ReadOnlyJavaBeanIntegerProperty.this.descriptor.removeListener(listener);
072            }
073        });
074    }
075
076    /**
077     * {@inheritDoc}
078     * 
079     * @throws UndeclaredThrowableException if calling the getter of the Java Bean
080     * property throws an {@code IllegalAccessException} or an 
081     * {@code InvocationTargetException}.
082     */
083    @Override
084    public int get() {
085        return AccessController.doPrivileged(new PrivilegedAction<Integer>() {
086            public Integer run() {
087                try {
088                    return ((Number)MethodUtil.invoke(
089                        descriptor.getGetter(), getBean(), (Object[])null)).intValue();
090                } catch (IllegalAccessException e) {
091                    throw new UndeclaredThrowableException(e);
092                } catch (InvocationTargetException e) {
093                    throw new UndeclaredThrowableException(e);
094                }
095            }
096        }, acc);
097    }
098
099    /**
100     * {@inheritDoc}
101     */
102    @Override
103    public Object getBean() {
104        return listener.getBean();
105    }
106
107    /**
108     * {@inheritDoc}
109     */
110    @Override
111    public String getName() {
112        return descriptor.getName();
113    }
114
115    /**
116     * {@inheritDoc}
117     */
118    @Override
119    public void fireValueChangedEvent() {
120        super.fireValueChangedEvent();
121    }
122
123    /**
124     * {@inheritDoc}
125     */
126    @Override
127    public void dispose() {
128        descriptor.removeListener(listener);
129    }
130}