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