KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > tigris > scarab > util > ScarabUtil


1 package org.tigris.scarab.util;
2
3 /* ================================================================
4  * Copyright (c) 2000-2002 CollabNet. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * 3. The end-user documentation included with the redistribution, if
18  * any, must include the following acknowlegement: "This product includes
19  * software developed by Collab.Net <http://www.Collab.Net/>."
20  * Alternately, this acknowlegement may appear in the software itself, if
21  * and wherever such third-party acknowlegements normally appear.
22  *
23  * 4. The hosted project names must not be used to endorse or promote
24  * products derived from this software without prior written
25  * permission. For written permission, please contact info@collab.net.
26  *
27  * 5. Products derived from this software may not use the "Tigris" or
28  * "Scarab" names nor may "Tigris" or "Scarab" appear in their names without
29  * prior written permission of Collab.Net.
30  *
31  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
32  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
33  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34  * IN NO EVENT SHALL COLLAB.NET OR ITS CONTRIBUTORS BE LIABLE FOR ANY
35  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
37  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
39  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
40  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42  *
43  * ====================================================================
44  *
45  * This software consists of voluntary contributions made by many
46  * individuals on behalf of Collab.Net.
47  */

48
49 import java.util.Iterator JavaDoc;
50 import java.util.List JavaDoc;
51
52 import org.apache.commons.lang.StringUtils;
53 import org.apache.oro.text.perl.Perl5Util;
54 import org.apache.turbine.RunData;
55 import org.tigris.scarab.om.Module;
56
57 /**
58  * A Utility class for code that doesn't really go other places.
59  *
60  * @author <a HREF="mailto:jon@collab.net">Jon Scott Stevens</a>
61  * @version $Id: ScarabUtil.java 8933 2004-02-03 11:31:48Z dep4b $
62  */

63 public class ScarabUtil
64 {
65     private static final String JavaDoc REGEX_URL =
66         "s%\\b(?:[hH][tT]{2}[pP]|[fF][tT][pP]):[^ \\t\\n<>\"]+[\\w/]*%<a HREF=\"$0\">$0</a>%g";
67     private static final String JavaDoc REGEX_MAILTO =
68         "s%\\b(?:([mM][aA][iI][lL][tT][oO])):([^ \\t\\n<>\"]+[\\w/])*%<a HREF=\"$0\">$2</a>%g";
69     private static final String JavaDoc REGEX_NEWLINETOBR =
70         "s%\\n%<br />%g";
71
72     private static Perl5Util perlUtil = new Perl5Util();
73
74
75     /**
76      * Finds the first value for the named request parameter. This is
77      * useful to handle the case when there are more than one of the
78      * named key fields present on a screen.
79      *
80      * @param runData Source of the export format information.
81      * @param name The name of the request parameter to get a value
82      * for.
83      * @return The format type, or <code>null</code> if indeterminate.
84      */

85     public static String JavaDoc findValue(RunData runData, String JavaDoc name)
86     {
87         String JavaDoc[] possibilities = runData.getParameters().getStrings(name);
88         if (possibilities != null)
89         {
90             for (int i = 0; i < possibilities.length; i++)
91             {
92                 if (StringUtils.isNotEmpty(possibilities[i]))
93                 {
94                     return possibilities[i];
95                 }
96             }
97         }
98         return null;
99     }
100
101     /**
102      * First, it converts all HTML markup into entities.
103      * Then it the Jakarta ORO package to convert http:// ftp:// mailto:
104      * links into URL's.
105      * Lastly, it uses the IssueIdParser to convert all issue id's into links.
106      */

107     public static String JavaDoc linkifyText(String JavaDoc input, ScarabLink link, Module module)
108         throws Exception JavaDoc
109     {
110         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(input.length() * 2);
111         // first get rid of any HTML crap
112
String JavaDoc output = ReferenceInsertionFilter.filter(input);
113         output = perlUtil.substitute(REGEX_NEWLINETOBR,output);
114         output = perlUtil.substitute(REGEX_MAILTO,output);
115         output = perlUtil.substitute(REGEX_URL,output);
116         List JavaDoc result = IssueIdParser.tokenizeText(module, output);
117         for (Iterator JavaDoc itr = result.iterator(); itr.hasNext();)
118         {
119             Object JavaDoc tmp = itr.next();
120             if (tmp instanceof String JavaDoc)
121             {
122                 sb.append(tmp);
123             }
124             else
125             {
126                 List JavaDoc tmpList = (List JavaDoc)tmp;
127                 link.addPathInfo("id", (String JavaDoc)tmpList.get(1));
128                 link.setLabel((String JavaDoc)tmpList.get(0));
129                 String JavaDoc bar = link.setAlternateText((String JavaDoc)tmpList.get(0)).toString();
130                 sb.append(bar);
131             }
132         }
133         return sb.toString();
134     }
135
136     /**
137      * Check whether Object array contains passed in object.
138      */

139     public static final boolean contains(Object JavaDoc[] array, Object JavaDoc obj)
140     {
141         boolean contains = false;
142         if (array != null && array.length > 0)
143         {
144             for (int i = 0; i < array.length; i++)
145             {
146                 Object JavaDoc element = array[i];
147                 if (obj.equals(element))
148                 {
149                     contains = true;
150                     break;
151                 }
152             }
153         }
154         return contains;
155     }
156               
157     /**
158      * URL encodes <code>in</code>. If the string is null, nothing will be
159      * written. This method is faster than urlEncodeSlow if the string to
160      * encode does not contain any characters needing encoding. It adds some
161      * penalty for strings which actually need to be encoded. for short strings
162      * ~20 characters the upside is a 75% decrease. while the penalty is a 10%
163      * increase. As many query parameters do not need encoding even in i18n
164      * applications it should be much better to delay the byte conversion.
165      *
166      * @param in the String to encode.
167      * @return the url-encoded string.
168      */

169     public static final String JavaDoc urlEncode(String JavaDoc in)
170     {
171         if (in == null)
172         {
173             return null;
174         }
175
176         if (in.length() == 0)
177         {
178             return "";
179         }
180
181         StringBuffer JavaDoc out = new StringBuffer JavaDoc(in.length());
182         char[] chars = in.toCharArray();
183
184         for (int i = 0; i < chars.length; i++)
185         {
186             char c = chars[i];
187
188             if (c < 128 && safe[c])
189             {
190                 out.append(c);
191             }
192             else if (c == ' ')
193             {
194                 out.append('+');
195             }
196             else
197             {
198                 // since we need to encode we will give up on
199
// doing it the fast way and convert to bytes.
200
return out
201                     .append(urlEncodeSlow(in.substring(i).getBytes()))
202                     .toString();
203             }
204         }
205         return out.toString();
206     }
207
208     /**
209      * URL encodes <code>in</code>. Code 'borrowed' from DynamicURI.java in
210      * the Jakarta Turbine 3 package. We use this code instead of
211      * java.net.Encoder because Encoder.encode is deprecated and we don't feel
212      * like putting a dependency on JDK 1.4.1. This should work fine for our
213      * purposes.
214      *
215      * @param in a non-empty String to encode.
216      * @return the url-encoded string.
217      */

218     private static final String JavaDoc urlEncodeSlow(byte[] bytes)
219     {
220         StringBuffer JavaDoc out = new StringBuffer JavaDoc(bytes.length * 2);
221
222         for (int i = 0; i < bytes.length; i++)
223         {
224             char c = (char)bytes[i];
225
226             if (c < 128 && safe[c])
227             {
228                 out.append(c);
229             }
230             else if (c == ' ')
231             {
232                 out.append('+');
233             }
234             else
235             {
236                 byte toEscape = bytes[i];
237                 out.append('%');
238                 int low = (toEscape & 0x0f);
239                 int high = ((toEscape & 0xf0) >> 4);
240                 out.append(HEXADECIMAL[high]);
241                 out.append(HEXADECIMAL[low]);
242             }
243         }
244         return out.toString();
245     }
246     
247     /**
248      * Array mapping hexadecimal values to the corresponding ASCII characters.
249      */

250     private static final char[] HEXADECIMAL =
251         {
252             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
253             'A', 'B', 'C', 'D', 'E', 'F'
254         };
255
256     /**
257      * Characters that need not be encoded. This is much faster than using a
258      * BitSet, and for such a small array the space cost seems justified.
259      */

260     private static boolean[] safe = new boolean[ 128 ];
261
262     /** Static initializer for {@link #safe} */
263     static
264     {
265         for (int i = 'a'; i <= 'z'; i++)
266         {
267             safe[ i ] = true;
268         }
269         for (int i = 'A'; i <= 'Z'; i++)
270         {
271             safe[ i ] = true;
272         }
273         for (int i = '0'; i <= '9'; i++)
274         {
275             safe[ i ] = true;
276         }
277
278         safe['-'] = true;
279         safe['_'] = true;
280         safe['.'] = true;
281         safe['!'] = true;
282         safe['~'] = true;
283         safe['*'] = true;
284         safe['\''] = true;
285         safe['('] = true;
286         safe[')'] = true;
287     }
288 }
289
Popular Tags