1 17 package org.alfresco.repo.content.transform; 18 19 import java.util.ArrayList ; 20 import java.util.Collections ; 21 import java.util.HashMap ; 22 import java.util.List ; 23 import java.util.Map ; 24 import java.util.concurrent.locks.Lock ; 25 import java.util.concurrent.locks.ReadWriteLock ; 26 import java.util.concurrent.locks.ReentrantReadWriteLock ; 27 28 import org.alfresco.error.AlfrescoRuntimeException; 29 import org.alfresco.repo.content.MimetypeMap; 30 import org.apache.commons.logging.Log; 31 import org.apache.commons.logging.LogFactory; 32 import org.springframework.util.Assert; 33 34 45 public class ContentTransformerRegistry 46 { 47 private static final Log logger = LogFactory.getLog(ContentTransformerRegistry.class); 48 49 private List <ContentTransformer> transformers; 50 private MimetypeMap mimetypeMap; 51 52 private Map <TransformationKey, List <ContentTransformer>> transformationCache; 53 private short accessCount; 54 55 private Lock transformationCacheReadLock; 56 57 private Lock transformationCacheWriteLock; 58 59 62 public ContentTransformerRegistry(MimetypeMap mimetypeMap) 63 { 64 Assert.notNull(mimetypeMap, "The MimetypeMap is mandatory"); 65 this.mimetypeMap = mimetypeMap; 66 67 this.transformers = new ArrayList <ContentTransformer>(10); 68 transformationCache = new HashMap <TransformationKey, List <ContentTransformer>>(17); 69 70 accessCount = 0; 71 ReadWriteLock transformationCacheLock = new ReentrantReadWriteLock (); 73 transformationCacheReadLock = transformationCacheLock.readLock(); 74 transformationCacheWriteLock = transformationCacheLock.writeLock(); 75 } 76 77 84 public void addExplicitTransformer(TransformationKey key, ContentTransformer transformer) 85 { 86 transformationCache.put(key, Collections.singletonList(transformer)); 87 if (logger.isDebugEnabled()) 89 { 90 logger.debug("Registered explicit transformation: \n" + 91 " key: " + key + "\n" + 92 " transformer: " + transformer); 93 } 94 } 95 96 101 public void addTransformer(ContentTransformer transformer) 102 { 103 transformers.add(transformer); 104 if (logger.isDebugEnabled()) 106 { 107 logger.debug("Registered general transformer: \n" + 108 " transformer: " + transformer); 109 } 110 } 111 112 116 public void resetCache() 117 { 118 transformationCacheWriteLock.lock(); 120 try 121 { 122 transformationCache.clear(); 123 accessCount = 0; 124 } 125 finally 126 { 127 transformationCacheWriteLock.unlock(); 128 } 129 if (logger.isDebugEnabled()) 131 { 132 logger.debug("Content transformation cache reset"); 133 } 134 } 135 136 147 public ContentTransformer getTransformer(String sourceMimetype, String targetMimetype) 148 { 149 if (!mimetypeMap.getMimetypes().contains(sourceMimetype)) 151 { 152 throw new AlfrescoRuntimeException("Unknown source mimetype: " + sourceMimetype); 153 } 154 if (!mimetypeMap.getMimetypes().contains(targetMimetype)) 155 { 156 throw new AlfrescoRuntimeException("Unknown target mimetype: " + targetMimetype); 157 } 158 159 TransformationKey key = new TransformationKey(sourceMimetype, targetMimetype); 160 List <ContentTransformer> transformers = null; 161 transformationCacheReadLock.lock(); 162 try 163 { 164 if (transformationCache.containsKey(key)) 165 { 166 transformers = transformationCache.get(key); 169 } 170 } 171 finally 172 { 173 transformationCacheReadLock.unlock(); 174 } 175 176 if (transformers == null) 177 { 178 transformationCacheWriteLock.lock(); 182 try 183 { 184 transformers = findTransformers(sourceMimetype, targetMimetype); 186 transformationCache.put(key, transformers); 188 } 189 finally 190 { 191 transformationCacheWriteLock.unlock(); 192 } 193 } 194 long bestTime = -1L; 196 ContentTransformer bestTransformer = null; 197 for (ContentTransformer transformer : transformers) 198 { 199 long transformationTime = transformer.getTransformationTime(); 200 if (bestTransformer == null || transformationTime < bestTime) 202 { 203 bestTransformer = transformer; 204 bestTime = transformationTime; 205 } 206 } 207 return bestTransformer; 209 } 210 211 217 private List <ContentTransformer> findTransformers(String sourceMimetype, String targetMimetype) 218 { 219 List <ContentTransformer> transformers = findDirectTransformers(sourceMimetype, targetMimetype); 221 List <ContentTransformer> complexTransformers = findComplexTransformer(sourceMimetype, targetMimetype); 223 transformers.addAll(complexTransformers); 224 if (logger.isDebugEnabled()) 226 { 227 logger.debug("Searched for transformer: \n" + 228 " source mimetype: " + sourceMimetype + "\n" + 229 " target mimetype: " + targetMimetype + "\n" + 230 " transformers: " + transformers); 231 } 232 return transformers; 233 } 234 235 243 private List <ContentTransformer> findDirectTransformers(String sourceMimetype, String targetMimetype) 244 { 245 double maxReliability = 0.0; 246 long leastTime = 100000L; List <ContentTransformer> bestTransformers = new ArrayList <ContentTransformer>(2); 248 for (ContentTransformer transformer : this.transformers) 250 { 251 double reliability = transformer.getReliability(sourceMimetype, targetMimetype); 252 if (reliability <= 0.0) 253 { 254 continue; 256 } 257 else if (reliability < maxReliability) 258 { 259 continue; 261 } 262 else if (reliability == maxReliability) 263 { 264 } 266 else 267 { 268 bestTransformers.clear(); 270 maxReliability = reliability; 271 } 272 bestTransformers.add(transformer); 274 } 275 return bestTransformers; 277 } 278 279 282 private List <ContentTransformer> findComplexTransformer(String sourceMimetype, String targetMimetype) 283 { 284 return Collections.emptyList(); 287 } 288 289 292 private void buildTransformer(List <ContentTransformer> transformers, 293 double reliability, 294 List <String > touchedMimetypes, 295 String currentMimetype, 296 String targetMimetype) 297 { 298 throw new UnsupportedOperationException (); 299 } 300 301 304 public static class TransformationKey 305 { 306 private final String sourceMimetype; 307 private final String targetMimetype; 308 private final String key; 309 310 public TransformationKey(String sourceMimetype, String targetMimetype) 311 { 312 this.key = (sourceMimetype + "_" + targetMimetype); 313 this.sourceMimetype = sourceMimetype; 314 this.targetMimetype = targetMimetype; 315 } 316 317 public String getSourceMimetype() 318 { 319 return sourceMimetype; 320 } 321 public String getTargetMimetype() 322 { 323 return targetMimetype; 324 } 325 326 @Override 327 public boolean equals(Object obj) 328 { 329 if (obj == null) 330 { 331 return false; 332 } 333 else if (this == obj) 334 { 335 return true; 336 } 337 else if (!(obj instanceof TransformationKey)) 338 { 339 return false; 340 } 341 TransformationKey that = (TransformationKey) obj; 342 return this.key.equals(that.key); 343 } 344 @Override 345 public int hashCode() 346 { 347 return key.hashCode(); 348 } 349 } 350 } 351 | Popular Tags |