001: /* ====================================================================
002: * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
003: *
004: * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by Jcorporate Ltd.
021: * (http://www.jcorporate.com/)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. "Jcorporate" and product names such as "Expresso" must
026: * not be used to endorse or promote products derived from this
027: * software without prior written permission. For written permission,
028: * please contact info@jcorporate.com.
029: *
030: * 5. Products derived from this software may not be called "Expresso",
031: * or other Jcorporate product names; nor may "Expresso" or other
032: * Jcorporate product names appear in their name, without prior
033: * written permission of Jcorporate Ltd.
034: *
035: * 6. No product derived from this software may compete in the same
036: * market space, i.e. framework, without prior written permission
037: * of Jcorporate Ltd. For written permission, please contact
038: * partners@jcorporate.com.
039: *
040: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
041: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
042: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
043: * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
044: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
045: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
046: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
047: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
048: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
049: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
050: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
051: * SUCH DAMAGE.
052: * ====================================================================
053: *
054: * This software consists of voluntary contributions made by many
055: * individuals on behalf of the Jcorporate Ltd. Contributions back
056: * to the project(s) are encouraged when you make modifications.
057: * Please send them to support@jcorporate.com. For more information
058: * on Jcorporate Ltd. and its products, please see
059: * <http://www.jcorporate.com/>.
060: *
061: * Portions of this software are based upon other open source
062: * products and are subject to their respective licenses.
063: */
064:
065: package com.jcorporate.expresso.core.security.filters;
066:
067: import com.jcorporate.expresso.core.misc.ReusableChar;
068: import com.jcorporate.expresso.kernel.util.FastStringBuffer;
069: import org.apache.log4j.Category;
070:
071: import java.util.HashMap;
072: import java.util.Iterator;
073:
074: /**
075: * This class provides a "filter parse tree" interface to the system.
076: * It is a dual action object, it's a union of a node, and a leaf. Thus allowing
077: * us to play with TreeMap/HashMap quickly.
078: * <p/>
079: * <i>Please Note:</i> This class is unsynchronized for performance reasons, please
080: * be careful when using in a multi-threaded environment outisde of the Filter
081: * class.
082: * </p>
083: *
084: * @author Michael Rimov
085: */
086: public class FilterTreeNode implements java.io.Serializable {
087: private String replacementString = null;
088: private HashMap subnodes = null;
089:
090: public FilterTreeNode() {
091: }
092:
093: /**
094: * @return A replacement string if it exists at this node. otherwise null
095: */
096: public String getReplacementString() {
097: return replacementString;
098: }
099:
100: /**
101: * Should be only called be the parse tree builder
102: * Set the replacement string that corresponds to this node
103: *
104: * @param newReplacementString The replacement string to put at this node
105: * @throws Exception if a replacement string already exists for this
106: */
107: public void setReplacementString(String newReplacementString)
108: throws Exception {
109:
110: // if (replacementString != null) {
111: // throw new Exception("Replacement String already exists for this node:" +
112: // " Value = " + replacementString);
113: // }
114: replacementString = (newReplacementString);
115: }
116:
117: /**
118: * Set a subnode based upon the character key. Should be only called
119: * by the parse tree builder.
120: *
121: * @param key The character key to look up the subnode.
122: * @param newSubNode The FilterTreeNode to exist on that subnode
123: * @throw Exception if subnode already exists for this key.
124: */
125: public void setSubnode(ReusableChar key, FilterTreeNode newSubnode)
126: throws Exception {
127: if (subnodes == null) {
128: subnodes = new HashMap();
129: }
130:
131: // if (subnodes.containsKey(key)) {
132: // throw new Exception(key + " already exists as a subnode");
133: // }
134: subnodes.put(key, newSubnode);
135: }
136:
137: /**
138: * @return true if a subnode exists for this key.
139: */
140: public boolean subnodeExists(ReusableChar key) {
141: if (subnodes == null) {
142: return false;
143: }
144:
145: return subnodes.containsKey(key);
146: }
147:
148: /**
149: * @param key The key to base this subnode after.
150: * @return the subnode that exists at this key, or null if it doesn't exist
151: */
152: public FilterTreeNode getSubnode(ReusableChar key) {
153: if (subnodes == null) {
154: return null;
155: }
156: if (subnodes.containsKey(key)) {
157: return (FilterTreeNode) subnodes.get(key);
158: } else {
159: return null;
160: }
161: }
162:
163: /**
164: * Dumps the contents of the tree to the log. (ie dumps this node and all
165: * subnodes.
166: *
167: * @param Category - The log4j Category to dump to.
168: */
169: public void dumpNode(Category log) {
170: if (log.isDebugEnabled()) {
171: FastStringBuffer fsb = FastStringBuffer.getInstance();
172: try {
173: dumpNode(fsb, 0);
174: log.debug(fsb.toString());
175: } finally {
176: fsb.release();
177: fsb = null;
178: }
179: }
180: }
181:
182: /**
183: * Dumps a printout of the node and subnodes to System.out
184: */
185: public void dumpNode() {
186: FastStringBuffer fsb = FastStringBuffer.getInstance();
187: try {
188: dumpNode(fsb, 0);
189: System.out.println(fsb.toString());
190: } finally {
191: fsb.release();
192: fsb = null;
193: }
194: }
195:
196: /**
197: * Dumps the contents of the tree to the log. uses depth to format
198: * how many tabs in
199: */
200: public void dumpNode(FastStringBuffer stringBuffer, int depth) {
201: if (replacementString != null) {
202: this .padWithTabs(stringBuffer, depth);
203: stringBuffer.append("Node's ReplacementString:"
204: + replacementString + "\n");
205: }
206: if (subnodes != null) {
207: for (Iterator i = subnodes.keySet().iterator(); i.hasNext();) {
208: Character c = (Character) i.next();
209: FilterTreeNode ftn = (FilterTreeNode) subnodes.get(c);
210:
211: if (ftn != null) {
212: this .padWithTabs(stringBuffer, depth);
213: stringBuffer
214: .append("dump for subnode: " + c + "\n");
215: ftn.dumpNode(stringBuffer, depth + 1);
216: }
217: }
218: }
219: }
220:
221: /**
222: * Formatter helping function to pad in for each node.
223: */
224: private void padWithTabs(FastStringBuffer stringBuffer, int numTabs) {
225: for (int i = 0; i < numTabs; i++) {
226: stringBuffer.append('\t');
227: }
228: }
229: }
|