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.properties; 019 020import java.io.File; 021import java.io.FileOutputStream; 022import java.io.IOException; 023import java.text.DateFormat; 024import java.text.SimpleDateFormat; 025import java.util.ArrayList; 026import java.util.Arrays; 027import java.util.Calendar; 028import java.util.Collections; 029import java.util.List; 030import java.util.Map; 031import java.util.Properties; 032 033import org.apache.commons.logging.Log; 034import org.apache.commons.logging.LogFactory; 035import org.nuxeo.common.utils.StringUtils; 036import org.nuxeo.ecm.core.api.DataModel; 037import org.nuxeo.ecm.core.api.DocumentModel; 038import org.nuxeo.ecm.core.api.NuxeoException; 039import org.nuxeo.ecm.core.api.PropertyException; 040import org.nuxeo.ecm.core.schema.types.primitives.DateType; 041 042/** 043 * Handle properties file creation from a {@code DocumentModel}. 044 * <p> 045 * Only support the types that {@code MetadataCollector} knows. 046 * 047 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a> 048 */ 049public class MetadataFile { 050 051 private static final Log log = LogFactory.getLog(MetadataFile.class); 052 053 protected DocumentModel doc; 054 055 protected Properties metadataProperties = new Properties(); 056 057 /** 058 * Create a {@code MetadataFile} from a {@code DocumentModel}'s schemas. 059 * 060 * @return a new MetadataFile object 061 */ 062 public static MetadataFile createFromDocument(DocumentModel doc) { 063 MetadataFile mdFile = new MetadataFile(doc); 064 mdFile.load(); 065 return mdFile; 066 } 067 068 /** 069 * Create a {@code MetadataFile} from the listed schemas (with all properties) and the listed properties of a 070 * {@code DocumentModel} 071 * 072 * @return a new MetadataFile object 073 */ 074 public static MetadataFile createFromSchemasAndProperties(DocumentModel doc, List<String> allPropertiesSchemas, 075 List<String> properties) { 076 MetadataFile mdFile = new MetadataFile(doc); 077 mdFile.load(allPropertiesSchemas, properties); 078 return mdFile; 079 } 080 081 /** 082 * Create a {@code MetadataFile} from the listed schemas (with all properties) of a {@code DocumentModel} 083 * 084 * @return a new MetadataFile object 085 */ 086 public static MetadataFile createFromSchemas(DocumentModel doc, List<String> allPropertiesSchemas) 087 { 088 return createFromSchemasAndProperties(doc, allPropertiesSchemas, Collections.<String> emptyList()); 089 } 090 091 /** 092 * Create a {@code MetadataFile} from the listed properties of a {@code DocumentModel} 093 * 094 * @return a new MetadataFile object 095 */ 096 public static MetadataFile createFromProperties(DocumentModel doc, List<String> properties) { 097 return createFromSchemasAndProperties(doc, Collections.<String> emptyList(), properties); 098 } 099 100 protected MetadataFile(DocumentModel doc) { 101 this.doc = doc; 102 } 103 104 protected void load(List<String> allPropertiesSchemas, List<String> properties) { 105 if (!metadataProperties.isEmpty()) { 106 return; 107 } 108 109 for (String schema : allPropertiesSchemas) { 110 addAllProperties(schema); 111 } 112 113 for (String property : properties) { 114 try { 115 addProperty(property, doc.getPropertyValue(property)); 116 } catch (PropertyException e) { 117 String message = String.format("Property '%s' not found on document type: %s. Skipping it.", property, 118 doc.getType()); 119 log.debug(message); 120 } 121 } 122 } 123 124 protected void addAllProperties(String schema) { 125 DataModel dm = doc.getDataModel(schema); 126 if (dm != null) { 127 for (Map.Entry<String, Object> entry : dm.getMap().entrySet()) { 128 Object value = entry.getValue(); 129 String propertyKey = entry.getKey(); 130 addProperty(computePropertyKey(propertyKey, schema), value); 131 } 132 } 133 } 134 135 public void addProperty(String propertyKey, Object value) { 136 if (value instanceof String) { 137 metadataProperties.put(propertyKey, value); 138 } else if (value instanceof List) { 139 try { 140 List<String> list = (List<String>) value; 141 if (!list.isEmpty()) { 142 if (list.size() == 1) { 143 list = new ArrayList<String>(list); 144 list.add(""); 145 } 146 metadataProperties.put(propertyKey, StringUtils.join(list, MetadataCollector.LIST_SEPARATOR)); 147 } 148 } catch (ClassCastException e) { 149 // do nothing 150 } 151 } else if (value instanceof String[]) { 152 List<String> list = Arrays.asList((String[]) value); 153 if (!list.isEmpty()) { 154 if (list.size() == 1) { 155 list = new ArrayList<String>(list); 156 list.add(""); 157 } 158 metadataProperties.put(propertyKey, StringUtils.join(list, MetadataCollector.ARRAY_SEPARATOR)); 159 } 160 } else if (value instanceof Calendar) { 161 metadataProperties.put(propertyKey, new DateType().encode(value)); 162 } else if (value instanceof Number) { 163 metadataProperties.put(propertyKey, value.toString()); 164 } 165 } 166 167 protected String computePropertyKey(String propertyKey, String schema) { 168 if (!propertyKey.contains(":")) { 169 propertyKey = schema + ":" + propertyKey; 170 } 171 return propertyKey; 172 } 173 174 protected void load() { 175 for (String schema : doc.getDeclaredSchemas()) { 176 addAllProperties(schema); 177 } 178 } 179 180 /** 181 * Write the properties file to the given {@code file} 182 */ 183 public void writeTo(File file) { 184 FileOutputStream fos = null; 185 try { 186 fos = new FileOutputStream(file); 187 metadataProperties.store(fos, null); 188 } catch (IOException e) { 189 throw new NuxeoException("Unable to write the metadata properties to " + file.getAbsolutePath(), e); 190 } finally { 191 if (fos != null) { 192 try { 193 fos.close(); 194 } catch (IOException e) { 195 // nothing to do... 196 } 197 } 198 } 199 } 200 201}