============ the file name: Attribute.java
package fs.cb;
import java.util.List;
import java.util.Vector;
public class Attribute {
private BaseObject source;
private String name;
private Object value;
private List<AttributeListener> listeners = new Vector<AttributeListener>();
public Attribute(BaseObject source, String name) {
this(source, name, null);
}
public Attribute(BaseObject source, String name, Object value) {
check(source, name);
this.source = source;
this.name = name;
this.value = value;
}
protected void check(BaseObject source, String name) {
if (source == null || name == null) {
throw new IllegalArgumentException("Either source or name is null");
}
}
public synchronized void addListener(AttributeListener listener) {
listeners.add(listener);
}
public synchronized void removeListener(AttributeListener listener) {
listeners.remove(listener);
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public List<AttributeListener> getListeners() {
return listeners;
}
}
============ the file name: AttributeEvent.java
package fs.cb;
import java.util.EventObject;
public class AttributeEvent extends EventObject {
private String name;
private Object oldValue;
private Object newValue;
public AttributeEvent(Object source, String attribute, Object oldValue,
Object newValue) {
super(source);
this.name = attribute;
this.oldValue = oldValue;
this.newValue = newValue;
}
public String toString() {
return "{[" + getSource() + "], (attribute:" + name
+ "), (oldValue:" + oldValue + "), (newValue:" + newValue
+ ")}";
}
public String getName() {
return name;
}
public void setAttribute(String attribute) {
this.name = attribute;
}
public Object getNewValue() {
return newValue;
}
public void setNewValue(Object newValue) {
this.newValue = newValue;
}
public Object getOldValue() {
return oldValue;
}
public void setOldValue(Object oldValue) {
this.oldValue = oldValue;
}
}
============ the file name: AttributeListener.java
package fs.cb;
import java.util.List;
public interface AttributeListener {
void onChange(AttributeEvent ae);
}
============ the file name: AttributeSupportTest.java
package fs.cb;
import java.util.Arrays;
import junit.framework.TestCase;
public class AttributeSupportTest extends TestCase {
public void testA() {
BaseObject ps = new BaseObject();
ps.set("username", "shaucle");
assertEquals(ps.get("username"), "shaucle");
System.out.println(ps.get("username") + "aaa");
}
public void testB() {
final BaseObject a = new BaseObject();
final BaseObject b = new BaseObject();
Binder.bind(b, "username", a, "am");
a.set("am", "augmtuem");
// Arrays.fill(a, val);
System.out.println(b.get("username") + "========");
}
public void testC() throws Exception {
final BaseObject a = new BaseObject() {
public void onName(AttributeEvent ae) {
System.out.println("DANAME");
}
public void onname(AttributeEvent ae) {
System.out.println("xiaoname");
}
public void onTitle(AttributeEvent ae) {
System.out.println("title" + ae.getNewValue());
}
};
a.set("name", "carlos");
a.set("title", "this is a title");
}
}
============ the file name: BaseObject.java
package fs.cb;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
public class BaseObject {
private Map<String, Attribute> attributes = new HashMap<String, Attribute>();
public Object get(String name) {
Attribute attribute = attributes.get(name);
if (attribute == null)
return null;
return attribute.getValue();
}
public synchronized void set(String name, Object value) {
Object oldValue = get(name);
getOrCreateAttribute(name).setValue(value);
fireAttributeChange(name, oldValue, value);
}
public void addListener(String name, AttributeListener listener) {
getOrCreateAttribute(name).addListener(listener);
}
Attribute getAttribute(String name) {
return attributes.get(name);
}
Attribute getOrCreateAttribute(String name) {
Attribute attribute = attributes.get(name);
if (attribute == null) {
attribute = new Attribute(this, name);
attributes.put(name, attribute);
}
return attribute;
}
private void fireAttributeChange(String name, Object oldValue,
Object newValue) {
AttributeEvent ae = new AttributeEvent(this, name, oldValue, newValue);
List<AttributeListener> listeners = attributes.get(name).getListeners();
for (int i = 0; i < listeners.size(); i++) {
AttributeListener listener = listeners.get(i);
listener.onChange(ae);
}
EventUtils.sendEvent(ae);
}
public String toString(){
return this.getClass().getName();
}
}
============ the file name: Binder.java
package fs.cb;
public class Binder {
public static void bind(final BaseObject target, final String targetName,
final BaseObject source, final String sourceName) {
source.addListener(sourceName, new AttributeListener() {
public void onChange(AttributeEvent ae) {
target.set(targetName, source.get(sourceName));
}
});
}
public static void bind(final BaseObject target, final String targetName,
final BaseObject source) {
source.addListener(targetName, new AttributeListener() {
public void onChange(AttributeEvent ae) {
target.set(targetName, source.get(targetName));
}
});
}
}
============ the file name: EventUtils.java
package fs.cb;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.*;
public class EventUtils {
private final static ExecutorService pool = Executors
.newFixedThreadPool(10);
public static boolean on = true;
public static void setOn(boolean on) {
EventUtils.on = on;
}
public static void sendEventAsyn(final AttributeEvent ae) {
if (!on)
return;
pool.execute(new Runnable() {
public void run() {
sendEvent(ae);
}
});
}
public static void sendEvent(AttributeEvent ae) {
if (!on)
return;
BaseObject source = (BaseObject) ae.getSource();
Method method = getEventMethod(source, ae.getName());
if (method == null)
return;
try {
if (method.getParameterTypes().length == 0) {
method.invoke(source);
} else {
method.invoke(source, ae);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static Method getEventMethod(BaseObject source, String name) {
Method method = null;
String methodName = "on" + Character.toUpperCase(name.charAt(0))
+ name.substring(1);
method = getMethod(source, methodName);
if (method == null) {
method = getMethod(source, "on" + name);
}
return method;
}
private static Method getMethod(BaseObject source, String methodName) {
Method method = null;
try {
method = source.getClass().getMethod(methodName,
AttributeEvent.class);
} catch (Exception e) {
try {
method = source.getClass().getMethod(methodName);
} catch (Exception e2) {
// ignore
}
}
return method;
}
}
the threda's name: Thread-0java.lang.ThreadGroup[name=main,maxpri=10] toString: Thread[Thread-0,5,main]
94