1 /* 2 * Copyright 2010 - org.tinyjee.maven 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.tinyjee.maven.dim.extensions; 18 19 import org.apache.maven.doxia.logging.Log; 20 import org.codehaus.plexus.util.FileUtils; 21 import org.tinyjee.maven.dim.spi.Globals; 22 import org.tinyjee.maven.dim.utils.AbstractAliasHandler; 23 import org.tinyjee.maven.dim.utils.SelectableArrayList; 24 25 import java.io.File; 26 import java.io.IOException; 27 import java.net.URL; 28 import java.util.LinkedHashMap; 29 import java.util.Map; 30 import java.util.Properties; 31 import java.util.TreeSet; 32 33 import static org.tinyjee.maven.dim.spi.ResourceResolver.findSource; 34 35 /** 36 * PropertiesLoader is a 'source-class' compatible helper class that can load a properties file 37 * and add or overwrite the request properties by the properties contained in the file. 38 * <p/> 39 * <p/> 40 * <b>Usage:</b><div><code> 41 * %{include|source=template.vm|source-class=org.tinyjee.maven.dim.extensions.PropertiesLoader|properties=props.(xml|properties)} 42 * </code></div> 43 * or when using the alias:<div><code> 44 * %{include|source=template.vm|source-properties=props.(xml|properties)} 45 * </code></div> 46 * 47 * @author Juergen_Kellerer, 2010-09-08 48 * @version 1.0 49 */ 50 public class PropertiesLoader extends LinkedHashMap<String, Object> { 51 52 private static final long serialVersionUID = 7451224247313497738L; 53 54 /** 55 * Implements the "{@link PropertiesLoader#PARAM_ALIAS}" alias functionality. 56 */ 57 public static class AliasHandler extends AbstractAliasHandler { 58 /** 59 * Constructs the handler (Note: Is called by 60 * {@link org.tinyjee.maven.dim.spi.RequestParameterTransformer#TRANSFORMERS}). 61 */ 62 public AliasHandler() { 63 super(PARAM_ALIAS, PARAM_PROPERTIES, PropertiesLoader.class.getName()); 64 } 65 } 66 67 /** 68 * Defines a shortcut for the request properties '{@code source-class}' and '{@code properties}'. 69 * <p/> 70 * If this parameter is present inside the request parameters list, the system 71 * will effectively behave as if 'source-class' and 'properties' where set 72 * separately. 73 */ 74 public static final String PARAM_ALIAS = "source-properties"; 75 76 /** 77 * Sets the path to the properties file to load inside the request parameters. 78 * <p/> 79 * The specified file is retrieved in exactly the same way as if the "{@code source}" 80 * parameter would have been used (see Macro reference). 81 * <p/> 82 * <i>Note:</i> Properties can use the traditional {@code .properties} or 83 * the newer {@code .xml} format. Format selection is performed by file extension. 84 */ 85 public static final String PARAM_PROPERTIES = "properties"; 86 87 /** 88 * Is filled with the loaded {@link Properties} instance. 89 * <p/> 90 * Note: All loaded properties are exposed in the standard scope as request properties and are accessible 91 * like any other parameters specified with the macro call. 92 * <br/> 93 * This additional map based access allows to query properties whose names are not compatible with the variable naming 94 * scheme and it also allows to iterate all loaded properties using {@code $loadedProperties.entrySet()}. 95 */ 96 public static final String OUT_PARAM_LOADED_PROPERTIES = "loadedProperties"; 97 98 /** 99 * Is filled with a sorted, regex-enabled list of property keys (= 100 * <code>new {@link SelectableArrayList}<String>(new TreeSet<String>(properties.keySet()));</code>). 101 */ 102 public static final String OUT_PARAM_LOADED_PROPERTY_KEYS = "loadedPropertyKeys"; 103 104 /** 105 * Constructs a new properties loader searching for properties using the given base path. 106 * 107 * @param baseDir the base dir to of the maven module. 108 * @param requestParams the request params of the macro call. 109 */ 110 @SuppressWarnings("unchecked") 111 public PropertiesLoader(File baseDir, Map<String, Object> requestParams) { 112 final Log log = Globals.getLog(); 113 final boolean debug = log.isDebugEnabled(); 114 115 putAll(requestParams); 116 117 URL propertiesURL = findSource(baseDir, (String) requestParams.get(PARAM_PROPERTIES)); 118 try { 119 Properties properties = new Properties(); 120 boolean isXml = "xml".equalsIgnoreCase(FileUtils.extension(propertiesURL.getFile())); 121 if (debug) log.debug("About to load properties from '" + propertiesURL + "'. Used format: " + (isXml ? "xml" : "properties")); 122 if (isXml) 123 properties.loadFromXML(propertiesURL.openStream()); 124 else 125 properties.load(propertiesURL.openStream()); 126 127 put(OUT_PARAM_LOADED_PROPERTIES, properties); 128 SelectableArrayList sortedKeys = new SelectableArrayList(new TreeSet(properties.keySet())); 129 put(OUT_PARAM_LOADED_PROPERTY_KEYS, sortedKeys); 130 131 if (debug) log.debug("Loaded properties:"); 132 for (Object key : sortedKeys) { 133 String propertyKey = key.toString(), propertyValue = properties.getProperty(propertyKey); 134 put(propertyKey, propertyValue); 135 if (debug) log.debug(propertyKey + "=" + propertyValue); 136 } 137 } catch (IOException e) { 138 throw new RuntimeException(e); 139 } 140 } 141 }