📄 elproperty.java
字号:
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 + -