All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.main.java.com.eva.properties.Context Maven / Gradle / Ivy

Go to download

Advanced properties with object factories, references and inheritance.

There is a newer version: 0.3
Show newest version
/*
 * $Id: Context.java 41 2007-02-27 21:19:12Z max $
 * 
 * Copyright (c) 2006-2007 Maximilian Antoni. All rights reserved.
 * 
 * This software is licensed as described in the file LICENSE.txt, which you
 * should have received as part of this distribution. The terms are also
 * available at http://www.maxantoni.de/projects/eva-properties/license.txt.
 */
package com.eva.properties;

import java.util.List;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;

/**
 * provides context information while resolving properties.
 * 
 * @author Max Antoni
 * @version $Revision: 41 $
 */
class Context {
    private List currentKeys;
    private Context parent;
    private Properties properties;
    
    /**
     * creates a context with a parent context and properties.
     * 
     * @param inParent the parent context.
     * @param inProperties the properties.
     * @throws NullPointerException if either the parent or the properties are
     *             null.
     */
    Context(Context inParent, Properties inProperties) {
        super();
        if(inParent == null) {
            throw new NullPointerException("Parent context is null.");
        }
        parent = inParent;
        setProperties(inProperties);
    }
    
    /**
     * creates a context with properties. If the provided properties object has
     * a parent properties object, a new context may be created lazily with
     * those parent properties and is then set as the parent of this context.
     * 
     * @param inProperties the properties.
     */
    Context(Properties inProperties) {
        super();
        setProperties(inProperties);
    }
    
    /**
     * returns the parent context for this context.
     * 
     * @return the parent context.
     */
    Context getParent() {
        if(parent == null) {
            Properties p = properties.getParent();
            parent = p == null ? null : new Context(p);
        }
        return parent;
    }
    
    /**
     * 

* checks if the properties framework is in debug mode. This is the case if *

*
    *
  • PropertiesFactory.DEBUG is true, or
  • *
  • Log.INSTANCE.isLoggable(Level.FINE) returns * true.
  • *
*

* In debug mode the context tracks the current resolve path and throws an * exception with that path if a recursive dependency is detected. *

* * @return true if the properties framework is in debug mode, * false otherwise. */ boolean isDebug() { return PropertiesFactory.DEBUG || Log.INSTANCE.isLoggable(Level.FINE); } Class loadClass(String inClassName) { ClassLoader classLoader = (ClassLoader) lookup("classloader"); if(classLoader == null) { classLoader = Thread.currentThread().getContextClassLoader(); } try { return classLoader.loadClass(inClassName); } catch(SecurityException e) { throw new PropertiesException("Cannot load \"" + inClassName + "\": " + e.getMessage()); } catch(ClassNotFoundException e) { throw new PropertiesException("Class \"" + inClassName + "\" not found ."); } } /** * looks up an object for a given key in this context. * * @param inKey the key. * @return the object, if found, null otherwise. * @throws PropertiesException if an error accours while looking for the * object. */ Object lookup(String inKey) throws PropertiesException { if(inKey.startsWith(".")) { if(getParent() == null) { return null; } return parent.lookup(inKey.substring(1)); } if(isDebug()) { /* * See com.eva.properties.RecursionTest: */ if(currentKeys.contains(inKey)) { StringBuffer buffer = new StringBuffer(); buffer.append("Recursive references: "); writePathHelper(buffer); buffer.append(inKey); throw new PropertiesException(buffer.toString()); } currentKeys.add(inKey); try { return lookupHelper(inKey); } finally { currentKeys.remove(currentKeys.size() - 1); } } return lookupHelper(inKey); } /** * lookup a key in the parent chain. This method does not allow * dot-separated key paths. * * @param inKey the key. * @return returns the found object or null. */ Object lookupParentChain(String inKey) { Object value; if(properties instanceof MapProperties) { value = ((MapProperties) properties).getInternal(inKey); } else if(properties instanceof ListProperties) { try { value = ((ListProperties) properties).get(Integer .parseInt(inKey)); } catch(NumberFormatException e) { value = null; } } else { value = null; // NoProperties } if(value == null && getParent() != null) { return parent.lookupParentChain(inKey); } return value; } /** * replaces the content of the given value if it is a replaceable or a * string with references. * * @param inValue the value to be replaced. * @return the replaced value or inValue if there was nothing * to replace. * @throws PropertiesException */ Object replace(Object inValue) throws PropertiesException { if(inValue instanceof Replaceable) { return replaceReplaceable((Replaceable) inValue); } if(inValue instanceof String) { return replaceString((String) inValue); } return inValue; } /** * replaces the given replaceable in this context. * * @param inReplaceable the replaceable. * @return the object. * @throws PropertiesException if the replacement was not successful. */ Object replaceReplaceable(Replaceable inReplaceable) { try { return inReplaceable.replace(this); } catch(PropertiesException e) { throw new PropertiesException("Cannot replace " + inReplaceable.toString() + ", " + e.getMessage(), e); } } /** * replaces the given string in this context. * * @param inString the string. * @return the object. * @throws PropertiesException if the replacement was not successful. */ Object replaceString(String inString) throws PropertiesException { String replaced = Replacer.replace(inString, this); if(replaced == null) { return null; } return ProtocolFactory.forString(this, replaced); } /** * writes the current lookup path to the given buffer. * * @param inoutBuffer */ void writePath(StringBuffer inoutBuffer) { if(getParent() != null) { int length = inoutBuffer.length(); parent.writePath(inoutBuffer); if(length < inoutBuffer.length()) { inoutBuffer.append(" > "); } } writePathHelper(inoutBuffer); } /** * helper method for {@link #lookup(String)}. * * @param inKey the key. * @return the object. */ private Object lookupHelper(String inKey) { Object value = properties.getProperty(this, inKey); if(value == null && getParent() != null) { return parent.lookupHelper(inKey); } return value; } /** * stores the given properties in this context. * * @param inProperties the properties. */ private void setProperties(Properties inProperties) { if(inProperties == null) { throw new NullPointerException("Properties is null."); } properties = inProperties; if(isDebug()) { currentKeys = new ArrayList(); } } /** * helper method for {@link #writePath(StringBuffer)}. * * @param inoutBuffer the buffer. */ private void writePathHelper(StringBuffer inoutBuffer) { for(Iterator i = currentKeys.iterator(); i.hasNext();) { String key = (String) i.next(); inoutBuffer.append(key); inoutBuffer.append(" > "); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy