blob: 5831ec95e90f12638298a40eba60c6db5319ce51 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.chemistry.opencmis.tools.mapper;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.chemistry.opencmis.tools.parser.MetadataParser;
import org.apache.chemistry.opencmis.tools.parser.MetadataParserTika;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Configurator {
private static final Logger LOG = LoggerFactory.getLogger(Configurator.class.getName());
private static Configurator instance;
private static final String PREFIX = "mapping.contentType";
public static Configurator getInstance() {
if (null == instance) {
instance = new Configurator();
}
return instance;
}
private Properties properties;
private Map<String, PropertyMapper> contentTypeMapperMap = new HashMap<String, PropertyMapper>();
private Map<String, MetadataParser> parserMap = new HashMap<String, MetadataParser>();
private String defaultDocumentType;
private String defaultFolderType;
private Configurator() {
loadProperties();
loadDefaults();
buildMapperMap();
createParsers();
}
// just for unit tests
Configurator(Properties props) {
this.properties = props;
}
public PropertyMapper getPropertyMapper(String contentType) {
MetadataParser parser = getParser(contentType);
return parser.getMapper();
}
public MetadataParser getParser(String contentType) {
MetadataParser parser = parserMap.get(contentType);
if (null == parser) {
// if not found try a more generic one
String genericContentType = contentType.substring(0, contentType.indexOf('/')) + "/*";
for (String key : parserMap.keySet()) {
if (key.equals(genericContentType)) {
return parserMap.get(key);
}
}
}
return parser;
}
private void loadProperties() {
// Returns null on lookup failures:
InputStream in = Configurator.class.getResourceAsStream("/mapping.properties");
if (in != null) {
properties = new Properties();
try {
properties.load(in);
} catch (IOException e) {
LOG.error(e.toString(), e);
e.printStackTrace();
throw new MapperException("Could not load file mapping.properties as resource", e);
}
}
}
private void loadDefaults() {
defaultDocumentType = properties.getProperty(PREFIX + ".default.document");
if (null == defaultDocumentType) {
defaultDocumentType = "cmis:document";
}
defaultFolderType = properties.getProperty(PREFIX + ".default.folder");
if (null == defaultFolderType) {
defaultFolderType = "cmis:folder";
}
}
public String getDefaultDocumentType() {
return defaultDocumentType;
}
public String getDefaultFolderType() {
return defaultFolderType;
}
public final Properties getProperties() {
return properties;
}
/**
* return an overridden MIME type from a file extension
*
* @param fileExtension
* enforced or content-type or null if none is set
*/
public String getContentType(String fileExtension) {
return properties.getProperty(PREFIX + ".forceContentType." + fileExtension, null);
}
String[] getTypeKeys() {
String s = properties.getProperty(PREFIX + "s");
if (null == s) {
return null;
}
String[] keys = s.split(",");
for (int i = 0; i < keys.length; i++) {
keys[i] = keys[i].trim();
}
return keys;
}
void buildMapperMap() {
String[] typeKeys = getTypeKeys();
for (String typeKey : typeKeys) {
PropertyMapper mapper = loadMapperClass(typeKey);
String contentType = properties.getProperty(PREFIX + "." + typeKey);
if (null == contentType) {
throw new MapperException("Missingt content type in properties: " + PREFIX + "." + typeKey);
}
boolean ok = mapper.initialize(PREFIX, typeKey, properties);
if (ok) {
contentTypeMapperMap.put(typeKey, mapper);
}
}
}
void createParsers() {
String[] typeKeys = getTypeKeys();
for (String typeKey : typeKeys) {
MetadataParser parser = loadParserClass(typeKey);
String contentType = properties.getProperty(PREFIX + "." + typeKey);
if (null == contentType) {
throw new MapperException("Missing content type in properties: " + PREFIX + "." + typeKey);
}
PropertyMapper mapper = contentTypeMapperMap.get(typeKey);
parser.initialize(mapper, contentType);
String[] contentTypes = parser.getContentTypes();
for (String ct : contentTypes) {
parserMap.put(ct, parser);
}
}
}
MetadataParser loadParserClass(String typeKey) {
String className = properties.getProperty(PREFIX + "." + typeKey + ".parserClass");
if (null == className) {// use Tika as default parser if none is
// configured
className = MetadataParserTika.class.getName();
}
Object obj = null;
try {
obj = Class.forName(className).newInstance();
} catch (InstantiationException e) {
LOG.error(e.toString(), e);
throw new MapperException("Illegal class to load metadata parser, cannot instantiate " + className, e);
} catch (IllegalAccessException e) {
LOG.error(e.toString(), e);
throw new MapperException("Illegal class to load metadata parser, cannot access " + className, e);
} catch (ClassNotFoundException e) {
LOG.error(e.toString(), e);
throw new MapperException("Illegal class to load metadata parser, class not found: " + className, e);
}
if (obj instanceof MetadataParser) {
return (MetadataParser) obj;
} else {
throw new MapperException("Illegal class to create metadata parser: " + className
+ ", must implement MetadataParser interface.");
}
}
PropertyMapper loadMapperClass(String typeKey) {
String className = properties.getProperty(PREFIX + "." + typeKey + ".mapperClass");
if (null == className) {
className = PropertyMapperTika.class.getName();
}
Object obj = null;
try {
obj = Class.forName(className).newInstance();
} catch (InstantiationException e) {
LOG.error(e.toString(), e);
throw new MapperException("Illegal class to load mapping configuration, cannot instantiate " + className, e);
} catch (IllegalAccessException e) {
LOG.error(e.toString(), e);
throw new MapperException("Illegal class to load mapping configuration, cannot access " + className, e);
} catch (ClassNotFoundException e) {
LOG.error(e.toString(), e);
throw new MapperException("Illegal class to load mapping configuration, class not found: " + className, e);
}
if (obj instanceof PropertyMapper) {
return (PropertyMapper) obj;
} else {
throw new MapperException("Illegal class to create property mapper: " + className
+ ", must implement PropertyMapper interface.");
}
}
}