Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/tripi/asp/util/Tools.java


1   /**
2    * ArrowHead ASP Server 
3    * This is a source file for the ArrowHead ASP Server - an 100% Java
4    * VBScript interpreter and ASP server.
5    *
6    * For more information, see http://www.tripi.com/arrowhead
7    *
8    * Copyright (C) 2002  Terence Haddock
9    *
10   * This program is free software; you can redistribute it and/or modify
11   * it under the terms of the GNU General Public License as published by
12   * the Free Software Foundation; either version 2 of the License, or
13   * (at your option) any later version.
14   *
15   * This program is distributed in the hope that it will be useful,
16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   * GNU General Public License for more details.
19   *
20   * You should have received a copy of the GNU General Public License
21   * along with this program; if not, write to the Free Software
22   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23   *
24   */
25  package com.tripi.asp.util;
26  
27  import java.util.ArrayList;
28  import java.util.Enumeration;
29  import java.util.HashMap;
30  import java.util.Iterator;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Vector;
34  
35  import jregex.Pattern;
36  
37  import org.apache.log4j.Category;
38  
39  import com.tripi.asp.AspCollection;
40  import com.tripi.asp.AspException;
41  import com.tripi.asp.AspNestedException;
42  import com.tripi.asp.AspReadOnlyException;
43  import com.tripi.asp.Constants;
44  import com.tripi.asp.SimpleMap;
45  import com.tripi.asp.SimpleReference;
46  import com.tripi.asp.Types;
47  import com.tripi.asp.UndefinedValueNode;
48  
49  public class Tools
50  {
51      /** Debugging category */
52      private static Category DBG = Category.getInstance(Tools.class);
53  
54      /**
55       * This function parses a query string. The keys and values
56       * are left un-decoded so post-processing can occur.
57       * @param queryString query string to parse
58       * @return map of key -> list of values
59       */
60      public static Map parseQueryString(String queryString)
61      {
62          if (DBG.isDebugEnabled()) 
63          {
64              DBG.debug("Parse: " + queryString);
65              try {
66                  String testString = new String(
67                      queryString.getBytes("ISO8859-1"), "UTF-8");
68                  DBG.debug("Test: " + testString);
69              } catch (Exception ex) {
70                  DBG.error(ex);
71              }
72          }
73          HashMap map = new HashMap();
74          if (queryString == null) return map;
75  
76          final Pattern tokP = new Pattern("&");
77          String[] arr=tokP.tokenizer(queryString).split();
78          for (int i =0; i < arr.length; i++)
79          {
80              String paramValue = arr[i];
81              if (DBG.isDebugEnabled()) {
82                  DBG.debug("ParamValue: " + paramValue);
83              }
84              int eqIndex = paramValue.indexOf('=');
85              String param, value;
86              if (eqIndex == -1) {
87                  param = paramValue;
88                  value = "";
89              } else {
90                  param = paramValue.substring(0, eqIndex);
91                  value = paramValue.substring(eqIndex + 1);
92              }
93  
94              if (DBG.isDebugEnabled()) {
95                  DBG.debug("Param: " + param);
96                  DBG.debug("Value: " + value);
97              }
98              if (map.containsKey(param)) {
99                  List oldValue = (List)map.get(param);
100                 oldValue.add(value);
101             } else {
102                 List theList = new ArrayList();
103                 theList.add(value);
104                 map.put(param, theList);
105             }
106         }
107         return map;
108     }
109 
110     private static String fixValue(String value, boolean bDecode)
111         throws AspException
112     {
113         String retValue;
114         if (bDecode)
115         {
116             retValue = urlDecode(value);
117         } else {
118             retValue = value;
119         }
120         if (DBG.isDebugEnabled()) DBG.debug("Decoding value: " + retValue);
121         try {
122             retValue = new String(retValue.getBytes("ISO8859-1"), "UTF-8");
123         } catch (Exception ex)
124         {
125             throw new AspNestedException(ex);
126         }
127         if (DBG.isDebugEnabled()) DBG.debug("Value: " + retValue);
128         return retValue;
129     }
130 
131     private static void testFixValue(String value)
132     {
133         try {
134             String testString = new String(
135                 value.getBytes("ISO8859-1"), "UTF-8");
136             DBG.debug("Value: " + value);
137             DBG.debug("Value(UTF-8): " + testString);
138         } catch (Exception ex) {
139             DBG.error(ex);
140         }
141     }
142 
143     public static void convertToMultiValue(AspCollection contents,
144         Map paramValues, boolean bDecodeValues) throws AspException
145     {
146         Iterator e = paramValues.keySet().iterator();
147         while (e.hasNext())
148         {
149             String key = (String)e.next();
150             Object valuesObj = paramValues.get(key);
151             String keyDec = fixValue(key, bDecodeValues);
152 
153             Object contentsValue = contents.get(keyDec);
154             if (contentsValue instanceof UndefinedValueNode)
155             {
156                 MultiValue multiValue = new MultiValue();
157                 contents.put(keyDec, multiValue);
158                 contentsValue = multiValue;
159             }
160             if (valuesObj instanceof List)
161             {
162                 List values = (List)valuesObj;
163                 for (int i = 0; i < values.size(); i++)
164                 {
165                     String value = (String)values.get(i);
166                     String valDec = fixValue(value, bDecodeValues);
167 
168                     ((MultiValue)contentsValue).add(valDec);
169                 }
170             } else if (valuesObj instanceof String[])
171             {
172                 String values[] = (String[])valuesObj;
173                 for (int i = 0; i < values.length; i++)
174                 {
175                     String valDec = fixValue(values[i], bDecodeValues);
176                 
177                     ((MultiValue)contentsValue).add(valDec);
178                 }
179             } else {
180                 String valDec = fixValue(valuesObj.toString(), bDecodeValues);
181         
182                 ((MultiValue)contentsValue).add(valDec);
183             }
184         }
185     }
186 
187     public static boolean isHex(char ch)
188     {
189         if ((ch >= '0') && (ch <= '9')) return true;
190         if ((ch >= 'a') && (ch <= 'f')) return true;
191         if ((ch >= 'A') && (ch <= 'F')) return true;
192         return false;
193     }
194 
195     public static String urlDecode(String paramsEncoded)
196     {
197         StringBuffer str = new StringBuffer();
198         int i = 0;
199 
200         while (i < paramsEncoded.length())
201         {
202             if (paramsEncoded.charAt(i)=='%') {
203                 if (paramsEncoded.length()<(i+3)) {
204                     str.append(paramsEncoded.charAt(i));
205                 } else {
206                     String hexStr = paramsEncoded.substring(i+1, i+3);
207                     if (isHex(hexStr.charAt(0)) && isHex(hexStr.charAt(1)))
208                     {
209                         char chVal = (char)Integer.parseInt(hexStr, 16);
210                         str.append(chVal);
211                         i+=2;
212                     } else {
213                         str.append(paramsEncoded.charAt(i));
214                     }
215                 }
216             } else if (paramsEncoded.charAt(i)=='+') {
217                 str.append(' ');
218             } else {
219                 str.append(paramsEncoded.charAt(i));
220             }
221             i++;
222         }
223         return str.toString();
224     }
225 
226 
227     /**
228      * MultiValue is a class which can store multiple values for
229      * a single object.
230      */
231     public static class MultiValue implements SimpleReference, SimpleMap
232     {
233         /** List of values */
234         Vector values;
235 
236         /** String representation of the whole list */
237         String  wholeValue;
238 
239         /** count of items in the array of values, publically
240             accessible to the ASP code. */
241         public int count;
242 
243         /**
244          * Constructor, initially created with no values.
245          */
246         public MultiValue()
247         {
248             values = new Vector();
249             wholeValue = "";
250             count = 0;
251         }
252 
253         /**
254          * Adds a value to this multiple value list.
255          * @param value New value to add.
256          */
257         void add(String value)
258         {
259             values.add(value);
260             if (!wholeValue.equals("")) wholeValue += ", ";
261             wholeValue+=value;
262             count++;
263         }
264 
265         /**
266          * Obtains the list of keys for this multi value.
267          * This function is used in the For Each ... statement.
268          * @return Enumeration of values in this multi value.
269          * @see SimpleMap#getKeys
270          */
271         public Enumeration getKeys()
272         {
273             return values.elements();
274         }
275 
276         /**
277          * SimpleMap read function to obtain a multi value at
278          * the specified index. <b>TODO</b> 1-based or 0-based?
279          * @param value key of multi value to obtain, will
280          * be converted to integer.
281          * @return value at the specified index.
282          * @throws AspException on error, mosting array index out of bounds.
283          * @see SimpleMap#get
284          */
285         public Object get(Object value) throws AspException
286         {
287             int iVal = Types.coerceToInteger(value).intValue();
288             if (iVal < 1 || iVal > count) {
289                 throw new AspException("Array index out of bound: " + iVal);
290             }
291             return values.get(iVal - 1);
292         }
293 
294         /**
295          * SimpleMap write function to store a value at a specified
296          * index. This function always throws AspReadOnlyException
297          * since Request.QueryString(i) is read-only.
298          * @param key Key of object to store.
299           * @param value Value of object to store.
300          * @throws AspException always throws AspReadOnlyException
301          * @see SimpleMap#put
302          */
303         public void put(Object key, Object value) throws AspException
304         {
305             throw new AspReadOnlyException("Request.QueryString");
306         }
307 
308         /**
309          * SimpleReference method to obtain the first value of this
310          * multi value list.
311          * @return first value of this multi value list.
312          * @throws AspException on error
313          * @see SimpleReference#getValue
314          */
315         public Object getValue() throws AspException
316         {
317             if (values.size()==0)
318                 return Constants.undefinedValueNode;
319             return wholeValue;
320         }
321 
322         /**
323          * SimpleReference method to set the value of this multi value 
324          * list. Always throws AspReadOnlyException 
325          * @param obj New value
326          * @throws AspException always throws AspReadOnlyException
327          */
328         public void setValue(Object obj) throws AspException
329         {
330             throw new AspReadOnlyException("Request.QueryString");
331         }
332 
333         /**
334          * Converts this multi value class to string, for debugging.
335          * @return string value of this query string value class
336          */
337         public String toString()
338         {
339             return "{MultiValue(" + values + ")}";
340         }
341     }
342 }
343