1 17 package org.alfresco.repo.service; 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.Collection ; 24 import java.util.Collections ; 25 import java.util.HashMap ; 26 import java.util.Map ; 27 28 import org.alfresco.service.ServiceException; 29 import org.alfresco.service.cmr.repository.NodeRef; 30 import org.alfresco.service.cmr.repository.StoreRef; 31 import org.alfresco.util.ParameterCheck; 32 import org.apache.commons.logging.Log; 33 import org.apache.commons.logging.LogFactory; 34 import org.springframework.beans.factory.FactoryBean; 35 import org.springframework.beans.factory.InitializingBean; 36 37 52 public class StoreRedirectorProxyFactory<I> implements FactoryBean, InitializingBean 53 { 54 private static final Log logger = LogFactory.getLog(StoreRedirectorProxyFactory.class); 56 57 private Class <I> proxyInterface = null; 59 60 private I defaultBinding = null; 62 63 private Map <String , I> redirectedProtocolBindings = null; 65 66 private Map <StoreRef, I> redirectedStoreBindings = null; 68 69 private I redirectorProxy = null; 71 72 78 public void setProxyInterface(Class <I> proxyInterface) 79 { 80 this.proxyInterface = proxyInterface; 81 } 82 83 89 public void setDefaultBinding(I defaultBinding) 90 { 91 this.defaultBinding = defaultBinding; 92 } 93 94 100 public void setRedirectedProtocolBindings(Map <String , I> protocolBindings) 101 { 102 this.redirectedProtocolBindings = protocolBindings; 103 } 104 105 111 public void setRedirectedStoreBindings(Map <String , I> storeBindings) 112 { 113 redirectedStoreBindings = new HashMap <StoreRef, I>(storeBindings.size()); 114 for(String ref : storeBindings.keySet()) 115 { 116 redirectedStoreBindings.put(new StoreRef(ref), storeBindings.get(ref)); 117 } 118 } 119 120 121 124 public void afterPropertiesSet() throws ServiceException 125 { 126 ParameterCheck.mandatory("Proxy Interface", proxyInterface); 127 ParameterCheck.mandatory("Default Binding", defaultBinding); 128 129 this.redirectorProxy = (I)Proxy.newProxyInstance(proxyInterface.getClassLoader(), new Class [] { proxyInterface, StoreRedirector.class }, new RedirectorInvocationHandler()); 131 } 132 133 134 137 public I getObject() 138 { 139 return redirectorProxy; 140 } 141 142 143 146 public Class getObjectType() 147 { 148 return proxyInterface; 149 } 150 151 152 155 public boolean isSingleton() 156 { 157 return true; 158 } 159 160 161 164 class RedirectorInvocationHandler implements InvocationHandler , StoreRedirector 165 { 166 167 170 public Object invoke(Object proxy, Method method, Object [] args) throws Throwable 171 { 172 if (method.getDeclaringClass().equals(StoreRedirector.class)) 174 { 175 return method.invoke(this, args); 176 } 177 178 Object binding = null; 181 StoreRef storeRef = getStoreRef(args); 182 if (storeRef == null) 183 { 184 binding = StoreRedirectorProxyFactory.this.defaultBinding; 185 } 186 else 187 { 188 if (StoreRedirectorProxyFactory.this.redirectedStoreBindings != null) 189 { 190 binding = StoreRedirectorProxyFactory.this.redirectedStoreBindings.get(storeRef); 191 } 192 if ((binding == null) && (StoreRedirectorProxyFactory.this.redirectedProtocolBindings != null)) 193 { 194 binding = StoreRedirectorProxyFactory.this.redirectedProtocolBindings.get(storeRef.getProtocol()); 195 } 196 if (binding == null) 197 { 198 binding = StoreRedirectorProxyFactory.this.defaultBinding; 199 } 200 if (binding == null) 201 { 202 throw new ServiceException("Store type " + storeRef + " is not supported"); 203 } 204 } 205 206 if (logger.isDebugEnabled()) 207 logger.debug("Redirecting method " + method + " based on store type " + storeRef); 208 209 try 210 { 211 return method.invoke(binding, args); 213 } 214 catch (InvocationTargetException e) 215 { 216 throw e.getTargetException(); 217 } 218 } 219 220 221 227 private StoreRef getStoreRef(Object [] args) 228 { 229 StoreRef storeRef = null; 230 231 if(args == null) 232 { 233 return null; 234 } 235 236 for (Object arg : args) 237 { 238 StoreRef argStoreRef = null; 240 if (arg instanceof NodeRef) 241 { 242 argStoreRef = ((NodeRef) arg).getStoreRef(); 243 } 244 else if (arg instanceof StoreRef) 245 { 246 argStoreRef = ((StoreRef) arg); 247 } 248 249 if (argStoreRef != null) 251 { 252 if (storeRef != null && !storeRef.equals(argStoreRef)) 253 { 254 throw new ServiceException("Multiple store types are not supported - types " + storeRef + " and " + argStoreRef + " passed"); 255 } 256 storeRef = argStoreRef; 257 } 258 } 259 260 return storeRef; 261 } 262 263 264 267 public Collection <String > getSupportedStoreProtocols() 268 { 269 return Collections.unmodifiableCollection(StoreRedirectorProxyFactory.this.redirectedProtocolBindings.keySet()); 270 } 271 272 273 276 public Collection <StoreRef> getSupportedStores() 277 { 278 return Collections.unmodifiableCollection(StoreRedirectorProxyFactory.this.redirectedStoreBindings.keySet()); 279 } 280 281 } 282 } 283 | Popular Tags |