⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elproperty.java

📁 java属性邦定的(JSR-295)的一个实现
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        if (baseProperty == null) {
            if (source == null) {
                if (logErrors) {
                    log("getBeanFromSource()", "source is null");
                }
            }

            return source;
        }

        if (!baseProperty.isReadable(source)) {
            if (logErrors) {
                log("getBeanFromSource()", "unreadable source property");
            }
            return NOREAD;
        }

        Object bean = baseProperty.getValue(source);
        if (bean == null) {
            if (logErrors) {
                log("getBeanFromSource()", "source property returned null");
            }
            return null;
        }
        
        return bean;
    }

    protected final void listeningStarted(S source) {
        SourceEntry entry = map.get(source);
        if (entry == null) {
            entry = new SourceEntry(source);
            map.put(source, entry);
        }
    }

    protected final void listeningStopped(S source) {
        SourceEntry entry = map.remove(source);
        if (entry != null) {
            entry.cleanup();
        }
    }

    private static boolean didValueChange(Object oldValue, Object newValue) {
        return oldValue == null || newValue == null || !oldValue.equals(newValue);
    }

    private void notifyListeners(boolean wasWriteable, Object oldValue, SourceEntry entry) {
        PropertyStateListener[] listeners = getPropertyStateListeners(entry.source);

        if (listeners == null || listeners.length == 0) {
            return;
        }

        oldValue = toUNREADABLE(oldValue);
        Object newValue = toUNREADABLE(entry.cachedValue);
        boolean valueChanged = didValueChange(oldValue, newValue);
        boolean writeableChanged = (wasWriteable != entry.cachedIsWriteable);

        if (!valueChanged && !writeableChanged) {
            return;
        }

        PropertyStateEvent pse = new PropertyStateEvent(this,
                                                        entry.source,
                                                        valueChanged,
                                                        oldValue,
                                                        newValue,
                                                        writeableChanged,
                                                        entry.cachedIsWriteable);

        this.firePropertyStateChange(pse);
    }

    /**
     * Returns a string representation of the {@code ELProperty}. This
     * method is intended to be used for debugging purposes only, and
     * the content and format of the returned string may vary between
     * implementations. The returned string may be empty but may not
     * be {@code null}.
     *
     * @return a string representation of this {@code ELProperty}
     */
    public String toString() {
        return getClass().getName() + "[" + expression + "]";
    }

    /**
     * @throws PropertyResolutionException
     */
    private static BeanInfo getBeanInfo(Object object) {
        assert object != null;

        try {
            return Introspector.getBeanInfo(object.getClass(), Introspector.IGNORE_ALL_BEANINFO);
        } catch (IntrospectionException ie) {
            throw new PropertyResolutionException("Exception while introspecting " + object.getClass().getName(), ie);
        }
    }

    private static EventSetDescriptor getEventSetDescriptor(Object object) {
        assert object != null;
        
        EventSetDescriptor[] eds = getBeanInfo(object).getEventSetDescriptors();
        for (EventSetDescriptor ed : eds) {
            if (ed.getListenerType() == PropertyChangeListener.class) {
                return ed;
            }
        }

        return null;
    }

    /**
     * @throws PropertyResolutionException
     */
    private static Object invokeMethod(Method method, Object object, Object... args) {
        Exception reason = null;

        try {
            return method.invoke(object, args);
        } catch (IllegalArgumentException ex) {
            reason = ex;
        } catch (IllegalAccessException ex) {
            reason = ex;
        } catch (InvocationTargetException ex) {
            reason = ex;
        }

        throw new PropertyResolutionException("Exception invoking method " + method + " on " + object, reason);
    }

    private static Object toUNREADABLE(Object src) {
        return src == NOREAD ? UNREADABLE : src;
    }

    private void registerListener(ResolvedProperty resolved, SourceEntry entry) {
        Object source = resolved.getSource();
        Object property = resolved.getProperty();
        if (source != null && property instanceof String) {
            String sProp = (String)property;

            if (source instanceof ObservableMap) {
                RegisteredListener rl = new RegisteredListener(source, sProp);

                if (!entry.registeredListeners.contains(rl)) {
                    if (!entry.lastRegisteredListeners.remove(rl)) {
                        ((ObservableMap)source).addObservableMapListener(entry);
                    }
                    
                    entry.registeredListeners.add(rl);
                }
            } else if (!(source instanceof Map)) {
                source = getAdapter(source, sProp);

                RegisteredListener rl = new RegisteredListener(source, sProp);

                if (!entry.registeredListeners.contains(rl)) {
                    if (!entry.lastRegisteredListeners.remove(rl)) {
                        addPropertyChangeListener(source, entry);
                    }
                    
                    entry.registeredListeners.add(rl);
                }
            }
        }
    }

    private void unregisterListener(RegisteredListener rl, SourceEntry entry) {
        Object source = rl.getSource();
        if (source instanceof ObservableMap) {
            ((ObservableMap)source).removeObservableMapListener(entry);
        } else if (!(source instanceof Map)) {
            removePropertyChangeListener(source, entry);
        }
    }

    /**
     * @throws PropertyResolutionException
     */
    private static void addPropertyChangeListener(Object object, PropertyChangeListener listener) {
        EventSetDescriptor ed = getEventSetDescriptor(object);
        Method addPCMethod = null;

        if (ed == null || (addPCMethod = ed.getAddListenerMethod()) == null) {
            log("addPropertyChangeListener()", "can't add listener");
            return;
        }

        invokeMethod(addPCMethod, object, listener);
    }

    /**
     * @throws PropertyResolutionException
     */
    private static void removePropertyChangeListener(Object object, PropertyChangeListener listener) {
        EventSetDescriptor ed = getEventSetDescriptor(object);
        Method removePCMethod = null;

        if (ed == null || (removePCMethod = ed.getRemoveListenerMethod()) == null) {
            log("removePropertyChangeListener()", "can't remove listener from source");
            return;
        }
        
        invokeMethod(removePCMethod, object, listener);
    }

    private static boolean wrapsLiteral(Object o) {
        assert o != null;

        return o instanceof String ||
               o instanceof Byte ||
               o instanceof Character ||
               o instanceof Boolean ||
               o instanceof Short ||
               o instanceof Integer ||
               o instanceof Long ||
               o instanceof Float ||
               o instanceof Double;
    }

    // need special match method because when using reflection
    // to get a primitive value, the value is always wrapped in
    // a new object
    private static boolean match(Object a, Object b) {
        if (a == b) {
            return true;
        }

        if (a == null) {
            return false;
        }

        if (wrapsLiteral(a)) {
            return a.equals(b);
        }

        return false;
    }

    private Object getAdapter(Object o, String property) {
        Object adapter = null;
        adapter = BeanAdapterFactory.getAdapter(o, property);
        return adapter == null ? o : adapter;
    }
    
    private static final boolean LOG = false;

    private static void log(String method, String message) {
        if (LOG) {
            System.err.println("LOG: " + method + ": " + message);
        }
    }

    private static final class RegisteredListener {
        private final Object source;
        private final String property;
        
        RegisteredListener(Object source) {
            this(source, null);
        }
        
        RegisteredListener(Object source, String property) {
            this.source = source;
            if (property != null) {
                property = property.intern();
            }
            this.property = property;
        }
        
        public Object getSource() {
            return source;
        }
        
        public String getProperty() {
            return property;
        }

        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            }
            if (obj instanceof RegisteredListener) {
                RegisteredListener orl = (RegisteredListener) obj;
                return (orl.source == source && orl.property == property);
            }
            return false;
        }

        public int hashCode() {
            int result = 17;
            result = 37 * result + source.hashCode();
            if (property != null) {
                result = 37 * result + property.hashCode();
            }
            return result;
        }

        public String toString() {
            return "RegisteredListener [" +
                    " source=" + source +
                    " property=" + property + 
                    "]";
        }
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -