blob: 53a9097e855b8ccf43ce0b1ffb9c20e00d931f90 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.forrest.conf;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedSet;
import java.util.StringTokenizer;
import java.util.TreeSet;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.components.modules.input.DefaultsModule;
import org.apache.cocoon.components.modules.input.InputModule;
import org.apache.commons.lang.SystemUtils;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceNotFoundException;
import org.apache.excalibur.source.SourceResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* Input module for accessing the base properties used in Forrest. The main
* values are the locations of the <b>source </b> directories and of the
* <b>forrest </b> directories. The values are gotten using the ForrestConfUtils
* class.
*/
public class ForrestConfModule extends DefaultsModule implements InputModule,
Initializable, ThreadSafe, Serviceable {
private AntProperties filteringProperties;
private String forrestHome, projectHome, contextHome;
private SourceResolver m_resolver;
public Object getAttribute(String name, Configuration modeConf,
Map objectModel) throws ConfigurationException {
String original;
String attributeValue;
try {
original = super.getAttributeValues(name, modeConf, objectModel)[0]
.toString();
attributeValue = this.getAttributeValues(name, modeConf,
objectModel)[0].toString();
} catch (NullPointerException npe) {
original = "(not defined in forrest.xconf)";
attributeValue = filteringProperties.getProperty(name);
if (attributeValue == null) {
String error = "Unable to get attribute value for "
+ name
+ "\n"
+ "Please make sure you defined "
+ name
+ " in either forrest.properties.xml in $PROJECT_HOME "
+ "or in the default.forrest.properties.xml of the plugin "
+ "that is requesting this property."
+ "\n"
+ "If you see this message, then most of the time you have spotted a plugin bug "
+ "(i.e. forgot to define the plugin's default property). Please report to our mailing list.";
throw new ConfigurationException(error);
}
}
if (debugging()) {
debug(" - Requested:" + name);
debug(" - Unfiltered:" + original);
debug(" - Given:" + attributeValue);
}
return attributeValue;
}
public Object[] getAttributeValues(String name, Configuration modeConf,
Map objectModel) throws ConfigurationException {
Object[] attributeValues = super.getAttributeValues(name, modeConf,
objectModel);
for (int i = 0; i < attributeValues.length; i++) {
if (null != attributeValues[i])
attributeValues[i] = filteringProperties
.filter(attributeValues[i].toString());
else
attributeValues[i] = filteringProperties
.filter(filteringProperties.getProperty(name));
}
return attributeValues;
}
public Iterator getAttributeNames(Configuration modeConf, Map objectModel)
throws ConfigurationException {
SortedSet matchset = new TreeSet();
Enumeration enumeration = filteringProperties.keys();
while (enumeration.hasMoreElements()) {
String key = (String) enumeration.nextElement();
matchset.add(key);
}
Iterator iterator = super.getAttributeNames(modeConf, objectModel);
while (iterator.hasNext())
matchset.add(iterator.next());
return matchset.iterator();
}
public void initialize() throws Exception {
// add all homes important to forrest to the properties
setHomes();
loadSystemProperties(filteringProperties);
// NOTE: the first values set get precedence, as in AntProperties
String forrestPropertiesStringURI;
try {
// get forrest.properties and load the values
forrestPropertiesStringURI = projectHome
+ SystemUtils.FILE_SEPARATOR + "forrest.properties";
filteringProperties = loadAntPropertiesFromURI(filteringProperties,
forrestPropertiesStringURI);
// get the values from local.forrest.properties.xml
forrestPropertiesStringURI = projectHome
+ SystemUtils.FILE_SEPARATOR
+ "local.forrest.properties.xml";
filteringProperties = loadXMLPropertiesFromURI(filteringProperties,
forrestPropertiesStringURI);
// get the values from project forrest.properties.xml
forrestPropertiesStringURI = projectHome
+ SystemUtils.FILE_SEPARATOR + "forrest.properties.xml";
filteringProperties = loadXMLPropertiesFromURI(filteringProperties,
forrestPropertiesStringURI);
// get the values from user forrest.properties.xml
String userHome = filteringProperties.getProperty("user.home");
if (userHome != null) {
forrestPropertiesStringURI = userHome
+ SystemUtils.FILE_SEPARATOR + "forrest.properties.xml";
filteringProperties = loadXMLPropertiesFromURI(
filteringProperties, forrestPropertiesStringURI);
}
// get the values from global forrest.properties.xml
String globalHome = filteringProperties.getProperty("global.home");
if (globalHome != null) {
forrestPropertiesStringURI = globalHome
+ SystemUtils.FILE_SEPARATOR + "forrest.properties.xml";
filteringProperties = loadXMLPropertiesFromURI(
filteringProperties, forrestPropertiesStringURI);
}
// get the values from default.forrest.properties.xml
forrestPropertiesStringURI = contextHome
+ SystemUtils.FILE_SEPARATOR
+ "default.forrest.properties.xml";
filteringProperties = loadXMLPropertiesFromURI(filteringProperties,
forrestPropertiesStringURI);
// Load plugin default properties
String strPluginList = filteringProperties
.getProperty("project.required.plugins");
if (strPluginList != null) {
StringTokenizer st = new StringTokenizer(strPluginList, ",");
while (st.hasMoreTokens()) {
forrestPropertiesStringURI = ForrestConfUtils
.getPluginDir(st.nextToken().trim());
forrestPropertiesStringURI = forrestPropertiesStringURI
+ SystemUtils.FILE_SEPARATOR
+ "default.plugin.properties.xml";
filteringProperties = loadXMLPropertiesFromURI(
filteringProperties, forrestPropertiesStringURI);
}
}
// get default-forrest.properties and load the values
String defaultForrestPropertiesStringURI = contextHome
+ SystemUtils.FILE_SEPARATOR + "default-forrest.properties";
filteringProperties = loadAntPropertiesFromURI(filteringProperties,
defaultForrestPropertiesStringURI);
} finally {
ForrestConfUtils.aliasSkinProperties(filteringProperties);
if (debugging())
debug("Loaded project properties:" + filteringProperties);
}
}
/**
* Sets all forrest related home locations such as - forrestHome -
* projectHome - contextHome
*
* @throws Exception
*/
private void setHomes() throws Exception {
forrestHome = ForrestConfUtils.getForrestHome();
projectHome = ForrestConfUtils.getProjectHome();
contextHome = ForrestConfUtils.getContextHome();
filteringProperties = new AntProperties();
filteringProperties.setProperty("forrest.home", forrestHome);
filteringProperties.setProperty("project.home", projectHome);
filteringProperties.setProperty("context.home", contextHome);
}
/**
* Load system properties
*/
private void loadSystemProperties(AntProperties props) {
for (Enumeration e = System.getProperties().propertyNames(); e
.hasMoreElements();) {
String propName = (String) e.nextElement();
if (propName.startsWith("forrest.")
|| propName.startsWith("project.")
|| propName.endsWith(".home")) {
String systemPropValue = System.getProperty(propName);
if (systemPropValue != null) {
props.setProperty(propName, systemPropValue);
}
}
}
}
/**
* @param antPropertiesStringURI
* @throws MalformedURLException
* @throws IOException
* @throws SourceNotFoundException
*/
private AntProperties loadAntPropertiesFromURI(
AntProperties precedingProperties, String antPropertiesStringURI)
throws MalformedURLException, IOException, SourceNotFoundException {
Source source = null;
InputStream in = null;
try {
source = m_resolver.resolveURI(antPropertiesStringURI);
if (debugging())
debug("Searching for forrest.properties in" + source.getURI());
if (source.exists()) {
in = source.getInputStream();
filteringProperties = new AntProperties(precedingProperties);
filteringProperties.load(in);
if (debugging())
debug("Loaded:" + antPropertiesStringURI
+ filteringProperties.toString());
}
} finally {
if (source != null) {
m_resolver.release(source);
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
return filteringProperties;
}
/**
* @param propertiesStringURI
* @throws IOException
* @throws MalformedURLException
* @throws MalformedURLException
* @throws IOException
* @throws ParserConfigurationException
* @throws SAXException
* @throws SourceNotFoundException
*/
private AntProperties loadXMLPropertiesFromURI(
AntProperties precedingProperties, String propertiesStringURI)
throws MalformedURLException, IOException,
ParserConfigurationException, SAXException {
Source source = null;
InputStream in = null;
try {
source = m_resolver.resolveURI(propertiesStringURI);
if (debugging())
debug("Searching for forrest.properties.xml in "
+ source.getURI());
if (source.exists()) {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(source.getURI());
NodeList nl = document.getElementsByTagName("property");
if (nl != null && nl.getLength() > 0) {
for (int i = 0; i < nl.getLength(); i++) {
Element el = (Element) nl.item(i);
filteringProperties.setProperty(
el.getAttribute("name"), el
.getAttribute("value"));
}
}
if (debugging())
debug("Loaded:" + propertiesStringURI
+ filteringProperties.toString());
} else if (debugging())
debug("Unable to find " + source.getURI() + ", ignoring.");
} finally {
if (source != null) {
m_resolver.release(source);
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
return filteringProperties;
}
public void service(ServiceManager manager) throws ServiceException {
m_resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
}
/**
* Rocked science
*/
private final boolean debugging() {
return getLogger().isDebugEnabled();
}
/**
* Rocked science
*
* @param debugString
*/
private final void debug(String debugString) {
getLogger().debug(debugString);
}
}