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

com.eva.properties.ListProperties Maven / Gradle / Ivy

/*
 * $Id: ListProperties.java 109 2007-03-24 14:55:03Z 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.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

/**
 * is a list based properties implementation. Keys addressing a value must be
 * numbers.
 * 
 * @author Max Antoni
 * @version $Revision: 109 $
 */
public class ListProperties extends Properties implements List {
    
    /**
     * internal list iterator implementation.
     */
    private class ListPropertiesIterator implements ListIterator {
        private int index;
        
        /**
         * standard constructor.
         */
        ListPropertiesIterator() {
            super();
        }
        
        /**
         * standard constructor with an index.
         * 
         * @param inIndex the index.
         */
        ListPropertiesIterator(int inIndex) {
            super();
            index = inIndex;
        }
        
        /* 
         * @see java.util.ListIterator#add(java.lang.Object)
         */
        public void add(Object inValue) {
            ListProperties.this.add(inValue);
        }

        /* 
         * @see java.util.ListIterator#hasNext()
         */
        public boolean hasNext() {
            return index < ListProperties.this.size();
        }

        /* 
         * @see java.util.ListIterator#hasPrevious()
         */
        public boolean hasPrevious() {
            return index > 0;
        }

        /* 
         * @see java.util.ListIterator#next()
         */
        public Object next() {
            return ListProperties.this.get(index++);
        }

        /* 
         * @see java.util.ListIterator#nextIndex()
         */
        public int nextIndex() {
            return index;
        }

        /* 
         * @see java.util.ListIterator#previous()
         */
        public Object previous() {
            return ListProperties.this.get(--index);
        }

        /* 
         * @see java.util.ListIterator#previousIndex()
         */
        public int previousIndex() {
            return index - 1;
        }

        /* 
         * @see java.util.ListIterator#remove()
         */
        public void remove() {
            ListProperties.this.remove(--index);
        }

        /* 
         * @see java.util.ListIterator#set(java.lang.Object)
         */
        public void set(Object inValue) {
            ListProperties.this.set(index, inValue);
        }
        
    }
    
    private List list = new ArrayList();
    
    /**
     * Creates an empty list properties object with no parent.
     */
    public ListProperties() {
        // Empty default constructor.
    }
    
    public ListProperties(String inPath) throws PropertiesException,
            FileNotFoundException {
        if(inPath == null) {
            throw new NullPointerException("Path is null.");
        }
        PropertiesParser.readList(this, new DataSource(inPath));
    }
    
    public ListProperties(ClassLoader inClassLoader, String inPath)
            throws PropertiesException, FileNotFoundException {
        if(inClassLoader == null) {
            throw new NullPointerException("ClassLoader is null.");
        }
        if(inPath == null) {
            throw new NullPointerException("Path is null.");
        }
        PropertiesParser.readList(this, new DataSource(inClassLoader, inPath));
    }
    
    /**
     * creates a list properties object and initializes it with the the
     * configuration provided by the data source.
     * 
     * @param inDataSource the data source providing the configuration.
     * @throws PropertiesException
     */
    public ListProperties(DataSource inDataSource) throws PropertiesException {
        if(inDataSource == null) {
            throw new NullPointerException("DataSource is null.");
        }
        PropertiesParser.readList(this, inDataSource);
    }
    
    /**
     * creates a list properties object and initializes it with the the
     * configuration provided by the input stream.
     * 
     * @param inStream the input stream providing the configuration.
     * @throws PropertiesException
     */
    public ListProperties(InputStream inStream) throws PropertiesException {
        if(inStream == null) {
            throw new NullPointerException("Stream is null.");
        }
        PropertiesParser.readList(this, new InputStreamReader(inStream));
    }
    
    /**
     * creates a list properties object and uses the given list as its parent if
     * it is a properties list. Otherwise the list elements will be copied to
     * the new list properties.
     * 
     * @param inList the list.
     */
    public ListProperties(List inList) {
        super();
        if(inList == null) {
            throw new NullPointerException("List is null.");
        }
        if(inList instanceof Properties) {
            setParent((Properties) inList);
        }
        else {
            addAll(inList);
        }
    }

    /**
     * creats a list properties object and uses the given map as its parent if
     * it is a properties map. Otherwise a new map properties object is created
     * using the contents of the provided map and then used as the parent for
     * the new list properties.
     * 
     * @param inMap the map.
     */
    public ListProperties(Map inMap) {
        super();
        if(inMap == null) {
            throw new NullPointerException("Map is null.");
        }
        if(inMap instanceof Properties) {
            setParent((Properties) inMap);
        }
        else {
            setParent(new MapProperties(inMap));
        }
    }
    
    /**
     * creates a list properties object and initializes it with the the
     * configuration provided by the reader.
     * 
     * @param inReader the reader providing the configuration.
     * @throws PropertiesException
     */
    public ListProperties(Reader inReader) throws PropertiesException {
        super();
        if(inReader == null) {
            throw new NullPointerException("Reader is null.");
        }
        PropertiesParser.readList(this, inReader);
    }
    
    /**
     * creates a list properties object with the given parent properties.
     * 
     * @param inParent the parent properties.
     */
    public ListProperties(Properties inParent) {
        super(inParent);
    }
    
    /* 
     * @see java.util.List#add(int, java.lang.Object)
     */
    public void add(int inIndex, Object inValue) {
        list.add(inIndex, inValue);
    }
    
    /* 
     * @see java.util.List#add(java.lang.Object)
     */
    public boolean add(Object inValue) {
        return list.add(inValue);
    }
    
    /* 
     * @see java.util.List#addAll(java.util.Collection)
     */
    public boolean addAll(Collection inValues) {
        return list.addAll(inValues);
    }

    /* 
     * @see java.util.List#addAll(int, java.util.Collection)
     */
    public boolean addAll(int inIndex, Collection inValues) {
        return list.addAll(inIndex, inValues);
    }

    /* 
     * @see java.util.List#clear()
     */
    public void clear() {
        list.clear();
    }

    /* 
     * @see java.util.List#contains(java.lang.Object)
     */
    public boolean contains(Object inValue) {
        return list.contains(inValue);
    }

    /* 
     * @see java.util.List#containsAll(java.util.Collection)
     */
    public boolean containsAll(Collection inValues) {
        return list.containsAll(inValues);
    }

    /* 
     * @see java.util.List#get(int)
     */
    public Object get(int inIndex) {
        try {
            return new Context(this).replace(list.get(inIndex));
        }
        catch(PropertiesException e) {
            Throwable cause = e.getCause();
            if(cause == null) {
                throw new PropertiesException("Cannot resolve \"" + inIndex
                        + "\", " + e.getMessage());
            }
            throw new PropertiesException(
                    "Cannot resolve \"" + inIndex + "\":", cause);
        }
    }

    /* 
     * @see java.util.List#indexOf(java.lang.Object)
     */
    public int indexOf(Object inValue) {
        return list.indexOf(inValue);
    }

    /* 
     * @see java.util.List#isEmpty()
     */
    public boolean isEmpty() {
        return list.isEmpty();
    }

    /* 
     * @see java.util.List#iterator()
     */
    public Iterator iterator() {
        return new ListPropertiesIterator();
    }

    /* 
     * @see java.util.List#lastIndexOf(java.lang.Object)
     */
    public int lastIndexOf(Object inValue) {
        return list.lastIndexOf(inValue);
    }

    /* 
     * @see com.eva.properties.Properties#length()
     */
    public int length() {
        return list.size();
    }

    /* 
     * @see java.util.List#listIterator()
     */
    public ListIterator listIterator() {
        return new ListPropertiesIterator();
    }

    /* 
     * @see java.util.List#listIterator(int)
     */
    public ListIterator listIterator(int inIndex) {
        return new ListPropertiesIterator(inIndex);
    }

    /* 
     * @see java.util.List#remove(int)
     */
    public Object remove(int inIndex) {
        return list.remove(inIndex);
    }

    /* 
     * @see java.util.List#remove(java.lang.Object)
     */
    public boolean remove(Object inValue) {
        return list.remove(inValue);
    }

    /* 
     * @see java.util.List#removeAll(java.util.Collection)
     */
    public boolean removeAll(Collection inValues) {
        return list.removeAll(inValues);
    }

    /* 
     * @see java.util.List#retainAll(java.util.Collection)
     */
    public boolean retainAll(Collection inValues) {
        return list.retainAll(inValues);
    }

    /* 
     * @see java.util.List#set(int, java.lang.Object)
     */
    public Object set(int inIndex, Object inValue) {
        return list.set(inIndex, inValue);
    }

    /* 
     * @see java.util.List#size()
     */
    public int size() {
        return list.size();
    }

    /* 
     * @see java.util.List#subList(int, int)
     */
    public List subList(int inFrom, int inLength) {
        throw new UnsupportedOperationException();
    }

    /* 
     * @see java.util.List#toArray()
     */
    public Object[] toArray() {
        return toArray(Object.class);
    }

    /* 
     * @see java.util.List#toArray(java.lang.Object[])
     */
    public Object[] toArray(Object[] inArray) {
        Object[] array = toArray(inArray.getClass().getComponentType());
        if(array.length <= inArray.length) {
            System.arraycopy(array, 0, inArray, 0, array.length);
        }
        return array;
    }
    
    /**
     * returns the internal list.
     * 
     * @return the internal list.
     */
    public List getList() {
        return list;
    }

    /*
     * @see com.eva.properties.Properties#copy(com.eva.properties.Properties)
     */
    Properties copy(Properties inParent) {
        ListProperties newProperties = new ListProperties(inParent);
        for(Iterator i = list.iterator(); i.hasNext();) {
            Object value = i.next();
            if(value instanceof Properties) {
                newProperties.list
                        .add(((Properties) value).copy(newProperties));
            }
            else if(value instanceof Replaceable) {
                newProperties.list.add(((Replaceable) value)
                        .copy(newProperties));
            }
            else {
                newProperties.list.add(value);
            }
        }
        return newProperties;
    }

    /*
     * @see com.eva.properties.Properties#getProperty(
     *      com.eva.properties.Context, java.lang.String)
     */
    Object getProperty(Context inContext, String inKey)
            throws PropertiesException {
        int p = inKey.indexOf('.');
        if(p > 0) {
            String localKey = inKey.substring(0, p);
            String rightKey = inKey.substring(p + 1);
            if(localKey.equals("*")) {
                return createJokerList(inContext, rightKey);
            }
            if(list == null) {
                throw new IndexOutOfBoundsException();
            }
            int index;
            try {
                index = Integer.parseInt(localKey);
            }
            catch(NumberFormatException e) {
                return null;
            }
            Object value = list.get(index);
            if(value instanceof Properties) {
                Properties inner = (Properties) value;
                return inner.getProperty(new Context(inContext, inner),
                        rightKey);
            }
        }
        if(inKey.equals("length")) {
            return new Integer(length());
        }
        if(list == null) {
            return null;
        }
        Object value;
        try {
            value = list.get(Integer.parseInt(inKey)); // throws IndexOutOfBounds
        }
        catch(NumberFormatException e) {
            return null;
        }
        if(value == null) {
            return null;
        }
        return inContext.replace(value);
    }

    /*
     * @see com.eva.properties.Properties#putProperty(
     *      com.eva.properties.Context, java.lang.String, java.lang.Object)
     */
    Object putProperty(Context inContext, String inKey, Object inValue) {
        int p = inKey.indexOf('.');
        int index;
        if(p > 0) {
            String key = inKey.substring(0, p);
            try {
                index = Integer.parseInt(inKey);
            }
            catch(NumberFormatException e) {
                throw new PropertiesException(key + " is not a number.");
            }
            if(index > list.size()) {
                throw new PropertiesException("Index out of bounds, " + index
                        + " > " + list.size());
            }
            Object value = list.get(index);
            if(value instanceof Replaceable) {
                value = inContext.replaceReplaceable((Replaceable) value);
            }
            if(value instanceof Properties) {
                Properties inner = (Properties) value;
                return inner.putProperty(new Context(inContext, inner), inKey
                        .substring(p + 1), inValue);
            }
            throw new PropertiesException(key
                    + " is neither a map nor a list, " + String.valueOf(value));
        }
        try {
            index = Integer.parseInt(inKey);
        }
        catch(NumberFormatException e) {
            throw new PropertiesException("\"" + inKey + "\" is not a number.");
        }
        while(list.size() <= index) {
            list.add(null);
        }
        return list.set(index, inValue);
    }

    /**
     * converts this list properties object to an object array of the specified
     * type.
     * 
     * @param inClass the type to use for the array.
     * @return the array.
     */
    public Object[] toArray(Class inClass) {
        Object[] array = (Object[]) Array.newInstance(inClass, list.size());
        for(int i = 0; i < array.length; i++) {
            array[i] = get(i);
        }
        return array;
    }

    /* 
     * @see com.eva.properties.Properties#write(com.eva.properties.Writer)
     */
    void write(Writer inoutWriter) {
        inoutWriter.append("[\n");
        inoutWriter.increaseIndentation();
        for(Iterator i = list.iterator(); i.hasNext();) {
            inoutWriter.appendIndentation();
            inoutWriter.write(i.next());
        }
        inoutWriter.decreaseIndentation();
        inoutWriter.appendIndentation();
        inoutWriter.append("]\n");
    }

    private ListProperties createJokerList(Context inContext, String rightKey)
            throws PropertiesException {
        ListProperties l = new ListProperties((Properties) this);
        for(Iterator i = list.iterator(); i.hasNext();) {
            Object value = i.next();
            if(!(value instanceof Properties)) {
                continue;
            }
            value = ((Properties) value).getProperty(inContext,
                    rightKey);
            if(value != null) {
                l.add(value);
            }
        }
        return l;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy