001: /**********************************************************************************
002: *
003: * Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees of Indiana University,
004: * Board of Trustees of the Leland Stanford, Jr., University, and The MIT Corporation
005: *
006: * Licensed under the Educational Community License Version 1.0 (the "License");
007: * By obtaining, using and/or copying this Original Work, you agree that you have read,
008: * understand, and will comply with the terms and conditions of the Educational Community License.
009: * You may obtain a copy of the License at:
010: *
011: * http://cvs.sakaiproject.org/licenses/license_1_0.html
012: *
013: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
014: * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
015: * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
016: * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
017: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
018: *
019: **********************************************************************************/package edu.indiana.lib.twinpeaks.util;
020:
021: import java.io.*;
022: import java.net.*;
023: import java.util.*;
024:
025: /**
026: * Parameter (name=value pair) manipulation. In particular, this utility
027: * supports multiple parameters with the same name:
028: * <code>
029: * xxx=value1&xxx=value2
030: * </code>
031: */
032: public class ParameterMap {
033:
034: private static org.apache.commons.logging.Log _log = LogUtils
035: .getLog(ParameterMap.class);
036:
037: static private final int PREFIXSIZE = 4;
038: static private final int MAXVALUE = (1 << PREFIXSIZE * 4) - 1;
039:
040: private HashMap _parameterMap;
041: private Map.Entry _entry;
042: private int _fill;
043:
044: /**
045: * Public constructor
046: */
047: public ParameterMap() {
048: _parameterMap = new HashMap();
049: _fill = 0;
050: }
051:
052: /**
053: * Empty the parameter map
054: */
055: public synchronized void clear() {
056: _parameterMap.clear();
057: }
058:
059: /**
060: * Get an Iterator to the parameter map
061: * @return Map iterator
062: */
063: public synchronized Iterator getParameterMapIterator() {
064: return _parameterMap.entrySet().iterator();
065: }
066:
067: /**
068: * Save the next Entry Set for this Iterator
069: * @param iterator Parameter map iterator
070: * @return false If no more entries exist
071: */
072: public synchronized boolean nextParameterMapEntry(Iterator iterator) {
073: if (!iterator.hasNext()) {
074: _entry = null;
075: return false;
076: }
077:
078: _entry = (Map.Entry) iterator.next();
079: return true;
080: }
081:
082: /**
083: * Get the parameter name from the current iterator
084: * @return Item name
085: */
086: public synchronized String getParameterNameFromIterator() {
087: return (String) ((String) _entry.getKey())
088: .substring(PREFIXSIZE);
089: }
090:
091: /**
092: * Get the parameter value from the current iterator
093: * @return Item value
094: */
095: public synchronized String getParameterValueFromIterator() {
096: return (String) _entry.getValue();
097: }
098:
099: /**
100: * Set a name/value pair
101: * @param name Item name
102: * @param value Item value
103: */
104: public synchronized void setParameterMapValue(String name,
105: String value) {
106: String uniqueName = generateFillText() + name;
107:
108: _parameterMap.put(uniqueName, value);
109: }
110:
111: /**
112: * Get a named value from the parameter map
113: * @param name Item name
114: * @return Item value (a String, null if none)
115: */
116: public synchronized String getParameterMapValue(String name) {
117: Iterator iterator = getParameterMapIterator();
118:
119: while (iterator.hasNext()) {
120: Map.Entry entry = (Map.Entry) iterator.next();
121: String mapName = (String) ((String) entry.getKey())
122: .substring(PREFIXSIZE);
123:
124: if (mapName.equals(name)) {
125: return (String) entry.getValue();
126: }
127: }
128: return null;
129: }
130:
131: /**
132: * Get the parameter name associated with the 1st occurance of this value
133: * @param value Item value
134: * @return Item name (a String, null if none)
135: */
136: public synchronized String getParameterMapName(String value) {
137: Iterator iterator = getParameterMapIterator();
138:
139: while (iterator.hasNext()) {
140: Map.Entry entry = (Map.Entry) iterator.next();
141: String mapValue = (String) ((String) entry.getValue());
142:
143: if (mapValue.equals(value)) {
144: return (String) ((String) entry.getKey())
145: .substring(PREFIXSIZE);
146: }
147: }
148: return null;
149: }
150:
151: /**
152: * Fetch and increment the "unique fill text" seed
153: * @return Current seed value
154: */
155: private synchronized int getFillSeed() {
156: return _fill++;
157: }
158:
159: /**
160: * Build fixed length numeric filler text.
161: * @return Fill text. This is the HEX representation of the "rightmost"
162: * <code>PREFIXSIZE</code> digits of the original value.
163: */
164: private String generateFillText() {
165: StringBuffer result;
166: int value;
167:
168: value = getFillSeed();
169: if ((value < 0) || (value > MAXVALUE)) {
170: throw new UnsupportedOperationException("Value " + value
171: + " out of range");
172: }
173:
174: result = new StringBuffer();
175:
176: for (int i = 0; i < PREFIXSIZE; i++) {
177: result.insert(0, Integer.toHexString(value & 0xf));
178: value >>= 4;
179: }
180: return result.toString();
181: }
182:
183: /**
184: * Populate a parameter map from an URL argument list. Any of:
185: * <p><code>
186: * http://x.y.com?xxx=yyy&aaa=bbb
187: * </code>
188: *<br>
189: * <code>
190: * ?xxx=yyy&aaa=bbb
191: * </code>
192: *<br>
193: * <code>
194: * xxx=yyy&aaa=bbb
195: * </code><p>
196: * Will populated the map as:
197: * <code>
198: * xxx=yyy
199: * aaa=bbb
200: * </code><br>
201: *
202: * @param url Original URL [with optional parameter list] or only
203: * the parameter list [with an optional ? prefix]
204: * @param delimiter Argument separator text (regular expression)
205: * @return Number of parameters saved
206: */
207: public synchronized int populateMapFromUrlArguments(String url,
208: String delimiter) {
209: String parameters = url;
210: int count = 0;
211: String[] p;
212:
213: /*
214: * Find the argument list
215: */
216: if (url.startsWith("?")) {
217: parameters = (url.length() == 1) ? "" : url.substring(1);
218:
219: } else if (url.indexOf("://") != -1) {
220: int index = url.indexOf('?');
221:
222: parameters = "";
223: if ((index != -1) && (index != url.length())) {
224: parameters = url.substring(index + 1);
225: }
226: }
227: /*
228: * Save the name=value pairs
229: */
230: p = parameters.split(delimiter);
231: for (int i = 0; i < p.length; i++) {
232: int index;
233:
234: if ((index = p[i].indexOf("=")) == -1) {
235: /*
236: * Omit if no value specified
237: */
238: continue;
239: }
240:
241: setParameterMapValue(p[i].substring(0, index), p[i]
242: .substring(index + 1));
243: count++;
244: }
245: return count;
246: }
247: }
|