亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? elproperty.java

?? java屬性邦定的(JSR-295)的一個實現
?? JAVA
?? 第 1 頁 / 共 3 頁
字號:
/*
 * Copyright (C) 2006-2007 Sun Microsystems, Inc. All rights reserved. Use is
 * subject to license terms.
 */

package org.jdesktop.beansbinding;

import org.jdesktop.el.impl.ExpressionFactoryImpl;
import org.jdesktop.el.ELContext;
import org.jdesktop.el.ELException;
import org.jdesktop.el.Expression;
import org.jdesktop.el.Expression.ResolvedProperty;
import org.jdesktop.el.ValueExpression;
import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import org.jdesktop.observablecollections.ObservableMap;
import org.jdesktop.observablecollections.ObservableMapListener;
import static org.jdesktop.beansbinding.PropertyStateEvent.UNREADABLE;
import org.jdesktop.beansbinding.ext.BeanAdapterFactory;

/**
 * An implementation of {@code Property} that allows Java Beans properties of
 * source objects to be addressed using a simple dot-separated path syntax
 * within an EL expression. For example, to create a simple property representing
 * a {@code Person} bean's mother's {@code firstName}:
 * <p>
 * <pre><code>
 *    ELProperty.create("${mother.firstName}")
 * </pre></code>
 * </p>
 * Note that {@link org.jdesktop.beansbinding.BeanProperty} is more suitable for
 * such a simple property.
 * <p> 
 * To create a property representing the concatenation of a {@code Person} bean's
 * {@code firstName} and {@code lastName} properties:
 * <p>
 * <pre><code>
 *    ELProperty.create("${firstName} ${lastName}");
 *</code></pre>
 * <p>
 * To create a property that is {@code true} or {@code false} depending
 * on whether or not the {@code Person's} mother is older than 65:
 * <p>
 * <pre><code>
 *    BeanProperty.create("${mother.age > 65}");
 * </code></pre>
 * <p>
 * Paths specified in the EL expressions are resolved against the source object
 * with which the property is being used.
 * <p>
 * An instance of {@code ELProperty} is immutable and can be used with
 * different source objects. When a {@code PropertyStateListener} is added to
 * an {@code ELProperty} for a given source object, the {@code ELProperty}
 * starts listening to all objects along the paths in the expression (based on that source object)
 * for change notification, and reflects any changes by notifying the
 * listener associated with the property for that source object. So, for example,
 * if a {@code PropertyStateListener} is added to the property from the second example above
 * for an object {@code Duke}, the {@code PropertyStateListener} is
 * notified when either {@code Duke's} first name changes, or his last name changes.
 * If a listener is added to the property from the third example, the {@code PropertyStateListener}
 * is notified when either a change in {@code Duke's} mother or {@code Duke's} mother's {@code age}
 * results in a change to the result of the expression.
 * <p>
 * It is very important that any bean properties addressed via a {@code ELProperty}
 * follow the Java Beans specification, including firing property change notification;
 * otherwise, {@code ELProperty} cannot respond to change. As some beans outside
 * of your control may not follow the Java Beans specification, {@code ELProperty}
 * always checks the {@link org.jdesktop.beansbinding.ext.BeanAdapterFactory} to
 * see if a delegate provider has been registered to provide a delegate bean to take
 * the place of an object for a given property. See the
 * <a href="ext/package-summary.html">ext package level</a> documentation for more
 * details.
 * <p>
 * When there are no {@code PropertyStateListeners} installed on an {@code ELProperty}
 * for a given source, all {@code Property} methods act by evaluating the full expression,
 * thereby always providing "live" information.
 * On the contrary, when there are {@code PropertyStateListeners} installed, the beans
 * along the paths, and the final value, are cached, and only updated upon
 * notification of change from a bean. Again, this makes it very important that any
 * bean property that could change along the path fires property change notification.
 * <i>Note: The {@code setValue} method is currently excluded from the previous
 * assertion; with the exception of checking the cache to determine if the property is
 * writeable, it always evaluates the entire expression. The result of this is that
 * when working with paths containing beans that don't fire property change notification,
 * you can end up with all methods (including {@code getValue}) working on cached
 * information, but {@code setValue} working on the live expression. There are plans
 * to resolve this inconsistency in a future release.</i>
 * <p>
 * <a name="READABILITY"><b>Readability</b></a> of an {@code ELProperty} for a given source is defined as follows:
 * <i>An {@code ELProperty} is readable for a given source if and only if the
 * following is true for all paths used in the expression:
 * a) each bean the path, starting with the source, defines a Java Beans getter
 * method for the the property to be read on it AND b) each bean in the path,
 * starting with the source and ending with the bean on which we read the final
 * property, is {@code non-null}. The final value being {@code null} does not
 * affect the readability.</i>
 * <p>
 * So, in the third example given earlier, the {@code ELProperty} is readable for {@code Duke} when all
 * of the following are true: {@code Duke} defines a Java Beans getter for
 * {@code mother}, {@code Duke's mother} defines a Java Beans getter for
 * {@code age}, {@code Duke} is {@code non-null}, {@code Duke's mother}
 * is {@code non-null}. The {@code ELProperty} is therefore unreadable when
 * any of the following is true: {@code Duke} does not define a Java Beans
 * getter for {@code mother}, {@code Duke's mother} does not define a Java
 * Beans getter for {@code age}, {@code Duke} is {@code null},
 * {@code Duke's mother} is {@code null}.
 * <p>
 * <a name="WRITEABILITY"><b>Writeability</b></a> of an {@code ELProperty} for a given source is defined as follows:
 * <i>An {@code ELProperty} is writeable for a given source if and only if
 * a) the EL expression itself is not read-only
 * (ie. it is a simple expression involving one path such as "${foo.bar.baz}" AND
 * b) each bean in the path, starting with the source and ending with the bean on
 * which we set the final property, defines a Java Beans getter method for the
 * property to be read on it AND c) the bean on which we set the final property
 * defines a Java Beans setter for the property to be set on it AND d) each bean
 * in the path, starting with the source and ending with the bean on which we
 * set the final property, is {@code non-null}. The final value being {@code null}
 * does not affect the writeability.</i>
 * <p>
 * So in the first example given earlier (a simple path), the {@code ELProperty}
 * is writeable for {@code Duke} when all of the following are true: {@code Duke} defines a Java Beans getter for
 * {@code mother}, {@code Duke's mother} defines a Java Beans setter for
 * {@code firstName}, {@code Duke} is {@code non-null}, {@code Duke's mother}
 * is {@code non-null}. The {@code ELProperty} is therefore unreadable when
 * any of the following is true: {@code Duke} does not define a Java Beans
 * getter for {@code mother}, {@code Duke's mother} does not define a Java
 * Beans setter for {@code firstName}, {@code Duke} is {@code null},
 * {@code Duke's mother} is {@code null}. The second and third examples above
 * both represent read-only ELExpressions and are therefore unwritable.
 * <p>
 * In addition to working on Java Beans properties, any object in the paths
 * can be an instance of {@code Map}. In this case, the {@code Map's get}
 * method is used with the property name as the getter, and the
 * {@code Map's put} method is used with the property name as the setter.
 * {@code ELProperty} can only respond to changes in {@code Maps}
 * if they are instances of {@link org.jdesktop.observablecollections.ObservableMap}.
 * <p>
 * Some methods in this class document that they can throw
 * {@code PropertyResolutionException} if an exception occurs while trying
 * to evaluate the expression. The throwing of this exception represents an abnormal
 * condition and if listeners are installed for the given source object,
 * leaves the {@code ELProperty} in an inconsistent state for that source object.
 * An {@code ELProperty} should not be used again for that same source object
 * after such an exception without first removing all listeners associated with
 * the {@code ELProperty} for that source object.
 *
 * @param <S> the type of source object that this {@code ELProperty} operates on
 * @param <V> the type of value that this {@code ELProperty} represents
 *
 * @author Shannon Hickey
 * @author Scott Violet
 */
public final class ELProperty<S, V> extends PropertyHelper<S, V> {

    private Property<S, ?> baseProperty;
    private final ValueExpression expression;
    private final ELContext context = new TempELContext();
    private IdentityHashMap<S, SourceEntry> map = new IdentityHashMap<S, SourceEntry>();
    private static final Object NOREAD = new Object();

    private final class SourceEntry implements PropertyChangeListener,
                                               ObservableMapListener,
                                               PropertyStateListener {

        private S source;
        private Object cachedBean;
        private Object cachedValue;
        private boolean cachedIsWriteable;
        private Class<?> cachedWriteType;
        private boolean ignoreChange;
        private Set<RegisteredListener> registeredListeners;
        private Set<RegisteredListener> lastRegisteredListeners;

        private SourceEntry(S source) {
            this.source = source;

            if (baseProperty != null) {
                baseProperty.addPropertyStateListener(source, this);
            }

            registeredListeners = new HashSet<RegisteredListener>(1);
            updateCachedBean();
            updateCache();
        }

        private void cleanup() {
            for (RegisteredListener rl : registeredListeners) {
                unregisterListener(rl, this);
            }

            if (baseProperty != null) {
                baseProperty.removePropertyStateListener(source, this);
            }

            cachedBean = null;
            registeredListeners = null;
            cachedValue = null;
        }

        private boolean cachedIsReadable() {
            return cachedValue != NOREAD;
        }

        private void updateCachedBean() {
            cachedBean = getBeanFromSource(source, true);
        }

        private void updateCache() {
            lastRegisteredListeners = registeredListeners;
            registeredListeners = new HashSet<RegisteredListener>(lastRegisteredListeners.size());
            List<ResolvedProperty> resolvedProperties = null;

            try {
                expression.setSource(getBeanFromSource(source, true));
                Expression.Result result = expression.getResult(context, true);
                
                if (result.getType() == Expression.Result.Type.UNRESOLVABLE) {
                    log("updateCache()", "expression is unresolvable");
                    cachedValue = NOREAD;
                    cachedIsWriteable = false;
                    cachedWriteType = null;
                } else {
                    cachedValue = result.getResult();
                    cachedIsWriteable = !expression.isReadOnly(context);
                    cachedWriteType = cachedIsWriteable ? expression.getType(context) : null;
                }

                resolvedProperties = result.getResolvedProperties();
            } catch (ELException ele) {
                throw new PropertyResolutionException("Error evaluating EL expression " + expression + " on " + source, ele);
            } finally {
                expression.setSource(null);
            }

            for (ResolvedProperty prop : resolvedProperties) {
                registerListener(prop, this);
            }

            // Uninstall all listeners that are no longer along the path.
            for (RegisteredListener listener : lastRegisteredListeners) {
                unregisterListener(listener, this);
            }

            lastRegisteredListeners = null;
        }

        // flag -1 - validate all
        // flag  0 - source property changed value or readability
        // flag  1 - something else changed
        private void validateCache(int flag) {

/* In the future, this debugging code can be enabled via a flag */
            
/*
            if (flag != 0 && getBeanFromSource(source, false) != cachedBean) {
                log("validateCache()", "concurrent modification");
            }

            if (flag != 1) {
                try {
                    expression.setSource(getBeanFromSource(source, true));
                    Expression.Result result = expression.getResult(context, false);

                    Object currValue;
                    boolean currIsWriteable;
                    Class<?> currWriteType;

                    if (result.getType() == Expression.Result.Type.UNRESOLVABLE) {
                        currValue = NOREAD;
                        currIsWriteable = false;
                        currWriteType = null;
                    } else {
                        currValue = result.getResult();
                        currIsWriteable = !expression.isReadOnly(context);
                        currWriteType = currIsWriteable ? expression.getType(context) : null;
                    }

                    if (!match(currValue, cachedValue) || currIsWriteable != cachedIsWriteable || currWriteType != cachedWriteType) {
                        log("validateCache()", "concurrent modification");
                    }
                } catch (ELException ele) {
                    throw new PropertyResolutionException("Error evaluating EL expression " + expression + " on " + source, ele);
                } finally {
                    expression.setSource(null);
                }
            }
 */
        }

        public void propertyStateChanged(PropertyStateEvent pe) {
            if (!pe.getValueChanged()) {
                return;
            }

            validateCache(0);
            Object oldValue = cachedValue;
            boolean wasWriteable = cachedIsWriteable;
            updateCachedBean();
            updateCache();
            notifyListeners(wasWriteable, oldValue, this);
        }

        private void processSourceChanged() {
            validateCache(1);

            boolean wasWriteable = cachedIsWriteable;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
午夜亚洲福利老司机| 国产欧美日韩综合精品一区二区| 亚洲视频在线一区观看| 丰满岳乱妇一区二区三区| 久久久综合九色合综国产精品| 激情国产一区二区| 国产精品女主播在线观看| 成人动漫av在线| 亚洲午夜久久久久久久久电影院| 欧美在线高清视频| 天使萌一区二区三区免费观看| 欧美精品丝袜久久久中文字幕| 奇米影视一区二区三区小说| 国产亚洲福利社区一区| 91免费在线播放| 五月天激情综合| 国产偷v国产偷v亚洲高清| www.亚洲国产| 日韩精品一区第一页| 国产色产综合产在线视频| 色婷婷综合久久久中文字幕| 日韩国产精品久久久| 国产日韩精品一区| 欧美另类变人与禽xxxxx| 国模大尺度一区二区三区| 日韩美女视频19| 日韩欧美色综合| 91一区在线观看| 另类综合日韩欧美亚洲| 中文字幕一区在线观看视频| 欧美片网站yy| 不卡在线观看av| 奇米精品一区二区三区在线观看 | 色综合久久久久综合99| 亚洲第一电影网| 日本一区二区在线不卡| 欧美日韩免费电影| 国产ts人妖一区二区| 亚洲国产精品久久人人爱| 久久久91精品国产一区二区精品| 日本道精品一区二区三区| 国产一区欧美二区| 日日骚欧美日韩| 日韩伦理av电影| 精品人在线二区三区| 欧美自拍丝袜亚洲| 成人天堂资源www在线| 蜜臀av亚洲一区中文字幕| 亚洲激情图片小说视频| 国产日韩欧美一区二区三区乱码| 欧美日韩精品一区二区天天拍小说| 国产精品亚洲一区二区三区在线 | 亚洲欧美日韩久久精品| 精品久久久久久无| 欧美日韩精品欧美日韩精品一 | 欧美刺激午夜性久久久久久久 | 欧美日韩一级大片网址| 99国产精品久久久久久久久久久| 久久激情综合网| 免费人成在线不卡| 午夜欧美2019年伦理| 亚洲精品免费一二三区| 欧美国产禁国产网站cc| 精品99999| 欧美不卡123| 91精品国产色综合久久不卡电影| 一本色道**综合亚洲精品蜜桃冫| 成人免费观看av| 成人永久aaa| 国产99久久久国产精品免费看| 麻豆国产精品777777在线| 日韩电影一区二区三区| 偷拍与自拍一区| 亚洲成av人片一区二区梦乃| 亚洲综合色视频| 亚洲欧美日韩国产综合在线| 国产精品乱码久久久久久| 久久亚洲精精品中文字幕早川悠里| 日韩一区二区视频在线观看| 91精品国产乱| 日韩情涩欧美日韩视频| 日韩精品专区在线影院重磅| 日韩一区二区三区免费观看| 精品欧美一区二区久久| 久久综合色综合88| 国产拍欧美日韩视频二区| 久久久国产精品午夜一区ai换脸| 久久色视频免费观看| 国产日韩精品一区二区三区在线| 国产精品私人影院| 亚洲少妇屁股交4| 亚洲最新视频在线观看| 天堂va蜜桃一区二区三区漫画版 | 精品99一区二区| 国产精品少妇自拍| 国产精品国产三级国产aⅴ中文 | 亚洲日本在线视频观看| 亚洲最新在线观看| 免费成人av在线播放| 国产米奇在线777精品观看| 成人中文字幕电影| 欧美在线免费观看视频| 91精品国产91久久久久久一区二区 | 欧美视频在线一区| 制服丝袜在线91| 精品国产一区二区亚洲人成毛片 | 91麻豆国产香蕉久久精品| 日本电影亚洲天堂一区| 日韩一二三四区| 国产欧美日韩亚州综合 | 国产精品久久三区| 丝袜诱惑制服诱惑色一区在线观看 | 久久综合九色综合97婷婷女人| 中文字幕av不卡| 天天免费综合色| 粉嫩av一区二区三区| 在线看不卡av| 国产亚洲一二三区| 亚洲激情校园春色| 国产一区二区三区视频在线播放| 97久久超碰国产精品| 在线播放一区二区三区| 国产亚洲欧美日韩俺去了| 亚洲综合久久av| 国产制服丝袜一区| 欧美亚洲丝袜传媒另类| ww亚洲ww在线观看国产| 一区二区三区电影在线播| 韩国一区二区三区| 欧美亚日韩国产aⅴ精品中极品| 26uuu成人网一区二区三区| 亚洲在线中文字幕| 成人综合婷婷国产精品久久蜜臀| 欧美日韩激情在线| 国产精品亲子伦对白| 另类小说视频一区二区| 色狠狠一区二区三区香蕉| 久久欧美中文字幕| 日韩高清不卡一区二区三区| 91美女福利视频| 国产网站一区二区三区| 看片网站欧美日韩| 欧美狂野另类xxxxoooo| 日韩一区日韩二区| 国产激情视频一区二区在线观看 | 风间由美一区二区三区在线观看| 91精品国产91久久综合桃花| 亚洲激情中文1区| 成人美女在线视频| 久久久亚洲精品石原莉奈| 天堂久久一区二区三区| 欧美视频一区二区三区四区| 亚洲色图一区二区| 成人黄色一级视频| 久久久久高清精品| 精品一区中文字幕| 日韩欧美电影一区| 日韩精品欧美成人高清一区二区| 日本精品裸体写真集在线观看| 国产精品亲子乱子伦xxxx裸| 国产剧情在线观看一区二区| 欧美v国产在线一区二区三区| 日韩精品免费专区| 在线观看亚洲专区| 一区二区三区四区在线| 一本一本久久a久久精品综合麻豆| 国产精品久久久久久久岛一牛影视 | 国产欧美一区二区精品秋霞影院 | 337p粉嫩大胆噜噜噜噜噜91av| 蜜桃av一区二区三区电影| 日韩欧美亚洲另类制服综合在线| 蜜桃av噜噜一区二区三区小说| 91精品国产综合久久精品图片| 日韩高清一区二区| 精品久久久久久久人人人人传媒| 免费成人av资源网| 久久久久国产成人精品亚洲午夜 | 色菇凉天天综合网| 一区二区三区四区国产精品| 色欧美乱欧美15图片| 亚洲一区二区三区四区在线| 欧美系列一区二区| 日本欧美一区二区三区| 精品国产91洋老外米糕| 国产精品一区二区在线观看不卡 | 国产成人日日夜夜| 日本一区二区不卡视频| 99在线精品视频| 天天亚洲美女在线视频| 精品日韩在线一区| 国产成人亚洲精品青草天美| 自拍av一区二区三区| 欧美精品在线视频| 久久国产视频网| 国产精品乱人伦| 欧美老女人在线| 国产乱码精品一区二区三区五月婷 | 欧美精品一区二区蜜臀亚洲| 国产99一区视频免费| 一区二区三区高清在线|