package jef.database.meta.extension; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import jef.accelerator.bean.BeanAccessor; import jef.database.meta.ExtensionConfigFactory; import jef.database.meta.ExtensionTemplate; import jef.tools.reflect.FieldAccessor; import jef.tools.reflect.Property; public final class ExtensionAccessor extends BeanAccessor implements ExtensionModificationListener { private BeanAccessor accessor; /** * 扩展属性列表 */ private Map<String, Property> extProperties; /** * 混合后的属性列表 */ private Collection<String> allPropNames; private Collection<Property> allProps; private ReadWriteLock rwLock = new ReentrantReadWriteLock(); private FieldAccessor key; private String extensionName; /** * 构造 * * @param raw * @param provider */ public ExtensionAccessor(BeanAccessor raw, String extensionName, BeanExtensionProvider provider) { this.accessor = raw; this.extensionName=extensionName; setExtProperties(provider.getExtensionProperties(raw.getType(), extensionName, this)); ExtensionConfigFactory ef=provider.getExtensionFactory(raw.getType()); if(ef instanceof ExtensionTemplate){ this.key=((ExtensionTemplate) ef).getKeyAccessor(); } } /** * 当元数据发生变化时 * * @param extProps */ public void setExtProperties(Map<String, Property> extProps) { Lock lock = rwLock.writeLock(); lock.lock(); try { Collection<String> rawNames = accessor.getPropertyNames(); Collection<? extends Property> rawProperties = accessor.getProperties(); List<String> mergeNames = new ArrayList<String>(rawNames.size() + extProps.size()); List<Property> mergeProperties = new ArrayList<Property>(rawNames.size() + extProps.size()); mergeNames.addAll(rawNames); mergeNames.addAll(extProps.keySet()); mergeProperties.addAll(rawProperties); mergeProperties.addAll(extProps.values()); this.extProperties = extProps; this.allPropNames = mergeNames; this.allProps = mergeProperties; } finally { lock.unlock(); } } @Override public Collection<String> getPropertyNames() { Lock lock = rwLock.readLock(); lock.lock(); try { return allPropNames; } finally { lock.unlock(); } } @Override public Class<?> getPropertyType(String name) { Lock lock = rwLock.readLock(); lock.lock(); Property pp; try { pp = extProperties.get(name); } finally { lock.unlock(); } return pp == null ? accessor.getPropertyType(name) : pp.getType(); } @Override public Type getGenericType(String name) { Lock lock = rwLock.readLock(); lock.lock(); try { Property pp = extProperties.get(name); return pp == null ? accessor.getGenericType(name) : pp.getGenericType(); } finally { lock.unlock(); } } @Override public Object getProperty(Object bean, String name) { Lock lock = rwLock.readLock(); lock.lock(); try { Property pp = extProperties.get(name); return pp == null ? accessor.getProperty(bean, name) : pp.get(bean); } finally { lock.unlock(); } } @Override public boolean setProperty(Object bean, String name, Object v) { Lock lock = rwLock.readLock(); lock.lock(); try { Property pp = extProperties.get(name); if (pp == null) { return accessor.setProperty(bean, name, v); } else { pp.set(bean, v); return true; } } finally { lock.unlock(); } } @Override public void copy(Object o1, Object o2) { accessor.copy(o1, o2); Lock lock = rwLock.readLock(); lock.lock(); try { for (Property pp : extProperties.values()) { pp.set(o2, pp.get(o1)); } } finally { lock.unlock(); } } @Override public Property getProperty(String name) { Lock lock = rwLock.readLock(); lock.lock(); try { Property pp = extProperties.get(name); return pp == null ? accessor.getProperty(name) : pp; } finally { lock.unlock(); } } @Override public Collection<? extends Property> getProperties() { return allProps; } @Override public Map<Class<?>, Annotation> getAnnotationOnField(String name) { Property pp = extProperties.get(name); if(pp==null){ return accessor.getAnnotationOnField(name); }else{ return null; } } @Override public Map<Class<?>, Annotation> getAnnotationOnGetter(String name) { return accessor.getAnnotationOnGetter(name); } @Override public Map<Class<?>, Annotation> getAnnotationOnSetter(String name) { return accessor.getAnnotationOnSetter(name); } @Override public Object newInstance() { Object obj=accessor.newInstance(); if(key!=null){ key.set(obj, extensionName); } return obj; } @Override public Class<?> getType() { return accessor.getType(); } @Override public void initAnnotations(Map<Class<?>,Annotation>[] field, Map<Class<?>,Annotation>[] getter, Map<Class<?>,Annotation>[] setter) { accessor.initAnnotations(field, getter, setter); } @Override public void initNthGenericType(int index, Class<?> raw, Type type, int total, String fieldName) { accessor.initNthGenericType(index, raw, type, total, fieldName); } @Override public Map<String, Object> convert(Object obj) { Map<String,Object> map=accessor.convert(obj); for(Map.Entry<String, Property> entry:extProperties.entrySet()) { map.put(entry.getKey(), entry.getValue().get(obj)); } return map; } @Override public Object fromMap(Map<String, Object> map) { Object o=accessor.fromMap(map); for(Map.Entry<String, Property> entry:extProperties.entrySet()) { entry.getValue().set(o, map.get(entry.getKey())); } return o; } @Override public Object fromMap2(Map<String, Object> map) { Object o=accessor.fromMap2(map); for(Map.Entry<String, Property> entry:extProperties.entrySet()) { entry.getValue().set(o, map.get(entry.getKey())); } return o; } }