001/* 002 * (C) Copyright 2009 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Thomas Roger 016 */ 017 018package org.nuxeo.ecm.platform.importer.factories; 019 020import java.io.Serializable; 021import java.util.Map; 022 023import org.apache.commons.logging.Log; 024import org.apache.commons.logging.LogFactory; 025import org.nuxeo.common.utils.IdUtils; 026import org.nuxeo.ecm.core.api.CoreSession; 027import org.nuxeo.ecm.core.api.DocumentModel; 028import org.nuxeo.ecm.core.api.PropertyException; 029import org.nuxeo.ecm.core.api.impl.DocumentModelImpl; 030import org.nuxeo.ecm.core.api.model.PropertyNotFoundException; 031import org.nuxeo.ecm.core.api.pathsegment.PathSegmentService; 032import org.nuxeo.ecm.platform.importer.source.SourceNode; 033import org.nuxeo.runtime.api.Framework; 034 035/** 036 * Base class for classes implementing {@code ImporterDocumentModelFactory}. Contains common methods. 037 * 038 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a> 039 */ 040public abstract class AbstractDocumentModelFactory implements ImporterDocumentModelFactory { 041 042 private static final Log log = LogFactory.getLog(AbstractDocumentModelFactory.class); 043 044 /** 045 * By default there is no process bound to a folderish node creation error, and the global import task will 046 * continue. 047 * <p> 048 * You should override this method if you want a specific process to be executed after such an error and/or if you 049 * want the global import task to stop immediately after the error occurs, in which case the method should return 050 * false. 051 * </p> 052 */ 053 @Override 054 public boolean processFolderishNodeCreationError(CoreSession session, DocumentModel parent, SourceNode node) { 055 log.info(String.format("Nothing to process after error while trying to create the folderish node %s.", 056 node.getSourcePath())); 057 log.info("Global import task will continue."); 058 return true; 059 } 060 061 /** 062 * By default there is no process bound to a leaf node creation error, and the global import task will continue. 063 * <p> 064 * You should override this method if you want a specific process to be executed after such an error and/or if you 065 * want the global import task to stop immediately after the error occurs, in which case the method should return 066 * false. 067 * </p> 068 */ 069 @Override 070 public boolean processLeafNodeCreationError(CoreSession session, DocumentModel parent, SourceNode node) { 071 log.info(String.format("Nothing to process after error while trying to create the leaf node %s.", 072 node.getSourcePath())); 073 log.info("Global import task will continue."); 074 return true; 075 } 076 077 /* 078 * (non-Javadoc) 079 * @see org.nuxeo.ecm.platform.importer.base.ImporterDocumentModelFactory# isTargetDocumentModelFolderish 080 * (org.nuxeo.ecm.platform.importer.base.SourceNode) 081 */ 082 public boolean isTargetDocumentModelFolderish(SourceNode node) { 083 return node.isFolderish(); 084 } 085 086 protected final FilenameNormalizer filenameNormalizer = "true".equals(Framework.getProperty("nuxeo.importer.compatFilenames")) ? new CompatFilenameNormalizer() 087 : new DefaultFilenameNormalizer(); 088 089 protected interface FilenameNormalizer { 090 String normalize(String name); 091 } 092 093 protected static class CompatFilenameNormalizer implements FilenameNormalizer { 094 095 @Override 096 public String normalize(String name) { 097 name = IdUtils.generateId(name, "-", true, 100); 098 name = name.replace("'", ""); 099 name = name.replace("(", ""); 100 name = name.replace(")", ""); 101 name = name.replace("+", ""); 102 return name; 103 } 104 105 } 106 107 protected static class DefaultFilenameNormalizer implements FilenameNormalizer { 108 109 @Override 110 public String normalize(String name) { 111 DocumentModel fake = new DocumentModelImpl("/", name, "File"); 112 return Framework.getLocalService(PathSegmentService.class).generatePathSegment(fake); 113 } 114 } 115 116 /** 117 * Returns a valid Nuxeo name from the given {@code fileName}. 118 * 119 * @throws PropertyException 120 */ 121 protected String getValidNameFromFileName(String fileName) { 122 return filenameNormalizer.normalize(fileName); 123 } 124 125 /** 126 * Set all the properties to the given {@code doc}. The key is field xpath, the value is the value to set on the 127 * document. 128 */ 129 protected DocumentModel setDocumentProperties(CoreSession session, Map<String, Serializable> properties, 130 DocumentModel doc) { 131 if (properties != null) { 132 133 for (Map.Entry<String, Serializable> entry : properties.entrySet()) { 134 try { 135 doc.setPropertyValue(entry.getKey(), entry.getValue()); 136 } catch (PropertyNotFoundException e) { 137 String message = String.format("Property '%s' not found on document type: %s. Skipping it.", 138 entry.getKey(), doc.getType()); 139 log.debug(message); 140 } 141 } 142 doc = session.saveDocument(doc); 143 } 144 return doc; 145 } 146 147}