1 /*
2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javafx.beans.property.adapter;
27
28 import com.sun.javafx.property.adapter.Disposer;
29 import com.sun.javafx.property.adapter.ReadOnlyPropertyDescriptor;
30 import javafx.beans.property.ReadOnlyObjectPropertyBase;
31
32 import java.lang.reflect.InvocationTargetException;
33 import java.lang.reflect.UndeclaredThrowableException;
34
35 import java.security.AccessController;
36 import java.security.AccessControlContext;
37 import java.security.PrivilegedAction;
38
39 import sun.reflect.misc.MethodUtil;
40
41 /**
42 * A {@code ReadOnlyJavaBeanObjectProperty} provides an adapter between a regular
43 * read only Java Bean property of {@code T} and a JavaFX
44 * {@code ReadOnlyObjectProperty}. It cannot be created directly, but a
45 * {@link ReadOnlyJavaBeanObjectPropertyBuilder} has to be used.
46 * <p>
47 * As a minimum, the Java Bean must implement a getter for the
48 * property. If the getter of an instance of this class is called, the property of
49 * the Java Bean is returned. If the Java Bean property is bound (i.e. it supports
50 * PropertyChangeListeners), this {@code ReadOnlyJavaBeanObjectProperty} will be
51 * aware of changes in the Java Bean. Otherwise it can be notified about
52 * changes by calling {@link #fireValueChangedEvent()}.
53 *
54 * @see javafx.beans.property.ReadOnlyObjectProperty
55 * @see ReadOnlyJavaBeanObjectPropertyBuilder
56 *
57 * @param T the type of the wrapped {@code Object}
58 * @since JavaFX 2.1
59 */
60 public final class ReadOnlyJavaBeanObjectProperty<T> extends ReadOnlyObjectPropertyBase<T> implements ReadOnlyJavaBeanProperty<T> {
61
62 private final ReadOnlyPropertyDescriptor descriptor;
63 private final ReadOnlyPropertyDescriptor.ReadOnlyListener<T> listener;
64
65 private final AccessControlContext acc = AccessController.getContext();
66
67 ReadOnlyJavaBeanObjectProperty(ReadOnlyPropertyDescriptor descriptor, Object bean) {
68 this.descriptor = descriptor;
69 this.listener = descriptor.new ReadOnlyListener<T>(bean, this);
70 descriptor.addListener(listener);
71 Disposer.addRecord(this, new DescriptorListenerCleaner(descriptor, listener));
72 }
73
74 /**
75 * {@inheritDoc}
76 *
77 * @throws UndeclaredThrowableException if calling the getter of the Java Bean
78 * property throws an {@code IllegalAccessException} or an
79 * {@code InvocationTargetException}.
80 */
81 @Override
82 public T get() {
83 return AccessController.doPrivileged((PrivilegedAction<T>) () -> {
84 try {
85 return (T)MethodUtil.invoke(descriptor.getGetter(), getBean(), (Object[])null);
86 } catch (IllegalAccessException e) {
87 throw new UndeclaredThrowableException(e);
88 } catch (InvocationTargetException e) {
89 throw new UndeclaredThrowableException(e);
90 }
91 }, acc);
92 }
93
94 /**
95 * {@inheritDoc}
96 */
97 @Override
98 public Object getBean() {
99 return listener.getBean();
100 }
101
102 /**
103 * {@inheritDoc}
104 */
105 @Override
|
1 /*
2 * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javafx.beans.property.adapter;
27
28 import com.sun.javafx.property.MethodHelper;
29 import com.sun.javafx.property.adapter.Disposer;
30 import com.sun.javafx.property.adapter.ReadOnlyPropertyDescriptor;
31 import javafx.beans.property.ReadOnlyObjectPropertyBase;
32
33 import java.lang.reflect.InvocationTargetException;
34 import java.lang.reflect.UndeclaredThrowableException;
35
36 import java.security.AccessController;
37 import java.security.AccessControlContext;
38 import java.security.PrivilegedAction;
39
40 /**
41 * A {@code ReadOnlyJavaBeanObjectProperty} provides an adapter between a regular
42 * read only Java Bean property of {@code T} and a JavaFX
43 * {@code ReadOnlyObjectProperty}. It cannot be created directly, but a
44 * {@link ReadOnlyJavaBeanObjectPropertyBuilder} has to be used.
45 * <p>
46 * As a minimum, the Java Bean class must implement a getter for the
47 * property.
48 * The class, as well as the getter method, must be declared public.
49 * If the getter of an instance of this class is called, the property of
50 * the Java Bean is returned. If the Java Bean property is bound (i.e. it supports
51 * PropertyChangeListeners), this {@code ReadOnlyJavaBeanObjectProperty} will be
52 * aware of changes in the Java Bean. Otherwise it can be notified about
53 * changes by calling {@link #fireValueChangedEvent()}.
54 * </p>
55 * <p><b>Deploying an Application as a Module</b></p>
56 * <p>
57 * If the Java Bean class is in a named module, then it must be reflectively
58 * accessible to the {@code javafx.base} module.
59 * A class is reflectively accessible if the module
60 * {@link Module#isOpen(String,Module) opens} the containing package to at
61 * least the {@code javafx.base} module.
62 * </p>
63 * <p>
64 * For example, if {@code com.foo.MyBeanClass} is in the {@code foo.app} module,
65 * the {@code module-info.java} might
66 * look like this:
67 * </p>
68 *
69 <pre>{@code module foo.app {
70 opens com.foo to javafx.base;
71 }}</pre>
72 *
73 * <p>
74 * Alternatively, a class is reflectively accessible if the module
75 * {@link Module#isExported(String) exports} the containing package
76 * unconditionally.
77 * </p>
78 *
79 * @see javafx.beans.property.ReadOnlyObjectProperty
80 * @see ReadOnlyJavaBeanObjectPropertyBuilder
81 *
82 * @param T the type of the wrapped {@code Object}
83 * @since JavaFX 2.1
84 */
85 public final class ReadOnlyJavaBeanObjectProperty<T> extends ReadOnlyObjectPropertyBase<T> implements ReadOnlyJavaBeanProperty<T> {
86
87 private final ReadOnlyPropertyDescriptor descriptor;
88 private final ReadOnlyPropertyDescriptor.ReadOnlyListener<T> listener;
89
90 private final AccessControlContext acc = AccessController.getContext();
91
92 ReadOnlyJavaBeanObjectProperty(ReadOnlyPropertyDescriptor descriptor, Object bean) {
93 this.descriptor = descriptor;
94 this.listener = descriptor.new ReadOnlyListener<T>(bean, this);
95 descriptor.addListener(listener);
96 Disposer.addRecord(this, new DescriptorListenerCleaner(descriptor, listener));
97 }
98
99 /**
100 * {@inheritDoc}
101 *
102 * @throws UndeclaredThrowableException if calling the getter of the Java Bean
103 * property throws an {@code IllegalAccessException} or an
104 * {@code InvocationTargetException}.
105 */
106 @Override
107 public T get() {
108 return AccessController.doPrivileged((PrivilegedAction<T>) () -> {
109 try {
110 return (T)MethodHelper.invoke(descriptor.getGetter(), getBean(), (Object[])null);
111 } catch (IllegalAccessException e) {
112 throw new UndeclaredThrowableException(e);
113 } catch (InvocationTargetException e) {
114 throw new UndeclaredThrowableException(e);
115 }
116 }, acc);
117 }
118
119 /**
120 * {@inheritDoc}
121 */
122 @Override
123 public Object getBean() {
124 return listener.getBean();
125 }
126
127 /**
128 * {@inheritDoc}
129 */
130 @Override
|