You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2012/04/28 18:33:39 UTC

svn commit: r1331791 [9/12] - in /chemistry/opencmis/trunk: ./ chemistry-opencmis-client/chemistry-opencmis-client-bindings/ chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/cache/...

Modified: chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/filecopy/FileCopier.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/filecopy/FileCopier.java?rev=1331791&r1=1331790&r2=1331791&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/filecopy/FileCopier.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/filecopy/FileCopier.java Sat Apr 28 16:33:35 2012
@@ -1,239 +1,239 @@
-/*
- * 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.client.filecopy;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.chemistry.opencmis.client.api.Document;
-import org.apache.chemistry.opencmis.client.api.Folder;
-import org.apache.chemistry.opencmis.client.api.ObjectId;
-import org.apache.chemistry.opencmis.client.api.Session;
-import org.apache.chemistry.opencmis.client.api.SessionFactory;
-import org.apache.chemistry.opencmis.client.mapper.Configurator;
-import org.apache.chemistry.opencmis.client.mapper.MapperException;
-import org.apache.chemistry.opencmis.client.mapper.PropertyMapper;
-import org.apache.chemistry.opencmis.client.parser.MetadataParser;
-import org.apache.chemistry.opencmis.client.parser.MetadataParserTika;
-import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
-import org.apache.chemistry.opencmis.commons.PropertyIds;
-import org.apache.chemistry.opencmis.commons.data.ContentStream;
-import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
-import org.apache.chemistry.opencmis.commons.enums.VersioningState;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.tika.Tika;
-    
-public class FileCopier {
-    
-    private static final Log LOG = LogFactory.getLog(FileCopier.class.getName());
-    // initialize configurator to get parsers and property mappings
-    private static final Configurator CFG = Configurator.getInstance(); 
-    
-    private Session session;
-    
-    public FileCopier() {
-    }
-    
-    public void connect(Map<String, String> parameters) {
-        System.out.println("Connecting to a repository ...");
-
-        // Create a SessionFactory and set up the SessionParameter map
-        SessionFactory sessionFactory = SessionFactoryImpl.newInstance();
-
-        session = sessionFactory.createSession(parameters);
-
-        LOG.debug("Got a connection to repository.");
-    }
-        
-    public void copyRecursive(String folderName, String folderId) {
-
-        try {
-            File fileOrDir = new File(folderName);
-            if (fileOrDir.isDirectory()) {
-                String newFolderId = createFolderInRepository(fileOrDir.getAbsolutePath(), folderId);
-                File[] children = fileOrDir.listFiles();
-                for (File file: children) {
-                    if (!file.getName().equals(".") && !file.getName().equals("..")) {
-                        copyRecursive(file.getAbsolutePath(), newFolderId);
-                    }
-                }
-            } else {
-                copyFileToRepository(fileOrDir.getAbsolutePath(), folderId);
-            }            
-        } catch (Exception e) {
-            LOG.error(e);
-        } finally {  
-        }
-    }
-    
-    private String copyFileToRepository(String fileName, String folderId) {
-        LOG.debug("uploading file " + fileName);
-        FileInputStream is = null;
-        Map<String, Object> properties = new HashMap<String, Object>();
-        Folder parentFolder;
-        String id = null;
-        
-        if (null == folderId)
-            parentFolder = session.getRootFolder();
-        else
-            parentFolder = (Folder) session.getObject(folderId);
-        
-        try {
-            File f = new File(fileName);
-            Tika tika = new Tika();     
-            String mimeType = tika.detect(f);
-            LOG.info("Detected MIME type: "+ mimeType);
-            
-            // extract metadata: first get a parser
-            MetadataParser parser = CFG.getParser(mimeType);
-            if (null == parser) {
-                properties.put(PropertyIds.NAME, f.getName().replaceAll(" ", "_"));
-                properties.put(PropertyIds.OBJECT_TYPE_ID, CFG.getDefaultDocumentType());
-            } else {
-                parser.reset();
-                PropertyMapper mapper = CFG.getPropertyMapper(mimeType);
-                if (null == mapper)
-                    throw new MapperException("Unknown mime type (no configuration): " + mimeType);
-                String typeId = mapper.getMappedTypeId();
-                if (null == typeId)
-                    throw new MapperException("No CMIS type configured for mime type" + mimeType);
-                TypeDefinition td = session.getTypeDefinition(typeId);
-                if (null == td)
-                    throw new MapperException("CMIS type " + typeId + " does not exist on server.");
-
-                LOG.info("Detected MIME type: "+ mimeType + " is mapped to CMIS type id: " + td.getId());
-                parser.extractMetadata(f, td);
-                properties = parser.getCmisProperties();
-            }
-                        
-            // check if there is an overridden content type configured
-            int posLastDot = f.getName().indexOf('.');
-            String ext = posLastDot < 0 ? null : f.getName().substring(posLastDot+1, f.getName().length());
-            String overridden = null;
-            if (null != ext && (overridden = CFG.getContentType(ext)) != null)
-                mimeType = overridden;
-            long length = f.length();
-            
-            is = new FileInputStream(fileName);
-
-            ContentStream contentStream = session.getObjectFactory().createContentStream(fileName,
-                    length, mimeType, is);
-            if (!properties.containsKey(PropertyIds.NAME))
-                properties.put(PropertyIds.NAME, f.getName().replaceAll(" ", "_"));
-            LOG.debug("uploading document with content lenth: " + contentStream.getLength());
-            Document doc = parentFolder.createDocument(properties, contentStream, VersioningState.NONE);
-            id = doc.getId();
-            LOG.info("New document created with id: " + id + ", name: " +  properties.get(PropertyIds.NAME) + " in folder: " + parentFolder.getId());
-        } catch (Exception e) {
-            LOG.error("Failed to create CMIS document.", e);
-        } finally {
-            if (null != is) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                    LOG.error(e);
-                }
-            }
-            LOG.debug("Conversion and transfer done.");    
-        }
-        return id;
-    }
-    
-    private  String createFolderInRepository(String fileName, String parentFolderId) {
-        Folder parentFolder;
-        String id = null;
-        if (null == parentFolderId)
-            parentFolder = session.getRootFolder();
-        else
-            parentFolder = (Folder) session.getObject(parentFolderId);
-        Map<String, Object> properties = new HashMap<String, Object>();
-        File f = new File(fileName);
-        properties.put(PropertyIds.NAME, f.getName().replaceAll(" ", "_"));
-        properties.put(PropertyIds.OBJECT_TYPE_ID, CFG.getDefaultFolderType());
-        try {
-            Folder folder = parentFolder.createFolder(properties);
-            id = folder.getId();
-            LOG.debug("New folder created with id: " + folder.getId() + ", path: " + folder.getPaths().get(0));
-        } catch (Exception e) {
-            LOG.error("Failed to create CMIS document.", e);
-        } finally {
-        }
-        LOG.info("New folder created with id: " + id + ", name: " +  properties.get(PropertyIds.NAME) + " in parent folder: " + parentFolder.getId());
-        return id;
-    }
-    
-    public void listMetadata(String fileName) {
-        try {
-            File f = new File(fileName);
-            Tika tika = new Tika();     
-            String mimeType = tika.detect(f);
-            LOG.info("Detected MIME type: "+ mimeType);
-            
-            // extract metadata: first get a parser
-            MetadataParser parser = CFG.getParser(mimeType);
-            if (null == parser) {
-                LOG.warn("Unknown content type " + mimeType + " no metadata found, listing all tags found in file.");
-                MetadataParserTika mpt = new MetadataParserTika();
-                mpt.listMetadata(f);
-            } else {
-                PropertyMapper mapper = CFG.getPropertyMapper(mimeType);
-                if (null == mapper)
-                    throw new MapperException("Unknown mime type (no configuration): " + mimeType);
-                String typeId = mapper.getMappedTypeId();
-                if (null == typeId)
-                    throw new MapperException("No CMIS type configured for mime type" + mimeType);
-                
-                // Session available? if yes do conversion
-                TypeDefinition td = null;
-                if (null!= session) {
-                    session.getTypeDefinition(typeId);
-                    if (null == td)
-                        throw new MapperException("CMIS type " + typeId + " does not exist on server.");
-                }
-                LOG.info("Detected MIME type: "+ mimeType + " is mapped to CMIS type id: " + td.getId());
-                
-                parser.extractMetadata(f, td);
-                Map<String, Object> properties = parser.getCmisProperties();
-                for (String key : properties.keySet()) {
-                    LOG.info("Found metadata tag " + key + "mapped to " + properties.get(key));
-                }
-            }                        
-        } catch (Exception e) {
-            LOG.error("Failed to list metadata", e);
-        } finally {
-        }
-        LOG.debug("Conversion and transfer done.");            
-    }
-    
-    static public void main(String[] args) {
-        String fileName = args[0];
-        LOG.debug("extracting CMIS properties for file " + fileName);
-        try {
-            new FileCopier().listMetadata(fileName);            
-        } catch (Exception e) {
-            LOG.error(e);
-        } finally {
-        }
-        LOG.debug("Extraction done.");    
-    }
-}
+/*
+ * 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.client.filecopy;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.chemistry.opencmis.client.api.Document;
+import org.apache.chemistry.opencmis.client.api.Folder;
+import org.apache.chemistry.opencmis.client.api.ObjectId;
+import org.apache.chemistry.opencmis.client.api.Session;
+import org.apache.chemistry.opencmis.client.api.SessionFactory;
+import org.apache.chemistry.opencmis.client.mapper.Configurator;
+import org.apache.chemistry.opencmis.client.mapper.MapperException;
+import org.apache.chemistry.opencmis.client.mapper.PropertyMapper;
+import org.apache.chemistry.opencmis.client.parser.MetadataParser;
+import org.apache.chemistry.opencmis.client.parser.MetadataParserTika;
+import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.data.ContentStream;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
+import org.apache.chemistry.opencmis.commons.enums.VersioningState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.tika.Tika;
+    
+public class FileCopier {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(FileCopier.class.getName());
+    // initialize configurator to get parsers and property mappings
+    private static final Configurator CFG = Configurator.getInstance(); 
+    
+    private Session session;
+    
+    public FileCopier() {
+    }
+    
+    public void connect(Map<String, String> parameters) {
+        System.out.println("Connecting to a repository ...");
+
+        // Create a SessionFactory and set up the SessionParameter map
+        SessionFactory sessionFactory = SessionFactoryImpl.newInstance();
+
+        session = sessionFactory.createSession(parameters);
+
+        LOG.debug("Got a connection to repository.");
+    }
+        
+    public void copyRecursive(String folderName, String folderId) {
+
+        try {
+            File fileOrDir = new File(folderName);
+            if (fileOrDir.isDirectory()) {
+                String newFolderId = createFolderInRepository(fileOrDir.getAbsolutePath(), folderId);
+                File[] children = fileOrDir.listFiles();
+                for (File file: children) {
+                    if (!file.getName().equals(".") && !file.getName().equals("..")) {
+                        copyRecursive(file.getAbsolutePath(), newFolderId);
+                    }
+                }
+            } else {
+                copyFileToRepository(fileOrDir.getAbsolutePath(), folderId);
+            }            
+        } catch (Exception e) {
+            LOG.error(e.toString(), e);
+        } finally {  
+        }
+    }
+    
+    private String copyFileToRepository(String fileName, String folderId) {
+        LOG.debug("uploading file " + fileName);
+        FileInputStream is = null;
+        Map<String, Object> properties = new HashMap<String, Object>();
+        Folder parentFolder;
+        String id = null;
+        
+        if (null == folderId)
+            parentFolder = session.getRootFolder();
+        else
+            parentFolder = (Folder) session.getObject(folderId);
+        
+        try {
+            File f = new File(fileName);
+            Tika tika = new Tika();     
+            String mimeType = tika.detect(f);
+            LOG.info("Detected MIME type: "+ mimeType);
+            
+            // extract metadata: first get a parser
+            MetadataParser parser = CFG.getParser(mimeType);
+            if (null == parser) {
+                properties.put(PropertyIds.NAME, f.getName().replaceAll(" ", "_"));
+                properties.put(PropertyIds.OBJECT_TYPE_ID, CFG.getDefaultDocumentType());
+            } else {
+                parser.reset();
+                PropertyMapper mapper = CFG.getPropertyMapper(mimeType);
+                if (null == mapper)
+                    throw new MapperException("Unknown mime type (no configuration): " + mimeType);
+                String typeId = mapper.getMappedTypeId();
+                if (null == typeId)
+                    throw new MapperException("No CMIS type configured for mime type" + mimeType);
+                TypeDefinition td = session.getTypeDefinition(typeId);
+                if (null == td)
+                    throw new MapperException("CMIS type " + typeId + " does not exist on server.");
+
+                LOG.info("Detected MIME type: "+ mimeType + " is mapped to CMIS type id: " + td.getId());
+                parser.extractMetadata(f, td);
+                properties = parser.getCmisProperties();
+            }
+                        
+            // check if there is an overridden content type configured
+            int posLastDot = f.getName().indexOf('.');
+            String ext = posLastDot < 0 ? null : f.getName().substring(posLastDot+1, f.getName().length());
+            String overridden = null;
+            if (null != ext && (overridden = CFG.getContentType(ext)) != null)
+                mimeType = overridden;
+            long length = f.length();
+            
+            is = new FileInputStream(fileName);
+
+            ContentStream contentStream = session.getObjectFactory().createContentStream(fileName,
+                    length, mimeType, is);
+            if (!properties.containsKey(PropertyIds.NAME))
+                properties.put(PropertyIds.NAME, f.getName().replaceAll(" ", "_"));
+            LOG.debug("uploading document with content lenth: " + contentStream.getLength());
+            Document doc = parentFolder.createDocument(properties, contentStream, VersioningState.NONE);
+            id = doc.getId();
+            LOG.info("New document created with id: " + id + ", name: " +  properties.get(PropertyIds.NAME) + " in folder: " + parentFolder.getId());
+        } catch (Exception e) {
+            LOG.error("Failed to create CMIS document.", e);
+        } finally {
+            if (null != is) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    LOG.error(e.toString(), e);
+                }
+            }
+            LOG.debug("Conversion and transfer done.");    
+        }
+        return id;
+    }
+    
+    private  String createFolderInRepository(String fileName, String parentFolderId) {
+        Folder parentFolder;
+        String id = null;
+        if (null == parentFolderId)
+            parentFolder = session.getRootFolder();
+        else
+            parentFolder = (Folder) session.getObject(parentFolderId);
+        Map<String, Object> properties = new HashMap<String, Object>();
+        File f = new File(fileName);
+        properties.put(PropertyIds.NAME, f.getName().replaceAll(" ", "_"));
+        properties.put(PropertyIds.OBJECT_TYPE_ID, CFG.getDefaultFolderType());
+        try {
+            Folder folder = parentFolder.createFolder(properties);
+            id = folder.getId();
+            LOG.debug("New folder created with id: " + folder.getId() + ", path: " + folder.getPaths().get(0));
+        } catch (Exception e) {
+            LOG.error("Failed to create CMIS document.", e);
+        } finally {
+        }
+        LOG.info("New folder created with id: " + id + ", name: " +  properties.get(PropertyIds.NAME) + " in parent folder: " + parentFolder.getId());
+        return id;
+    }
+    
+    public void listMetadata(String fileName) {
+        try {
+            File f = new File(fileName);
+            Tika tika = new Tika();     
+            String mimeType = tika.detect(f);
+            LOG.info("Detected MIME type: "+ mimeType);
+            
+            // extract metadata: first get a parser
+            MetadataParser parser = CFG.getParser(mimeType);
+            if (null == parser) {
+                LOG.warn("Unknown content type " + mimeType + " no metadata found, listing all tags found in file.");
+                MetadataParserTika mpt = new MetadataParserTika();
+                mpt.listMetadata(f);
+            } else {
+                PropertyMapper mapper = CFG.getPropertyMapper(mimeType);
+                if (null == mapper)
+                    throw new MapperException("Unknown mime type (no configuration): " + mimeType);
+                String typeId = mapper.getMappedTypeId();
+                if (null == typeId)
+                    throw new MapperException("No CMIS type configured for mime type" + mimeType);
+                
+                // Session available? if yes do conversion
+                TypeDefinition td = null;
+                if (null!= session) {
+                    session.getTypeDefinition(typeId);
+                    if (null == td)
+                        throw new MapperException("CMIS type " + typeId + " does not exist on server.");
+                }
+                LOG.info("Detected MIME type: "+ mimeType + " is mapped to CMIS type id: " + td.getId());
+                
+                parser.extractMetadata(f, td);
+                Map<String, Object> properties = parser.getCmisProperties();
+                for (String key : properties.keySet()) {
+                    LOG.info("Found metadata tag " + key + "mapped to " + properties.get(key));
+                }
+            }                        
+        } catch (Exception e) {
+            LOG.error("Failed to list metadata", e);
+        } finally {
+        }
+        LOG.debug("Conversion and transfer done.");            
+    }
+    
+    static public void main(String[] args) {
+        String fileName = args[0];
+        LOG.debug("extracting CMIS properties for file " + fileName);
+        try {
+            new FileCopier().listMetadata(fileName);            
+        } catch (Exception e) {
+            LOG.error(e.toString(), e);
+        } finally {
+        }
+        LOG.debug("Extraction done.");    
+    }
+}

Modified: chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/mapper/Configurator.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/mapper/Configurator.java?rev=1331791&r1=1331790&r2=1331791&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/mapper/Configurator.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/mapper/Configurator.java Sat Apr 28 16:33:35 2012
@@ -1,251 +1,251 @@
-/*
- * 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.client.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.client.parser.MetadataParser;
-import org.apache.chemistry.opencmis.client.parser.MetadataParserTika;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-public class Configurator {
-
-    private static final Log LOG = LogFactory.getLog(Configurator.class.getName());
-    
-    private static Configurator INSTANCE;
-    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) {
-//        contentTypeMapperMap = new HashMap<String, PropertyMapper>();
-        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;
-        
-//        for (String contentType : contentTypes) {
-//            if (contentType.equals(mimeType))
-//                return cmisTypeId;
-//            boolean isStar = contentType.endsWith("/*");
-//            if (isStar) {
-//                String generalPartParam = mimeType.substring(0, mimeType.indexOf('/'));
-//                String generalPartCfg = contentType.substring(0, mimeType.indexOf('/'));
-//                if (generalPartParam.equals(generalPartCfg))
-//                    return cmisTypeId;
-//            }
-//        }
-//        return null;        
-    }
-
-    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);
-                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 + "." + contentType);
-            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 + "." + contentType);
-            
-            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();
-//            throw new MapperException("Missing parser class in properties: " + PREFIX + "." + typeKey + ".parserClass");
-
-        Object obj = null;
-
-        try {
-            obj = Class.forName(className).newInstance();
-        } catch (InstantiationException e) {
-            LOG.error(e);
-            throw new MapperException(
-                    "Illegal class to load metadata parser, cannot instantiate " + className, e);
-        } catch (IllegalAccessException e) {
-            LOG.error(e);
-            throw new MapperException(
-                    "Illegal class to load metadata parser, cannot access " + className, e);
-        } catch (ClassNotFoundException e) {
-            LOG.error(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();
-//            throw new MapperException("Missing property mapper in properties: " + PREFIX + "." + typeKey + ".mapperClass");
-
-        Object obj = null;
-
-        try {
-            obj = Class.forName(className).newInstance();
-        } catch (InstantiationException e) {
-            LOG.error(e);
-            throw new MapperException(
-                    "Illegal class to load mapping configuration, cannot instantiate " + className, e);
-        } catch (IllegalAccessException e) {
-            LOG.error(e);
-            throw new MapperException(
-                    "Illegal class to load mapping configuration, cannot access " + className, e);
-        } catch (ClassNotFoundException e) {
-            LOG.error(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.");
-        }
-    }
-}
+/*
+ * 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.client.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.client.parser.MetadataParser;
+import org.apache.chemistry.opencmis.client.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;
+    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) {
+//        contentTypeMapperMap = new HashMap<String, PropertyMapper>();
+        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;
+        
+//        for (String contentType : contentTypes) {
+//            if (contentType.equals(mimeType))
+//                return cmisTypeId;
+//            boolean isStar = contentType.endsWith("/*");
+//            if (isStar) {
+//                String generalPartParam = mimeType.substring(0, mimeType.indexOf('/'));
+//                String generalPartCfg = contentType.substring(0, mimeType.indexOf('/'));
+//                if (generalPartParam.equals(generalPartCfg))
+//                    return cmisTypeId;
+//            }
+//        }
+//        return null;        
+    }
+
+    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 + "." + contentType);
+            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 + "." + contentType);
+            
+            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();
+//            throw new MapperException("Missing parser class in properties: " + PREFIX + "." + typeKey + ".parserClass");
+
+        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();
+//            throw new MapperException("Missing property mapper in properties: " + PREFIX + "." + typeKey + ".mapperClass");
+
+        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.");
+        }
+    }
+}

Modified: chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/mapper/PropertyMapperExif.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/mapper/PropertyMapperExif.java?rev=1331791&r1=1331790&r2=1331791&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/mapper/PropertyMapperExif.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-client/src/main/java/org/apache/chemistry/opencmis/client/mapper/PropertyMapperExif.java Sat Apr 28 16:33:35 2012
@@ -1,325 +1,325 @@
-/*
- * 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.client.mapper;
-
-import java.lang.reflect.Array;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
-import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
-import org.apache.chemistry.opencmis.commons.enums.PropertyType;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import com.drew.imaging.PhotographicConversions;
-import com.drew.lang.Rational;
-import com.drew.metadata.Directory;
-import com.drew.metadata.Tag;
-import com.drew.metadata.exif.ExifDirectory;
-import com.drew.metadata.exif.GpsDirectory;
-import com.drew.metadata.jpeg.JpegDirectory;
-
-public class PropertyMapperExif extends AbstractPropertyMapper {
-
-    private static final Log LOG = LogFactory.getLog(PropertyMapperExif.class.getName());
-    private static String EXIF_DATE_FORMAT = "yyyy:MM:dd HH:mm:ss";
-
-    private Map<String, String> propMapExif = new HashMap<String, String> (); // tag to property id
-    private Map<String, String> propMapGps = new HashMap<String, String> ();  // tag to property id
-    private Map<String, String> propMapJpeg = new HashMap<String, String> (); // tag to property id
-    
-    protected Map<String, Object> propMap;
-
-    public boolean initialize(String cfgPrefix, String typeKey, Properties properties) {
-        super.initialize(cfgPrefix, typeKey, properties);
-        reset();
-        dateFormat = EXIF_DATE_FORMAT;
-        buildIdMap("exif", propMapExif, properties);
-        buildIdMap("gps", propMapGps, properties);
-        buildIdMap("jpeg", propMapJpeg, properties);
-        
-        return true;
-    }
-
-    public void reset() {
-        propMap = new HashMap<String, Object> ();
-    }
-    
-
-    public Map<String, Object> getMappedProperties() {
-        return propMap;
-    }
-    
-    private void buildIdMap(String dirKey, Map<String, String> propMap, Properties properties) {
-        Set<String> keys = properties.stringPropertyNames(); 
-        String prefix = propPrefix + "." + dirKey + ".id.";
-        for (String key : keys) {
-            if (key.startsWith(prefix)) {
-                String id = key.substring(prefix.length());
-                String cmisPropId = properties.getProperty(key).trim();
-                if (null == cmisPropId)
-                    throw new MapperException("Configuration key " + key + " must have a value assigned");
-                LOG.debug("Found mapping for type " + dirKey + " with " + id + " to " + cmisPropId);
-                propMap.put(id,  cmisPropId);
-            }
-        }
-    }
-
-    public String getMappedTypeId(String mimeType) {
-        return cmisTypeId;
-    }
-
-    public String getMappedPropertyId(String key) {
-        return null;
-    }
-
-    public Object convertValue(String id, PropertyDefinition<?> propDef, String strValue) {
-        return null;
-    }
-
-    private String getHexString(int tagType) {
-        StringBuffer hexStr = new StringBuffer();
-        hexStr.append(Integer.toHexString(tagType));
-        while (hexStr.length() < 4)
-            hexStr.insert(0, "0");
-        hexStr.insert(0, "0x");
-        return hexStr.toString();
-    }
-    /**
-     * store the property id mapped to this tag in a JPEG file in a local map
-     * @param dir
-     *      directory of tag
-     * @param tag
-     *      tag
-     */
-    
-    public void mapTagAndConvert(Directory dir, Tag tag, TypeDefinition td) {
-        String propId = null;
-        String hexStr = getHexString(tag.getTagType());
-        
-        if (GpsDirectory.class.equals(dir.getClass())) {
-            propId = propMapGps.get(hexStr);
-        } else if (ExifDirectory.class.equals(dir.getClass())) {
-            propId = propMapExif.get(hexStr);
-        } else if (JpegDirectory.class.equals(dir.getClass())) {
-            propId = propMapJpeg.get(hexStr);
-        } else
-            propId = null;
-        
-        if (null != propId) {
-            if (null != td) {
-                PropertyDefinition<?> pd = td.getPropertyDefinitions().get(propId);
-                if (null == pd)
-                    throw new MapperException("Unknown property id " + propId + " in type definition " + td.getId());
-                PropertyType pt = pd.getPropertyType();
-                Object convValue = convertValue(dir, tag, pt);
-                propMap.put(propId, convValue);
-            } else
-                propMap.put(propId, dir.getObject(tag.getTagType())); // omit conversion if no type definition is available
-        }
-    }
-    
-    public Object convertValue(Directory dir, Tag tag, PropertyType propType) {
-        
-        Object res = null;
-        String hexStr = getHexString(tag.getTagType());
-
-        // Handle all tags corresponding to their directory specifics
-        if (GpsDirectory.class.equals(dir.getClass())) {
-            // first check for those tags that need special consideration:
-            if ( GpsDirectory.TAG_GPS_LONGITUDE == tag.getTagType()) {
-                Object ref = dir.getObject(GpsDirectory.TAG_GPS_DEST_LONGITUDE_REF);
-                boolean mustInv = ref != null && ref.equals('W');
-                return convertGps(tag, dir, mustInv);
-            } else if ( GpsDirectory.TAG_GPS_LATITUDE == tag.getTagType()) {
-                Object ref = dir.getObject(GpsDirectory.TAG_GPS_DEST_LONGITUDE_REF);
-                boolean mustInv = ref != null && ref.equals('S');
-                return convertGps(tag, dir, mustInv);
-            } else {
-                String propId = propMapGps.get(hexStr);
-                LOG.debug("Found GPS tag '" + tag + "\', property mapped is: " + propId);
-                if (null == propId) {
-                    LOG.info("Ignoring EXIF tag '" + tag + "\' no property mapped to this tag.");
-                } else if (propType == null) {
-                    // should not happen and is a configuration error: we have a property id but no type
-                    LOG.error("Ignoring EXIF tag '" + tag + "\' no property type mapped to this tag.");
-                }
-                Object src = dir.getObject(tag.getTagType());        
-                Class<?> clazz = src.getClass();
-                if (clazz.equals(Rational.class)) {
-                    // expect a CMIS decimal property
-                    if (propType != PropertyType.DECIMAL)
-                        throw new MapperException("Tag value has type Rational and expected CMIS Decimal, but found: " + propType + " for tag: " + tag);
-                    double d = ((Rational) src).doubleValue();
-                    res = d;
-                } else if (clazz.equals(String.class)) {
-                    if (propType != PropertyType.STRING && propType != PropertyType.ID && propType != PropertyType.URI &&
-                            propType != PropertyType.HTML && propType != PropertyType.DATETIME)
-                        throw new MapperException("Tag value has type String and expected CMIS String, but found: " + propType + " for tag: " + tag);
-                    String s = ((String) src);
-                    res = s;
-                } else
-                res = null;
-            }
-        } else if (ExifDirectory.class.equals(dir.getClass())) {
-            // is there a property mapped to this tag?
-            String propId = propMapExif.get(hexStr);
-            LOG.debug("Found EXIF tag '" + tag + "\', property mapped is: " + propId);
-
-            if (null == propId) {
-                LOG.debug("Ignoring EXIF tag '" + tag + "\' no property mapped to this tag.");
-            } else if (propType == null) {
-                // should not happen and is a configuration error: we have a property id but no type
-                LOG.error("Ignoring EXIF tag '" + tag + "\' no property type mapped to this tag.");
-            } else {
-                Object src = dir.getObject(tag.getTagType());        
-                Class<?> clazz = src.getClass();
-                // handle arrays and map them to multi-value properties
-                if (clazz.isArray()) {
-                    LOG.error("Found a multi-value tag " + tag + ": multi value not implemented");
-                    return null;
-                }
-                if (clazz.equals(Rational.class)) {
-                    // expect a CMIS decimal property
-                    if (propType != PropertyType.DECIMAL)
-                        throw new MapperException("Tag value has type Rational and expected CMIS Decimal, but found: " + propType + " for tag: " + tag);
-                    
-                    if (tag.getTagType() == ExifDirectory.TAG_SHUTTER_SPEED) {
-                        // requires special handling, see Tika impl.
-                        double apexValue = ((Rational) src).doubleValue();
-                        res = PhotographicConversions.shutterSpeedToExposureTime(apexValue);
-                    } else if (tag.getTagType() == (ExifDirectory.TAG_APERTURE)) {
-                        double aperture =((Rational) src).doubleValue();
-                        double fStop = PhotographicConversions.apertureToFStop(aperture);
-                        res = fStop;
-                    } else {
-                        // convert to a double
-                        double d = ((Rational) src).doubleValue();
-                        res = d;
-                    }
-                } else if (clazz.equals(Integer.class)) {
-                    if (propType != PropertyType.INTEGER)
-                        throw new MapperException("Tag value has type Integer and expected CMIS Integer, but found: " + propType + " for tag: " + tag);
-                    // convert to a long
-                    long l = ((Integer) src).longValue();
-                    res = l;                                        
-                } else if (clazz.equals(String.class)) {
-                    if (propType != PropertyType.STRING && propType != PropertyType.ID && propType != PropertyType.URI &&
-                            propType != PropertyType.HTML && propType != PropertyType.DATETIME)
-                        throw new MapperException("Tag value has type String and expected CMIS String, but found: " + propType + " for tag: " + tag);
-                    // convert to a String
-                    if (propType == PropertyType.DATETIME) {
-                        // parse format: 2012:02:25 16:23:16
-                        DateFormat formatter = new SimpleDateFormat(dateFormat);
-                        GregorianCalendar cal;
-                        try {
-                            Date date = (Date)formatter.parse((String) src);
-                            // convert date to GreogorianCalendar as CMIS expects
-                            cal = new GregorianCalendar();
-                            cal.setTime(date);
-                        } catch (ParseException e) {
-                            LOG.error(e);
-                            throw new MapperException("Unrecognized date format in EXIF date tag: " + src + " for tag: " + tag + " expected: yyyy:MM:dd HH:mm:ss");
-                        }
-                        res = cal;                     
-                    } else {
-                        String s = ((String) src);
-                        res = s;
-                    }
-                } else if (clazz.equals(Date.class)) {
-                    if (propType != PropertyType.DATETIME)
-                        throw new MapperException("Tag value has type Date and expected CMIS DateTime, but found: " + propType + " for tag: " + tag);
-                    // convert to a String
-                    Date date = ((Date) src);
-                    // convert date to GreogorianCalendar as CMIS expects
-                    GregorianCalendar  cal= new GregorianCalendar();
-                    cal.setTime(date);
-                    res = cal;                                        
-                } else if (clazz.equals(Boolean.class)) {
-                    if (propType != PropertyType.BOOLEAN)
-                        throw new MapperException("Tag value has type Boolean and expected CMIS Boolean, but found: " + propType + " for tag: " + tag);
-                    // convert to a String
-                    Boolean b = ((Boolean) src);
-                    res = b;                                        
-                } else {
-                    LOG.debug("Tag value has unsupported type: " + clazz.getName() + " for EXIF tag: " + tag);
-                    // throw new MapperException("Tag value has unsupported type: " + clazz.getName() + " for tag: " + tag);
-                }                
-            }            
-        } else if (JpegDirectory.class.equals(dir.getClass())) {
-            // is there a property mapped to this tag?
-            String propId = propMapJpeg.get(hexStr);
-            LOG.debug("Found JPEG tag '" + tag + "\', property mapped is: " + propId);
-
-            if (null == propId) {
-                LOG.info("Ignoring JPEG tag '" + tag + "\' no property mapped to this tag.");
-            } else if (propType == null) {
-                // should not happen and is a configuration error: we have a property id but no type
-                LOG.error("Ignoring JPEG tag '" + tag + "\' no property type mapped to this tag.");
-            } else {
-                Object src = dir.getObject(tag.getTagType());        
-                Class<?> clazz = src.getClass();
-
-                if (clazz.equals(Integer.class)) {
-                    if (propType != PropertyType.INTEGER)
-                        throw new MapperException("Tag value has type Integer and expected CMIS Integer, but found: " + propType + " for tag: " + tag);
-                    // convert to a long
-                    long l = ((Integer) src).longValue();
-                    res = l;                                        
-                } else {
-                    LOG.debug("Tag value has unsupported type: " + clazz.getName() + " for JPEG tag: " + tag);
-                }
-            }            
-        }
-            
-        return res;        
-    }
-    
-    private static Object convertGps(Tag tag, Directory dir, boolean mustInvert) {
-        Double res = null; 
-        Object src = dir.getObject(tag.getTagType());
-        
-        Class<?> stringArrayClass = src.getClass();
-        Class<?> stringArrayComponentType = stringArrayClass.getComponentType();
-        if (!stringArrayClass.isArray() || null == stringArrayComponentType || Array.getLength(src) != 3) 
-            throw new MapperException("GPS coordinate \"" + tag + "\" has unknown type.");
-        if (!stringArrayComponentType.equals(Rational.class))
-            throw new MapperException("GPS coordinate \"" + tag + "\" has unknown component type (expected Rational, found: " + 
-                    stringArrayComponentType.getName() + ")");
-        // do conversion
-        Rational[] components;
-        components = (Rational[]) src;
-        int deg = components[0].intValue();
-        double min = components[1].doubleValue();
-        double sec = components[2].doubleValue();
-        Double d = (deg + min / 60 + sec / 3600);
-        if (d > 0.0 && mustInvert)
-            d = -d;
-        res = d;
-        return res;
-    }
-}
+/*
+ * 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.client.mapper;
+
+import java.lang.reflect.Array;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
+import org.apache.chemistry.opencmis.commons.enums.PropertyType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.drew.imaging.PhotographicConversions;
+import com.drew.lang.Rational;
+import com.drew.metadata.Directory;
+import com.drew.metadata.Tag;
+import com.drew.metadata.exif.ExifDirectory;
+import com.drew.metadata.exif.GpsDirectory;
+import com.drew.metadata.jpeg.JpegDirectory;
+
+public class PropertyMapperExif extends AbstractPropertyMapper {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PropertyMapperExif.class.getName());
+    private static String EXIF_DATE_FORMAT = "yyyy:MM:dd HH:mm:ss";
+
+    private Map<String, String> propMapExif = new HashMap<String, String> (); // tag to property id
+    private Map<String, String> propMapGps = new HashMap<String, String> ();  // tag to property id
+    private Map<String, String> propMapJpeg = new HashMap<String, String> (); // tag to property id
+    
+    protected Map<String, Object> propMap;
+
+    public boolean initialize(String cfgPrefix, String typeKey, Properties properties) {
+        super.initialize(cfgPrefix, typeKey, properties);
+        reset();
+        dateFormat = EXIF_DATE_FORMAT;
+        buildIdMap("exif", propMapExif, properties);
+        buildIdMap("gps", propMapGps, properties);
+        buildIdMap("jpeg", propMapJpeg, properties);
+        
+        return true;
+    }
+
+    public void reset() {
+        propMap = new HashMap<String, Object> ();
+    }
+    
+
+    public Map<String, Object> getMappedProperties() {
+        return propMap;
+    }
+    
+    private void buildIdMap(String dirKey, Map<String, String> propMap, Properties properties) {
+        Set<String> keys = properties.stringPropertyNames(); 
+        String prefix = propPrefix + "." + dirKey + ".id.";
+        for (String key : keys) {
+            if (key.startsWith(prefix)) {
+                String id = key.substring(prefix.length());
+                String cmisPropId = properties.getProperty(key).trim();
+                if (null == cmisPropId)
+                    throw new MapperException("Configuration key " + key + " must have a value assigned");
+                LOG.debug("Found mapping for type " + dirKey + " with " + id + " to " + cmisPropId);
+                propMap.put(id,  cmisPropId);
+            }
+        }
+    }
+
+    public String getMappedTypeId(String mimeType) {
+        return cmisTypeId;
+    }
+
+    public String getMappedPropertyId(String key) {
+        return null;
+    }
+
+    public Object convertValue(String id, PropertyDefinition<?> propDef, String strValue) {
+        return null;
+    }
+
+    private String getHexString(int tagType) {
+        StringBuffer hexStr = new StringBuffer();
+        hexStr.append(Integer.toHexString(tagType));
+        while (hexStr.length() < 4)
+            hexStr.insert(0, "0");
+        hexStr.insert(0, "0x");
+        return hexStr.toString();
+    }
+    /**
+     * store the property id mapped to this tag in a JPEG file in a local map
+     * @param dir
+     *      directory of tag
+     * @param tag
+     *      tag
+     */
+    
+    public void mapTagAndConvert(Directory dir, Tag tag, TypeDefinition td) {
+        String propId = null;
+        String hexStr = getHexString(tag.getTagType());
+        
+        if (GpsDirectory.class.equals(dir.getClass())) {
+            propId = propMapGps.get(hexStr);
+        } else if (ExifDirectory.class.equals(dir.getClass())) {
+            propId = propMapExif.get(hexStr);
+        } else if (JpegDirectory.class.equals(dir.getClass())) {
+            propId = propMapJpeg.get(hexStr);
+        } else
+            propId = null;
+        
+        if (null != propId) {
+            if (null != td) {
+                PropertyDefinition<?> pd = td.getPropertyDefinitions().get(propId);
+                if (null == pd)
+                    throw new MapperException("Unknown property id " + propId + " in type definition " + td.getId());
+                PropertyType pt = pd.getPropertyType();
+                Object convValue = convertValue(dir, tag, pt);
+                propMap.put(propId, convValue);
+            } else
+                propMap.put(propId, dir.getObject(tag.getTagType())); // omit conversion if no type definition is available
+        }
+    }
+    
+    public Object convertValue(Directory dir, Tag tag, PropertyType propType) {
+        
+        Object res = null;
+        String hexStr = getHexString(tag.getTagType());
+
+        // Handle all tags corresponding to their directory specifics
+        if (GpsDirectory.class.equals(dir.getClass())) {
+            // first check for those tags that need special consideration:
+            if ( GpsDirectory.TAG_GPS_LONGITUDE == tag.getTagType()) {
+                Object ref = dir.getObject(GpsDirectory.TAG_GPS_DEST_LONGITUDE_REF);
+                boolean mustInv = ref != null && ref.equals('W');
+                return convertGps(tag, dir, mustInv);
+            } else if ( GpsDirectory.TAG_GPS_LATITUDE == tag.getTagType()) {
+                Object ref = dir.getObject(GpsDirectory.TAG_GPS_DEST_LONGITUDE_REF);
+                boolean mustInv = ref != null && ref.equals('S');
+                return convertGps(tag, dir, mustInv);
+            } else {
+                String propId = propMapGps.get(hexStr);
+                LOG.debug("Found GPS tag '" + tag + "\', property mapped is: " + propId);
+                if (null == propId) {
+                    LOG.info("Ignoring EXIF tag '" + tag + "\' no property mapped to this tag.");
+                } else if (propType == null) {
+                    // should not happen and is a configuration error: we have a property id but no type
+                    LOG.error("Ignoring EXIF tag '" + tag + "\' no property type mapped to this tag.");
+                }
+                Object src = dir.getObject(tag.getTagType());        
+                Class<?> clazz = src.getClass();
+                if (clazz.equals(Rational.class)) {
+                    // expect a CMIS decimal property
+                    if (propType != PropertyType.DECIMAL)
+                        throw new MapperException("Tag value has type Rational and expected CMIS Decimal, but found: " + propType + " for tag: " + tag);
+                    double d = ((Rational) src).doubleValue();
+                    res = d;
+                } else if (clazz.equals(String.class)) {
+                    if (propType != PropertyType.STRING && propType != PropertyType.ID && propType != PropertyType.URI &&
+                            propType != PropertyType.HTML && propType != PropertyType.DATETIME)
+                        throw new MapperException("Tag value has type String and expected CMIS String, but found: " + propType + " for tag: " + tag);
+                    String s = ((String) src);
+                    res = s;
+                } else
+                res = null;
+            }
+        } else if (ExifDirectory.class.equals(dir.getClass())) {
+            // is there a property mapped to this tag?
+            String propId = propMapExif.get(hexStr);
+            LOG.debug("Found EXIF tag '" + tag + "\', property mapped is: " + propId);
+
+            if (null == propId) {
+                LOG.debug("Ignoring EXIF tag '" + tag + "\' no property mapped to this tag.");
+            } else if (propType == null) {
+                // should not happen and is a configuration error: we have a property id but no type
+                LOG.error("Ignoring EXIF tag '" + tag + "\' no property type mapped to this tag.");
+            } else {
+                Object src = dir.getObject(tag.getTagType());        
+                Class<?> clazz = src.getClass();
+                // handle arrays and map them to multi-value properties
+                if (clazz.isArray()) {
+                    LOG.error("Found a multi-value tag " + tag + ": multi value not implemented");
+                    return null;
+                }
+                if (clazz.equals(Rational.class)) {
+                    // expect a CMIS decimal property
+                    if (propType != PropertyType.DECIMAL)
+                        throw new MapperException("Tag value has type Rational and expected CMIS Decimal, but found: " + propType + " for tag: " + tag);
+                    
+                    if (tag.getTagType() == ExifDirectory.TAG_SHUTTER_SPEED) {
+                        // requires special handling, see Tika impl.
+                        double apexValue = ((Rational) src).doubleValue();
+                        res = PhotographicConversions.shutterSpeedToExposureTime(apexValue);
+                    } else if (tag.getTagType() == (ExifDirectory.TAG_APERTURE)) {
+                        double aperture =((Rational) src).doubleValue();
+                        double fStop = PhotographicConversions.apertureToFStop(aperture);
+                        res = fStop;
+                    } else {
+                        // convert to a double
+                        double d = ((Rational) src).doubleValue();
+                        res = d;
+                    }
+                } else if (clazz.equals(Integer.class)) {
+                    if (propType != PropertyType.INTEGER)
+                        throw new MapperException("Tag value has type Integer and expected CMIS Integer, but found: " + propType + " for tag: " + tag);
+                    // convert to a long
+                    long l = ((Integer) src).longValue();
+                    res = l;                                        
+                } else if (clazz.equals(String.class)) {
+                    if (propType != PropertyType.STRING && propType != PropertyType.ID && propType != PropertyType.URI &&
+                            propType != PropertyType.HTML && propType != PropertyType.DATETIME)
+                        throw new MapperException("Tag value has type String and expected CMIS String, but found: " + propType + " for tag: " + tag);
+                    // convert to a String
+                    if (propType == PropertyType.DATETIME) {
+                        // parse format: 2012:02:25 16:23:16
+                        DateFormat formatter = new SimpleDateFormat(dateFormat);
+                        GregorianCalendar cal;
+                        try {
+                            Date date = (Date)formatter.parse((String) src);
+                            // convert date to GreogorianCalendar as CMIS expects
+                            cal = new GregorianCalendar();
+                            cal.setTime(date);
+                        } catch (ParseException e) {
+                            LOG.error(e.toString(), e);
+                            throw new MapperException("Unrecognized date format in EXIF date tag: " + src + " for tag: " + tag + " expected: yyyy:MM:dd HH:mm:ss");
+                        }
+                        res = cal;                     
+                    } else {
+                        String s = ((String) src);
+                        res = s;
+                    }
+                } else if (clazz.equals(Date.class)) {
+                    if (propType != PropertyType.DATETIME)
+                        throw new MapperException("Tag value has type Date and expected CMIS DateTime, but found: " + propType + " for tag: " + tag);
+                    // convert to a String
+                    Date date = ((Date) src);
+                    // convert date to GreogorianCalendar as CMIS expects
+                    GregorianCalendar  cal= new GregorianCalendar();
+                    cal.setTime(date);
+                    res = cal;                                        
+                } else if (clazz.equals(Boolean.class)) {
+                    if (propType != PropertyType.BOOLEAN)
+                        throw new MapperException("Tag value has type Boolean and expected CMIS Boolean, but found: " + propType + " for tag: " + tag);
+                    // convert to a String
+                    Boolean b = ((Boolean) src);
+                    res = b;                                        
+                } else {
+                    LOG.debug("Tag value has unsupported type: " + clazz.getName() + " for EXIF tag: " + tag);
+                    // throw new MapperException("Tag value has unsupported type: " + clazz.getName() + " for tag: " + tag);
+                }                
+            }            
+        } else if (JpegDirectory.class.equals(dir.getClass())) {
+            // is there a property mapped to this tag?
+            String propId = propMapJpeg.get(hexStr);
+            LOG.debug("Found JPEG tag '" + tag + "\', property mapped is: " + propId);
+
+            if (null == propId) {
+                LOG.info("Ignoring JPEG tag '" + tag + "\' no property mapped to this tag.");
+            } else if (propType == null) {
+                // should not happen and is a configuration error: we have a property id but no type
+                LOG.error("Ignoring JPEG tag '" + tag + "\' no property type mapped to this tag.");
+            } else {
+                Object src = dir.getObject(tag.getTagType());        
+                Class<?> clazz = src.getClass();
+
+                if (clazz.equals(Integer.class)) {
+                    if (propType != PropertyType.INTEGER)
+                        throw new MapperException("Tag value has type Integer and expected CMIS Integer, but found: " + propType + " for tag: " + tag);
+                    // convert to a long
+                    long l = ((Integer) src).longValue();
+                    res = l;                                        
+                } else {
+                    LOG.debug("Tag value has unsupported type: " + clazz.getName() + " for JPEG tag: " + tag);
+                }
+            }            
+        }
+            
+        return res;        
+    }
+    
+    private static Object convertGps(Tag tag, Directory dir, boolean mustInvert) {
+        Double res = null; 
+        Object src = dir.getObject(tag.getTagType());
+        
+        Class<?> stringArrayClass = src.getClass();
+        Class<?> stringArrayComponentType = stringArrayClass.getComponentType();
+        if (!stringArrayClass.isArray() || null == stringArrayComponentType || Array.getLength(src) != 3) 
+            throw new MapperException("GPS coordinate \"" + tag + "\" has unknown type.");
+        if (!stringArrayComponentType.equals(Rational.class))
+            throw new MapperException("GPS coordinate \"" + tag + "\" has unknown component type (expected Rational, found: " + 
+                    stringArrayComponentType.getName() + ")");
+        // do conversion
+        Rational[] components;
+        components = (Rational[]) src;
+        int deg = components[0].intValue();
+        double min = components[1].doubleValue();
+        double sec = components[2].doubleValue();
+        Double d = (deg + min / 60 + sec / 3600);
+        if (d > 0.0 && mustInvert)
+            d = -d;
+        res = d;
+        return res;
+    }
+}