/* * Copyright (C) 2003-2007 eXo Platform SAS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see. */ package org.exoplatform.container.configuration; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.servlet.ServletContext; import org.exoplatform.container.xml.Component; import org.exoplatform.container.xml.Configuration; /** * Jul 19, 2004 * * @author: Tuan Nguyen * @email: tuan08@users.sourceforge.net * @version: $Id: ConfigurationServiceImpl.java,v 1.8 2004/10/30 02:29:51 tuan08 * Exp $ */ public class ConfigurationManagerImpl implements ConfigurationManager { final static public String WAR_CONF_LOCATION = "/WEB-INF"; final static public String LOG_DEBUG_PROPERTY = "org.exoplatform.container.configuration.debug"; final static public boolean LOG_DEBUG = System.getProperty(LOG_DEBUG_PROPERTY) != null; protected Configuration configurations_; private ServletContext scontext_; private ClassLoader scontextClassLoader_; private String contextPath = null; private boolean validateSchema = true; /** The URL of the current document being unmarshalled. */ private static final ThreadLocal currentURL = new ThreadLocal(); /** * Returns the URL of the current document being unmarshalled or null. * @return the URL */ public static URL getCurrentURL() { return currentURL.get(); } public ConfigurationManagerImpl() { } public ConfigurationManagerImpl(ServletContext context) { scontext_ = context; } public ConfigurationManagerImpl(ClassLoader loader) { scontextClassLoader_ = loader; } public Configuration getConfiguration() { return configurations_; } public void addConfiguration(String url) throws Exception { if (url == null) return; addConfiguration(getURL(url)); } public void addConfiguration(Collection urls) throws Exception { Iterator i = urls.iterator(); while (i.hasNext()) { URL url = (URL) i.next(); addConfiguration(url); } } public void addConfiguration(URL url) throws Exception { if (LOG_DEBUG) System.out.println("Add configuration " + url); if (url == null) return; try { contextPath = (new File(url.toString())).getParent() + "/"; contextPath = contextPath.replaceAll("\\\\", "/"); } catch (Exception e) { contextPath = null; } // Just to prevent some nasty bug to happen if (currentURL.get() != null) { throw new IllegalStateException("Would not expect that"); } else { currentURL.set(url); } // try { ConfigurationUnmarshaller unmarshaller = new ConfigurationUnmarshaller(); Configuration conf = unmarshaller.unmarshall(url); if (configurations_ == null) configurations_ = conf; else configurations_.mergeConfiguration(conf); List urls = conf.getImports(); if (urls != null) { for (int i = 0; i < urls.size(); i++) { String uri = (String) urls.get(i); URL urlObject = getURL(uri); if (urlObject != null) { conf = unmarshaller.unmarshall(urlObject); configurations_.mergeConfiguration(conf); if (LOG_DEBUG) System.out.println("\timport " + urlObject); } else { System.err.println("WARNING: Couldn't process the URL for " + uri + " configuration file ignored "); } } } } catch (Exception ex) { // System .err.println("Error: " + ex.getMessage()); System.err.println("ERROR: cannot process the configuration " + url); ex.printStackTrace(); } finally { currentURL.set(null); } } public void processRemoveConfiguration() { if (configurations_ == null) return; List list = configurations_.getRemoveConfiguration(); if (list != null) { for (int i = 0; i < list.size(); i++) { String type = (String) list.get(i); configurations_.removeConfiguration(type); } } } public Component getComponent(String service) { return configurations_.getComponent(service); } public Component getComponent(Class clazz) throws Exception { return configurations_.getComponent(clazz.getName()); } public Collection getComponents() { if (configurations_ == null) return null; return configurations_.getComponents(); } public boolean isValidateSchema() { return validateSchema; } public void setValidateSchema(boolean validateSchema) { this.validateSchema = validateSchema; } public URL getResource(String url, String defaultURL) throws Exception { return null; } public URL getResource(String uri) throws Exception { return getURL(uri); } public InputStream getInputStream(String url, String defaultURL) throws Exception { if (url == null) url = defaultURL; return getInputStream(url); } public InputStream getInputStream(String uri) throws Exception { URL url = getURL(uri); if (url == null) { throw new IOException("Resource (" + uri + ") could not be found or the invoker doesn't have adequate privileges to get the resource"); } return url.openStream(); } public URL getURL(String url) throws Exception { if (url.startsWith("jar:")) { String path = removePrefix("jar:/", url); ClassLoader cl = Thread.currentThread().getContextClassLoader(); return cl.getResource(path); } else if (url.startsWith("classpath:")) { String path = removePrefix("classpath:/", url); ClassLoader cl = Thread.currentThread().getContextClassLoader(); return cl.getResource(path); } else if (url.startsWith("war:")) { String path = removePrefix("war:", url); if (scontext_ != null) { return scontext_.getResource(WAR_CONF_LOCATION + path); } if (scontextClassLoader_ != null) { return scontextClassLoader_.getResource(path); } throw new Exception("unsupport war uri in this configuration service"); } else if (url.startsWith("file:")) { url = resolveSystemProperties(url); return new URL(url); } else if (url.indexOf(":") < 0 && contextPath != null) { return new URL(contextPath + url); } return null; } /** * * @param input the input * @return the resolved input */ public static String resolveSystemProperties(String input) { final int NORMAL = 0; final int SEEN_DOLLAR = 1; final int IN_BRACKET = 2; if (input == null) return input; char[] chars = input.toCharArray(); StringBuffer buffer = new StringBuffer(); boolean properties = false; int state = NORMAL; int start = 0; for (int i = 0; i < chars.length; ++i) { char c = chars[i]; if (c == '$' && state != IN_BRACKET) state = SEEN_DOLLAR; else if (c == '{' && state == SEEN_DOLLAR) { buffer.append(input.substring(start, i - 1)); state = IN_BRACKET; start = i - 1; } else if (state == SEEN_DOLLAR) state = NORMAL; else if (c == '}' && state == IN_BRACKET) { if (start + 2 == i) { buffer.append("${}"); } else { String value = null; String key = input.substring(start + 2, i); value = System.getProperty(key); if (value != null) { properties = true; buffer.append(value); } } start = i + 1; state = NORMAL; } } if (properties == false) return input; if (start != chars.length) buffer.append(input.substring(start, chars.length)); return buffer.toString(); } public boolean isDefault(String value) { return value == null || value.length() == 0 || "default".equals(value); } protected String removePrefix(String prefix, String url) { return url.substring(prefix.length(), url.length()); } }