KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > content > metadata > MetadataExtracterRegistry


1 /*
2  * Copyright (C) 2005 Jesper Steen Møller
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.content.metadata;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.concurrent.locks.Lock JavaDoc;
24 import java.util.concurrent.locks.ReadWriteLock JavaDoc;
25 import java.util.concurrent.locks.ReentrantReadWriteLock JavaDoc;
26
27 import org.alfresco.error.AlfrescoRuntimeException;
28 import org.alfresco.repo.content.MimetypeMap;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 /**
33  * Holds and provides the most appropriate metadate extracter for a particular
34  * mimetype.
35  * <p>
36  * The extracters themselves know how well they are able to extract metadata.
37  *
38  * @see org.alfresco.repo.content.metadata.MetadataExtracter
39  * @author Jesper Steen Møller
40  */

41 public class MetadataExtracterRegistry
42 {
43     private static final Log logger = LogFactory.getLog(MetadataExtracterRegistry.class);
44
45     private List JavaDoc<MetadataExtracter> extracters;
46     private Map JavaDoc<String JavaDoc, MetadataExtracter> extracterCache;
47
48     private MimetypeMap mimetypeMap;
49     /** Controls read access to the cache */
50     private Lock JavaDoc extracterCacheReadLock;
51     /** controls write access to the cache */
52     private Lock JavaDoc extracterCacheWriteLock;
53
54     public MetadataExtracterRegistry()
55     {
56         // initialise lists
57
extracters = new ArrayList JavaDoc<MetadataExtracter>(10);
58         extracterCache = new HashMap JavaDoc<String JavaDoc, MetadataExtracter>(17);
59
60         // create lock objects for access to the cache
61
ReadWriteLock JavaDoc extractionCacheLock = new ReentrantReadWriteLock JavaDoc();
62         extracterCacheReadLock = extractionCacheLock.readLock();
63         extracterCacheWriteLock = extractionCacheLock.writeLock();
64     }
65
66     /**
67      * The mimetype map that will be used to check requests against
68      *
69      * @param mimetypeMap a map of mimetypes
70      */

71     public void setMimetypeMap(MimetypeMap mimetypeMap)
72     {
73         this.mimetypeMap = mimetypeMap;
74     }
75
76     /**
77      * Register an instance of an extracter for use
78      *
79      * @param extracter an extracter
80      */

81     public void register(MetadataExtracter extracter)
82     {
83         if (logger.isDebugEnabled())
84         {
85             logger.debug("Registering metadata extracter: " + extracter);
86         }
87
88         extracterCacheWriteLock.lock();
89         try
90         {
91             extracters.add(extracter);
92             extracterCache.clear();
93         }
94         finally
95         {
96             extracterCacheWriteLock.unlock();
97         }
98     }
99
100     /**
101      * Gets the best metadata extracter. This is a combination of the most
102      * reliable and the most performant extracter.
103      * <p>
104      * The result is cached for quicker access next time.
105      *
106      * @param mimetype the source MIME of the extraction
107      * @return Returns a metadata extracter that can extract metadata from the
108      * chosen MIME type.
109      */

110     public MetadataExtracter getExtracter(String JavaDoc sourceMimetype)
111     {
112         // check that the mimetypes are valid
113
if (!mimetypeMap.getMimetypes().contains(sourceMimetype))
114         {
115             throw new AlfrescoRuntimeException("Unknown extraction source mimetype: " + sourceMimetype);
116         }
117
118         MetadataExtracter extracter = null;
119         extracterCacheReadLock.lock();
120         try
121         {
122             if (extracterCache.containsKey(sourceMimetype))
123             {
124                 // the translation has been requested before
125
// it might have been null
126
return extracterCache.get(sourceMimetype);
127             }
128         }
129         finally
130         {
131             extracterCacheReadLock.unlock();
132         }
133
134         // the translation has not been requested before
135
// get a write lock on the cache
136
// no double check done as it is not an expensive task
137
extracterCacheWriteLock.lock();
138         try
139         {
140             // find the most suitable transformer - may be empty list
141
extracter = findBestExtracter(sourceMimetype);
142             // store the result even if it is null
143
extracterCache.put(sourceMimetype, extracter);
144             return extracter;
145         }
146         finally
147         {
148             extracterCacheWriteLock.unlock();
149         }
150     }
151
152     /**
153      * @param sourceMimetype The MIME type under examination
154      * @return The fastest of the most reliable extracters in <code>extracters</code>
155      * for the given MIME type, or null if none is available.
156      */

157     private MetadataExtracter findBestExtracter(String JavaDoc sourceMimetype)
158     {
159         double bestReliability = -1;
160         long bestTime = Long.MAX_VALUE;
161         logger.debug("Finding best extracter for " + sourceMimetype);
162
163         MetadataExtracter bestExtracter = null;
164
165         for (MetadataExtracter ext : extracters)
166         {
167             double r = ext.getReliability(sourceMimetype);
168             if (r <= 0.0)
169             {
170                 // extraction not achievable
171
continue;
172             }
173             else if (r == bestReliability)
174             {
175                 long time = ext.getExtractionTime();
176                 if (time < bestTime)
177                 {
178                     bestExtracter = ext;
179                     bestTime = time;
180                 }
181             }
182             else if (r > bestReliability)
183             {
184                 bestExtracter = ext;
185                 bestReliability = r;
186                 bestTime = ext.getExtractionTime();
187             }
188         }
189         return bestExtracter;
190     }
191 }
Popular Tags