This project has retired. For details please refer to its Attic page.
Configurator xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.client.mapper;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.util.HashMap;
24  import java.util.Map;
25  import java.util.Properties;
26  
27  import org.apache.chemistry.opencmis.client.parser.MetadataParser;
28  import org.apache.chemistry.opencmis.client.parser.MetadataParserTika;
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  
32  public class Configurator {
33  
34      private static final Log LOG = LogFactory.getLog(Configurator.class.getName());
35      
36      private static Configurator INSTANCE;
37      static final String PREFIX = "mapping.contentType";
38      
39      public static Configurator getInstance() {
40          if (null == INSTANCE)
41              INSTANCE = new Configurator();
42          return INSTANCE;
43      }
44      
45      private Properties properties;
46      private Map<String, PropertyMapper> contentTypeMapperMap  = new HashMap<String, PropertyMapper>();
47      private Map<String, MetadataParser> parserMap = new HashMap<String, MetadataParser>();
48      private String defaultDocumentType;
49      private String defaultFolderType;
50      
51      private Configurator() {     
52          loadProperties();
53          loadDefaults();
54          buildMapperMap();
55          createParsers();
56      }
57      
58      // just for unit tests
59      Configurator(Properties props) {
60  //        contentTypeMapperMap = new HashMap<String, PropertyMapper>();
61          this.properties = props;
62      }
63      
64      
65      public PropertyMapper getPropertyMapper(String contentType) {
66          MetadataParser parser = getParser(contentType);
67          return parser.getMapper();
68      }
69      
70      public MetadataParser getParser(String contentType) {
71          MetadataParser parser = parserMap.get(contentType);
72          if (null == parser) {
73              // if not found try a more generic one
74              String genericContentType = contentType.substring(0, contentType.indexOf('/')) + "/*";
75              for (String key: parserMap.keySet()) {
76                  if (key.equals(genericContentType))
77                      return parserMap.get(key);
78              }
79          }
80          return parser;
81          
82  //        for (String contentType : contentTypes) {
83  //            if (contentType.equals(mimeType))
84  //                return cmisTypeId;
85  //            boolean isStar = contentType.endsWith("/*");
86  //            if (isStar) {
87  //                String generalPartParam = mimeType.substring(0, mimeType.indexOf('/'));
88  //                String generalPartCfg = contentType.substring(0, mimeType.indexOf('/'));
89  //                if (generalPartParam.equals(generalPartCfg))
90  //                    return cmisTypeId;
91  //            }
92  //        }
93  //        return null;        
94      }
95  
96      private void loadProperties() {
97          // Returns null on lookup failures:
98          InputStream in = Configurator.class.getResourceAsStream ("/mapping.properties");
99          if (in != null)
100         {
101             properties = new Properties();
102             try {
103                 properties.load (in);
104             } catch (IOException e) {
105                 LOG.error(e);
106                 e.printStackTrace();
107                 throw new MapperException("Could not load file mapping.properties as resource", e);
108             } 
109         }
110     }
111     
112     private void loadDefaults() {
113         defaultDocumentType = properties.getProperty(PREFIX + ".default.document");
114         if (null == defaultDocumentType)
115             defaultDocumentType = "cmis:document";
116         
117         defaultFolderType = properties.getProperty(PREFIX + ".default.folder");
118         if (null == defaultFolderType)
119             defaultFolderType = "cmis:folder";                
120     }
121     
122     public String getDefaultDocumentType() {
123         return defaultDocumentType;
124     }
125     
126     public String getDefaultFolderType() {
127         return defaultFolderType;
128     }
129 
130     public final Properties getProperties() {
131         return properties;
132     }
133     
134     /**
135      * return an overridden MIME type from a file extension
136      * 
137      * @param fileExtension
138      *      enforced or content-type or null if none is set
139      */
140     public String getContentType(String fileExtension) {
141         return properties.getProperty(PREFIX+ ".forceContentType." + fileExtension, null);
142     }
143     
144     String[] getTypeKeys() {
145         String s = properties.getProperty(PREFIX + "s");
146         
147         if (null == s)
148             return null;
149         
150         String[] keys = s.split(",");
151         
152         for (int i=0; i<keys.length; i++)
153             keys[i] = keys[i].trim();
154         
155         return keys;
156     }
157     
158     void  buildMapperMap() {
159         
160         String[] typeKeys = getTypeKeys();
161         for (String typeKey : typeKeys) {
162             PropertyMapper mapper = loadMapperClass(typeKey);
163             String contentType = properties.getProperty(PREFIX + "." + typeKey);
164             if (null == contentType) 
165                 throw new MapperException("Missingt content type in properties: " + PREFIX + "." + contentType);
166             boolean ok = mapper.initialize(PREFIX, typeKey, properties);
167 
168             if (ok)
169                 contentTypeMapperMap.put(typeKey, mapper);
170         }        
171     }
172     
173     void createParsers() {
174         String[] typeKeys = getTypeKeys();
175         for (String typeKey : typeKeys) {
176             MetadataParser parser = loadParserClass(typeKey);
177             String contentType = properties.getProperty(PREFIX + "." + typeKey);
178             if (null == contentType) 
179                 throw new MapperException("Missing content type in properties: " + PREFIX + "." + contentType);
180             
181             PropertyMapper mapper = contentTypeMapperMap.get(typeKey);
182 
183             parser.initialize(mapper, contentType);
184             String[] contentTypes = parser.getContentTypes();
185             for (String ct : contentTypes)
186                 parserMap.put(ct, parser);
187         }                
188     }
189     
190     MetadataParser loadParserClass(String typeKey) {
191         String className = properties.getProperty(PREFIX + "." + typeKey + ".parserClass");
192         if (null == className) // use Tika as default parser if none is configured
193             className = MetadataParserTika.class.getName();
194 //            throw new MapperException("Missing parser class in properties: " + PREFIX + "." + typeKey + ".parserClass");
195 
196         Object obj = null;
197 
198         try {
199             obj = Class.forName(className).newInstance();
200         } catch (InstantiationException e) {
201             LOG.error(e);
202             throw new MapperException(
203                     "Illegal class to load metadata parser, cannot instantiate " + className, e);
204         } catch (IllegalAccessException e) {
205             LOG.error(e);
206             throw new MapperException(
207                     "Illegal class to load metadata parser, cannot access " + className, e);
208         } catch (ClassNotFoundException e) {
209             LOG.error(e);
210             throw new MapperException(
211                     "Illegal class to load metadata parser, class not found: " + className, e);
212         }
213 
214         if (obj instanceof MetadataParser) {
215             return (MetadataParser) obj;
216         } else {
217             throw new MapperException("Illegal class to create metadata parser: " + className + ", must implement MetadataParser interface.");
218         }
219     }
220 
221     PropertyMapper loadMapperClass(String typeKey) {
222         String className = properties.getProperty(PREFIX + "." + typeKey + ".mapperClass");
223         if (null == className) 
224             className = PropertyMapperTika.class.getName();
225 //            throw new MapperException("Missing property mapper in properties: " + PREFIX + "." + typeKey + ".mapperClass");
226 
227         Object obj = null;
228 
229         try {
230             obj = Class.forName(className).newInstance();
231         } catch (InstantiationException e) {
232             LOG.error(e);
233             throw new MapperException(
234                     "Illegal class to load mapping configuration, cannot instantiate " + className, e);
235         } catch (IllegalAccessException e) {
236             LOG.error(e);
237             throw new MapperException(
238                     "Illegal class to load mapping configuration, cannot access " + className, e);
239         } catch (ClassNotFoundException e) {
240             LOG.error(e);
241             throw new MapperException(
242                     "Illegal class to load mapping configuration, class not found: " + className, e);
243         }
244 
245         if (obj instanceof PropertyMapper) {
246             return (PropertyMapper) obj;
247         } else {
248             throw new MapperException("Illegal class to create property mapper: " + className + ", must implement PropertyMapper interface.");
249         }
250     }
251 }