001/* 002 * (C) Copyright 2006-2008 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 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.platform.importer.properties; 023 024import java.io.File; 025import java.io.FileInputStream; 026import java.io.IOException; 027import java.io.Serializable; 028import java.util.ArrayList; 029import java.util.Collections; 030import java.util.Enumeration; 031import java.util.HashMap; 032import java.util.List; 033import java.util.Map; 034import java.util.Properties; 035import java.util.concurrent.locks.ReentrantReadWriteLock; 036import java.util.regex.Pattern; 037 038import org.apache.commons.io.FilenameUtils; 039import org.apache.commons.lang.StringUtils; 040 041/** 042 * Collects meta-data from a FileSystem and manage inheritence 043 * 044 * @author Thierry Delprat 045 */ 046public class MetadataCollector { 047 048 public static final boolean staticInherit = true; 049 050 public static final boolean useIntrospection = false; 051 052 public static String DATE_FORMAT = "MM/dd/yyyy"; 053 054 public static String LIST_SEPARATOR = "|"; 055 056 public static String REGEXP_LIST_SEPARATOR = "\\|"; 057 058 public static String ARRAY_SEPARATOR = "||"; 059 060 public static String REGEXP_ARRAY_SEPARATOR = "\\|\\|"; 061 062 protected Map<String, Map<String, Serializable>> collectedMetadata = new HashMap<String, Map<String, Serializable>>(); 063 064 protected ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); 065 066 public void addPropertiesFromStrings(String contextPath, Map<String, String> properties) { 067 Map<String, Serializable> collectedProperties = new HashMap<String, Serializable>(); 068 for (String name : properties.keySet()) { 069 Serializable value = parseFromString(name, properties.get(name)); 070 collectedProperties.put(name, value); 071 } 072 addProperties(contextPath, collectedProperties); 073 } 074 075 public void addProperties(String contextPath, Map<String, Serializable> collectedProperties) { 076 try { 077 lock.writeLock().lock(); 078 contextPath = FilenameUtils.normalizeNoEndSeparator(contextPath); 079 if (staticInherit) { 080 File file = new File(contextPath); 081 while (!StringUtils.isEmpty(file.getParent())) { 082 file = file.getParentFile(); 083 Map<String, Serializable> parentProperties = collectedMetadata.get(file.toString()); 084 if (parentProperties != null) { 085 for (String name : parentProperties.keySet()) { 086 if (!collectedProperties.containsKey(name)) { 087 collectedProperties.put(name, parentProperties.get(name)); 088 } 089 } 090 } 091 } 092 } 093 collectedMetadata.put(contextPath, collectedProperties); 094 } finally { 095 lock.writeLock().unlock(); 096 } 097 098 } 099 100 protected static Pattern numPattern = Pattern.compile("([0-9\\,\\.\\+\\-]+)"); 101 102 protected Serializable parseFromString(String name, String value) { 103 104 Serializable prop = value; 105 if (useIntrospection) { 106 throw new UnsupportedOperationException("Introspection mode not available"); 107 } else { 108 if (value.contains(ARRAY_SEPARATOR)) { 109 prop = value.split(REGEXP_ARRAY_SEPARATOR); 110 } else if (value.contains(LIST_SEPARATOR)) { 111 List<Serializable> lstprop = new ArrayList<Serializable>(); 112 String[] parts = value.split(REGEXP_LIST_SEPARATOR); 113 for (String part : parts) { 114 lstprop.add(parseFromString(name, part)); 115 } 116 prop = (Serializable) lstprop; 117 } 118 } 119 return prop; 120 } 121 122 public Serializable getProperty(String contextPath, String name) { 123 124 Map<String, Serializable> props = getProperties(contextPath); 125 if (props != null) { 126 try { 127 lock.readLock().lock(); 128 return props.get(name); 129 } finally { 130 lock.readLock().unlock(); 131 } 132 } else { 133 return null; 134 } 135 } 136 137 public Map<String, Serializable> getProperties(String contextPath) { 138 139 contextPath = FilenameUtils.normalizeNoEndSeparator(contextPath); 140 141 try { 142 lock.readLock().lock(); 143 Map<String, Serializable> props = collectedMetadata.get(contextPath); 144 145 if (props == null) { 146 File file = new File(contextPath); 147 while (props == null && !StringUtils.isEmpty(file.getParent())) { 148 file = file.getParentFile(); 149 props = collectedMetadata.get(file.getPath().toString()); 150 } 151 } 152 153 if (props != null) { 154 props = Collections.unmodifiableMap(props); 155 } 156 return props; 157 } finally { 158 lock.readLock().unlock(); 159 } 160 } 161 162 public void addPropertyFile(File propertyFile) throws IOException { 163 164 Properties mdProperties = new Properties(); 165 mdProperties.load(new FileInputStream(propertyFile)); 166 167 Map<String, String> stringMap = new HashMap<String, String>(); 168 Enumeration names = mdProperties.propertyNames(); 169 while (names.hasMoreElements()) { 170 String name = (String) names.nextElement(); 171 stringMap.put(name, mdProperties.getProperty(name)); 172 } 173 String contextPath = new File(propertyFile.getPath()).getParent(); 174 addPropertiesFromStrings(contextPath, stringMap); 175 } 176 177}