001/*
002 * The Kuali Financial System, a comprehensive financial management system for higher education.
003 * 
004 * Copyright 2005-2014 The Kuali Foundation
005 * 
006 * This program is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU Affero General Public License as
008 * published by the Free Software Foundation, either version 3 of the
009 * License, or (at your option) any later version.
010 * 
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU Affero General Public License for more details.
015 * 
016 * You should have received a copy of the GNU Affero General Public License
017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package org.kuali.rice.kns.util;
020
021import java.util.Collection;
022import java.util.Map;
023import java.util.Set;
024
025import org.kuali.rice.kns.util.properties.PropertyTree;
026
027/**
028 * This class implements the Map interface for a Properties instance. Exports all properties from the given Properties instance as
029 * constants, usable from jstl. Implements the Map interface (by delegating everything to the PropertyTree, which really implements
030 * the Map methods directly) so that jstl can translate ${Constants.a} into a call to ConfigConstants.get( "a" ).
031 * <p>
032 * The contents of this Map cannot be changed once it has been initialized. Any calls to any of the Map methods made before the
033 * propertyTree has been initialized (i.e. before setProperties has been called) will throw an IllegalStateException.
034 * <p>
035 * Jstl converts ${Constants.a.b.c} into get("a").get("b").get("c"), so the properties are stored in a PropertyTree, which converts
036 * the initial set( "a.b.c", "value" ) into construction of the necessary tree structure to support get("a").get("b").get("c").
037 * <p>
038 * Implicitly relies on the assumption that the JSP will be calling toString() on the result of the final <code>get</code>, since
039 * <code>get</code> can only return one type, and that type must be the complex one so that further dereferencing will be
040 * possible.
041 * 
042 * 
043 */
044
045public abstract class JstlPropertyHolder implements Map {
046    private PropertyTree propertyTree;
047
048    /**
049     * Default constructor
050     */
051    public JstlPropertyHolder() {
052        propertyTree = null;
053    }
054
055    protected void setProperties(Map<String,String> properties) {
056        propertyTree = new PropertyTree();
057        propertyTree.setProperties(properties);
058    }
059
060    /**
061     * Copies in the given propertyTree rather than building its own. Reasonably dangerous, since that tree might presumably be
062     * modified, violating the readonlyness of this datastructure.
063     * 
064     * @param properties
065     */
066    protected void setPropertyTree(PropertyTree tree) {
067        propertyTree = tree;
068    }
069
070
071    // delegated methods
072    /**
073     * @see org.kuali.rice.kns.util.properties.PropertyTree#get(java.lang.Object)
074     */
075    public Object get(Object key) {
076        if (propertyTree == null) {
077            throw new IllegalStateException("propertyTree has not been initialized");
078        }
079        return this.propertyTree.get(key);
080    }
081
082    /**
083     * @see org.kuali.rice.kns.util.properties.PropertyTree#size()
084     */
085    public int size() {
086        if (propertyTree == null) {
087            throw new IllegalStateException("propertyTree has not been initialized");
088        }
089        return this.propertyTree.size();
090    }
091
092    /**
093     * @see org.kuali.rice.kns.util.properties.PropertyTree#clear()
094     */
095    public void clear() {
096        if (propertyTree == null) {
097            throw new IllegalStateException("propertyTree has not been initialized");
098        }
099        this.propertyTree.clear();
100    }
101
102    /**
103     * @see org.kuali.rice.kns.util.properties.PropertyTree#isEmpty()
104     */
105    public boolean isEmpty() {
106        if (propertyTree == null) {
107            throw new IllegalStateException("propertyTree has not been initialized");
108        }
109        return this.propertyTree.isEmpty();
110    }
111
112    /**
113     * @see org.kuali.rice.kns.util.properties.PropertyTree#containsKey(java.lang.Object)
114     */
115    public boolean containsKey(Object key) {
116        if (propertyTree == null) {
117            throw new IllegalStateException("propertyTree has not been initialized");
118        }
119        return this.propertyTree.containsKey(key);
120    }
121
122    /**
123     * @see org.kuali.rice.kns.util.properties.PropertyTree#containsValue(java.lang.Object)
124     */
125    public boolean containsValue(Object value) {
126        if (propertyTree == null) {
127            throw new IllegalStateException("propertyTree has not been initialized");
128        }
129        return this.propertyTree.containsValue(value);
130    }
131
132    /**
133     * @see org.kuali.rice.kns.util.properties.PropertyTree#values()
134     */
135    public Collection values() {
136        if (propertyTree == null) {
137            throw new IllegalStateException("propertyTree has not been initialized");
138        }
139        return this.propertyTree.values();
140    }
141
142    /**
143     * @see org.kuali.rice.kns.util.properties.PropertyTree#putAll(java.util.Map)
144     */
145    public void putAll(Map m) {
146        if (propertyTree == null) {
147            throw new IllegalStateException("propertyTree has not been initialized");
148        }
149        this.propertyTree.putAll(m);
150    }
151
152    /**
153     * @see org.kuali.rice.kns.util.properties.PropertyTree#entrySet()
154     */
155    public Set entrySet() {
156        if (propertyTree == null) {
157            throw new IllegalStateException("propertyTree has not been initialized");
158        }
159        return this.propertyTree.entrySet();
160    }
161
162    /**
163     * @see org.kuali.rice.kns.util.properties.PropertyTree#keySet()
164     */
165    public Set keySet() {
166        if (propertyTree == null) {
167            throw new IllegalStateException("propertyTree has not been initialized");
168        }
169        return this.propertyTree.keySet();
170    }
171
172    /**
173     * @see org.kuali.rice.kns.util.properties.PropertyTree#remove(java.lang.Object)
174     */
175    public Object remove(Object key) {
176        if (propertyTree == null) {
177            throw new IllegalStateException("propertyTree has not been initialized");
178        }
179        return this.propertyTree.remove(key);
180    }
181
182    /**
183     * @see org.kuali.rice.kns.util.properties.PropertyTree#put(java.lang.Object, java.lang.Object)
184     */
185    public Object put(Object key, Object value) {
186        if (propertyTree == null) {
187            throw new IllegalStateException("propertyTree has not been initialized");
188        }
189        return this.propertyTree.put(key, value);
190    }
191}