1 17 package org.alfresco.repo.policy; 18 19 import java.lang.reflect.InvocationHandler ; 20 import java.lang.reflect.InvocationTargetException ; 21 import java.lang.reflect.Method ; 22 import java.lang.reflect.Proxy ; 23 import java.util.ArrayList ; 24 import java.util.Collection ; 25 import java.util.Collections ; 26 import java.util.List ; 27 28 29 37 class PolicyFactory<B extends BehaviourBinding, P extends Policy> 38 { 39 private BehaviourIndex<B> index; 41 42 private Class <P> policyClass; 44 45 46 52 PolicyFactory(Class <P> policyClass, BehaviourIndex<B> index) 53 { 54 this.policyClass = policyClass; 55 this.index = index; 56 } 57 58 59 64 protected Class <P> getPolicyClass() 65 { 66 return policyClass; 67 } 68 69 70 76 public P create(B binding) 77 { 78 Collection <P> policyInterfaces = createList(binding); 79 return toPolicy(policyInterfaces); 80 } 81 82 83 89 @SuppressWarnings ("unchecked") 90 public Collection <P> createList(B binding) 91 { 92 Collection <BehaviourDefinition> behaviourDefs = index.find(binding); 93 List <P> policyInterfaces = new ArrayList <P>(behaviourDefs.size()); 94 for (BehaviourDefinition behaviourDef : behaviourDefs) 95 { 96 Behaviour behaviour = behaviourDef.getBehaviour(); 97 P policyIF = behaviour.getInterface(policyClass); 98 policyInterfaces.add(policyIF); 99 } 100 101 return policyInterfaces; 102 } 103 104 105 112 @SuppressWarnings ("unchecked") 113 public P toPolicy(Collection <P> policyList) 114 { 115 if (policyList.size() == 1) 116 { 117 return policyList.iterator().next(); 118 } 119 else if (policyList.size() == 0) 120 { 121 return (P)Proxy.newProxyInstance(policyClass.getClassLoader(), 122 new Class []{policyClass}, new NOOPHandler()); 123 } 124 else 125 { 126 return (P)Proxy.newProxyInstance(policyClass.getClassLoader(), 127 new Class []{policyClass, PolicyList.class}, new MultiHandler<P>(policyList)); 128 } 129 } 130 131 132 138 private static class NOOPHandler implements InvocationHandler 139 { 140 143 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable 144 { 145 if (method.getName().equals("toString")) 146 { 147 return toString(); 148 } 149 else if (method.getName().equals("hashCode")) 150 { 151 return hashCode(); 152 } 153 else if (method.getName().equals("equals")) 154 { 155 return equals(args[0]); 156 } 157 return null; 158 } 159 } 160 161 162 169 @SuppressWarnings ("hiding") 170 private static class MultiHandler<P> implements InvocationHandler , PolicyList 171 { 172 private Collection <P> policyInterfaces; 173 174 179 public MultiHandler(Collection <P> policyInterfaces) 180 { 181 this.policyInterfaces = Collections.unmodifiableCollection(policyInterfaces); 182 } 183 184 187 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable 188 { 189 if (method.getDeclaringClass().equals(PolicyList.class)) 191 { 192 return method.invoke(this, args); 193 } 194 195 if (method.getName().equals("toString")) 197 { 198 return toString() + ": wrapped " + policyInterfaces.size() + " policies"; 199 } 200 else if (method.getName().equals("hashCode")) 201 { 202 return hashCode(); 203 } 204 else if (method.getName().equals("equals")) 205 { 206 return equals(args[0]); 207 } 208 209 try 211 { 212 Object result = null; 213 for (P policyInterface : policyInterfaces) 214 { 215 result = method.invoke(policyInterface, args); 216 } 217 return result; 218 } 219 catch (InvocationTargetException e) 220 { 221 throw e.getTargetException(); 222 } 223 } 224 225 228 public Collection getPolicies() 229 { 230 return policyInterfaces; 231 } 232 } 233 234 } 235 | Popular Tags |