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