001/* 002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others. 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-2.1.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 * Nuxeo - initial API and implementation 016 * Thibaud Arguillere (Nuxeo) 017 * 018 * $Id$ 019 */ 020 021package org.nuxeo.ecm.platform.importer.factories; 022 023import java.io.IOException; 024import java.io.Serializable; 025import java.util.Collections; 026import java.util.HashMap; 027import java.util.List; 028import java.util.Map; 029 030import org.apache.commons.lang.StringUtils; 031import org.nuxeo.ecm.core.api.CoreSession; 032import org.nuxeo.ecm.core.api.DocumentModel; 033import org.nuxeo.ecm.core.api.blobholder.BlobHolder; 034import org.nuxeo.ecm.platform.importer.source.SourceNode; 035 036/** 037 * Default implementation for DocumentModel factory The default empty constructor create Folder for folderish file and 038 * File for other. But you can specify them using the other constructor. Also, if you are using .properties files to 039 * setup metada, you can use the ecm:primaryType xpath to specify the type of document to create. This will override the 040 * default ones, and works for files and folders. If no .properties file is provided of it the current node has a 041 * .properties file but no ecm:primaryType, the default types are created. This works for leafType but also for 042 * folderish type. 043 * 044 * @author Thierry Delprat 045 * @author Daniel Tellez 046 * @author Thibaud Arguillere 047 */ 048public class DefaultDocumentModelFactory extends AbstractDocumentModelFactory { 049 050 public static final String DOCTYPE_KEY_NAME = "ecm:primaryType"; 051 052 public static final String FACETS_KEY_NAME = "ecm:mixinTypes"; 053 054 protected String folderishType; 055 056 protected String leafType; 057 058 /** 059 * Instantiate a DefaultDocumentModelFactory that creates Folder and File 060 */ 061 public DefaultDocumentModelFactory() { 062 this("Folder", "File"); 063 } 064 065 /** 066 * Instantiate a DefaultDocumentModelFactory that creates specified types doc 067 * 068 * @param folderishType the folderish type 069 * @param leafType the other type 070 */ 071 public DefaultDocumentModelFactory(String folderishType, String leafType) { 072 this.folderishType = folderishType; 073 this.leafType = leafType; 074 } 075 076 /* 077 * (non-Javadoc) 078 * @seeorg.nuxeo.ecm.platform.importer.base.ImporterDocumentModelFactory# 079 * createFolderishNode(org.nuxeo.ecm.core.api.CoreSession, org.nuxeo.ecm.core.api.DocumentModel, 080 * org.nuxeo.ecm.platform.importer.base.SourceNode) 081 */ 082 @Override 083 public DocumentModel createFolderishNode(CoreSession session, DocumentModel parent, SourceNode node) 084 throws IOException { 085 086 String name = getValidNameFromFileName(node.getName()); 087 088 BlobHolder bh = node.getBlobHolder(); 089 String folderishTypeToUse = getDocTypeToUse(bh); 090 if (folderishTypeToUse == null) { 091 folderishTypeToUse = folderishType; 092 } 093 List<String> facets = getFacetsToUse(bh); 094 095 DocumentModel doc = session.createDocumentModel(parent.getPathAsString(), name, folderishTypeToUse); 096 for (String facet : facets) { 097 doc.addFacet(facet); 098 } 099 doc.setProperty("dublincore", "title", node.getName()); 100 doc = session.createDocument(doc); 101 102 if (bh != null) { 103 doc = setDocumentProperties(session, bh.getProperties(), doc); 104 } 105 106 return doc; 107 } 108 109 /* 110 * (non-Javadoc) 111 * @seeorg.nuxeo.ecm.platform.importer.base.ImporterDocumentModelFactory# 112 * createLeafNode(org.nuxeo.ecm.core.api.CoreSession, org.nuxeo.ecm.core.api.DocumentModel, 113 * org.nuxeo.ecm.platform.importer.base.SourceNode) 114 */ 115 @Override 116 public DocumentModel createLeafNode(CoreSession session, DocumentModel parent, SourceNode node) throws IOException { 117 return defaultCreateLeafNode(session, parent, node); 118 } 119 120 protected DocumentModel defaultCreateLeafNode(CoreSession session, DocumentModel parent, SourceNode node) 121 throws IOException { 122 123 BlobHolder bh = node.getBlobHolder(); 124 String leafTypeToUse = getDocTypeToUse(bh); 125 if (leafTypeToUse == null) { 126 leafTypeToUse = leafType; 127 } 128 List<String> facets = getFacetsToUse(bh); 129 130 String mimeType = bh.getBlob().getMimeType(); 131 if (mimeType == null) { 132 mimeType = getMimeType(node.getName()); 133 } 134 135 String name = getValidNameFromFileName(node.getName()); 136 String fileName = node.getName(); 137 138 DocumentModel doc = session.createDocumentModel(parent.getPathAsString(), name, leafTypeToUse); 139 for (String facet : facets) { 140 doc.addFacet(facet); 141 } 142 doc.setProperty("dublincore", "title", node.getName()); 143 doc.setProperty("file", "filename", fileName); 144 doc.setProperty("file", "content", bh.getBlob()); 145 146 doc = session.createDocument(doc); 147 148 if (bh != null) { 149 doc = setDocumentProperties(session, bh.getProperties(), doc); 150 } 151 152 return doc; 153 } 154 155 /* 156 * Return null if DOCTYPE_KEY_NAME is not in the properties or has been set to nothing. 157 */ 158 protected String getDocTypeToUse(BlobHolder inBH) { 159 String type = null; 160 161 if (inBH != null) { 162 Map<String, Serializable> props = inBH.getProperties(); 163 if (props != null) { 164 type = (String) props.get(DOCTYPE_KEY_NAME); 165 if (type != null && type.isEmpty()) { 166 type = null; 167 } 168 } 169 } 170 171 return type; 172 } 173 174 protected List<String> getFacetsToUse(BlobHolder inBH) { 175 if (inBH != null) { 176 Map<String, Serializable> props = inBH.getProperties(); 177 if (props != null) { 178 Serializable ob = props.get(FACETS_KEY_NAME); 179 if (ob instanceof String) { 180 String facet = (String) ob; 181 if (StringUtils.isNotBlank(facet)) { 182 return Collections.singletonList(facet); 183 } 184 } else if (ob != null) { 185 return (List<String>) ob; 186 } 187 } 188 } 189 return Collections.emptyList(); 190 } 191 192 /** Modify this to get right mime types depending on the file input */ 193 protected String getMimeType(String name) { 194 // Dummy MimeType detection : plug nuxeo Real MimeType service to 195 // have better results 196 197 if (name == null) { 198 return "application/octet-stream"; 199 /* OpenOffice.org 2.x document types */ 200 } else if (name.endsWith(".odp")) { 201 return "application/vnd.oasis.opendocument.presentation"; 202 } else if (name.endsWith(".otp")) { 203 return "application/vnd.oasis.opendocument.presentation-template"; 204 } else if (name.endsWith(".otg")) { 205 return "application/vnd.oasis.opendocument.graphics-template"; 206 } else if (name.endsWith(".odg")) { 207 return "application/vnd.oasis.opendocument.graphics"; 208 } else if (name.endsWith(".odt")) { 209 return "application/vnd.oasis.opendocument.text"; 210 } else if (name.endsWith(".ott")) { 211 return "application/vnd.oasis.opendocument.text-template"; 212 } else if (name.endsWith(".ods")) { 213 return "application/vnd.oasis.opendocument.spreadsheet"; 214 } else if (name.endsWith(".ots")) { 215 return "application/vnd.oasis.opendocument.spreadsheet-template"; 216 /* Microsoft Office document */ 217 } else if (name.endsWith(".doc")) { 218 return "application/msword"; 219 } else if (name.endsWith(".xls")) { 220 return "application/vnd.ms-excel"; 221 } else if (name.endsWith(".ppt")) { 222 return "application/vnd.ms-powerpoint"; 223 /* Ms Office 2007 */ 224 } else if (name.endsWith(".xlsx")) { 225 return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 226 } else if (name.endsWith(".pptx")) { 227 return "application/vnd.openxmlformats-officedocument.presentationml.presentation"; 228 } else if (name.endsWith(".docx")) { 229 return "application/vnd.openxmlformats-officedocument.wordprocessingml.template"; 230 /* Other */ 231 } else if (name.endsWith(".tar")) { 232 return "application/x-gtar"; 233 } else if (name.endsWith(".gz")) { 234 return "application/x-gtar"; 235 } else if (name.endsWith(".csv")) { 236 return "text/csv"; 237 } else if (name.endsWith(".pdf")) { 238 return "application/pdf"; 239 } else if (name.endsWith(".txt")) { 240 return "text/plain"; 241 } else if (name.endsWith(".html")) { 242 return "text/html"; 243 } else if (name.endsWith(".xml")) { 244 return "text/xml"; 245 } else if (name.endsWith(".png")) { 246 return "image/png"; 247 } else if (name.endsWith(".jpg")) { 248 return "image/jpg"; 249 } else if (name.endsWith(".jpeg")) { 250 return "image/jpeg"; 251 } else if (name.endsWith(".gif")) { 252 return "image/gif"; 253 } else if (name.endsWith(".zip")) { 254 return "application/zip"; 255 } else { 256 return "application/octet-stream"; 257 } 258 } 259 260 public void setFolderishType(String folderishType) { 261 this.folderishType = folderishType; 262 } 263 264 public void setLeafType(String leafType) { 265 this.leafType = leafType; 266 } 267 268}