View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.view.facelets.tag.jstl.fn;
20  
21  import java.lang.reflect.Array;
22  import java.util.Collection;
23  import java.util.Map;
24  import java.util.StringTokenizer;
25  
26  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletFunction;
27  
28  /**
29   * Implementations of JSTL Functions
30   * 
31   * @author Jacob Hookom
32   * @version $Id$
33   */
34  public final class JstlFunction
35  {
36      private JstlFunction()
37      {
38      }
39  
40      @JSFFaceletFunction(name="fn:contains")
41      public static boolean contains(String name, String searchString)
42      {
43          if (name == null || searchString == null)
44          {
45              return false;
46          }
47  
48          return -1 != name.indexOf(searchString);
49      }
50  
51      @JSFFaceletFunction(name="fn:containsIgnoreCase")
52      public static boolean containsIgnoreCase(String name, String searchString)
53      {
54          if (name == null || searchString == null)
55          {
56              return false;
57          }
58          
59          return -1 != name.toUpperCase().indexOf(searchString.toUpperCase());
60      }
61  
62      @JSFFaceletFunction(name="fn:endsWith")
63      public static boolean endsWith(String name, String searchString)
64      {
65          if (name == null || searchString == null)
66          {
67              return false;
68          }
69          
70          return name.endsWith(searchString);
71      }
72  
73      @JSFFaceletFunction(name="fn:escapeXml")
74      public static String escapeXml(String value)
75      {
76          if (value == null)
77          {
78              return "";
79          }
80          if (value.length() == 0)
81          {
82              return "";
83          }
84          
85          StringBuilder sb = null;    //create later on demand
86          String app;
87          char c;
88          for (int i = 0; i < value.length (); ++i)
89          {
90              app = null;
91              c = value.charAt(i);
92              
93              // All characters before letters
94              if ((int)c < 0x41)
95              {
96                  switch (c)
97                  {
98                      case '<' : app = "&lt;"; break;      //<
99                      case '>' : app = "&gt;"; break;      //>
100                     case '\'': app = "&#039;"; break;    //'
101                     case '"' : app = "&#034;"; break;    //"
102                     case '&' : //&
103                         if (i+4 < value.length() )
104                         {
105                             if ('a' == value.charAt(i+1) &&
106                                 'm' == value.charAt(i+2) &&
107                                 'p' == value.charAt(i+3) &&
108                                 ';' == value.charAt(i+4))
109                             {
110                                 //Skip
111                             }
112                             else
113                             {
114                                 app = "&amp;";
115                             }
116                         }
117                         else
118                         {
119                             app = "&amp;";
120                         }
121                         break;
122                     default: // all fine
123                 }
124             } 
125             if (app != null)
126             {
127                 if (sb == null)
128                 {
129                     sb = new StringBuilder(value.substring(0, i));
130                 }
131                 sb.append(app);
132             }
133             else
134             {
135                 if (sb != null)
136                 {
137                     sb.append(c);
138                 }
139             }
140         }
141 
142         if (sb == null)
143         {
144             return value;
145         }
146         else
147         {
148             return sb.toString();
149         }
150     }
151 
152     @JSFFaceletFunction(name="fn:indexOf")
153     public static int indexOf(String name, String searchString)
154     {
155         if (name == null || searchString == null)
156         {
157             return -1;
158         }
159         
160         return name.indexOf(searchString);
161     }
162 
163     @JSFFaceletFunction(name="fn:join")
164     public static String join(String[] a, String delim)
165     {
166         if (a == null || delim == null)
167         {
168             return "";
169         }
170         
171         if (a.length == 0)
172         {
173             return "";
174         }
175         
176         StringBuilder sb = new StringBuilder(a.length * (a[0].length() + delim.length()));
177         for (int i = 0; i < a.length; i++)
178         {
179             sb.append(a[i]);
180             if (i < (a.length - 1))
181             {
182                 sb.append(delim);
183             }
184         }
185         
186         return sb.toString();
187     }
188 
189     @JSFFaceletFunction(name="fn:length")
190     public static int length(Object obj)
191     {
192         if (obj == null)
193         {
194             return 0;
195         }
196         
197         if (obj instanceof Collection)
198         {
199             return ((Collection<?>) obj).size();
200         }
201         
202         if (obj.getClass().isArray())
203         {
204             return Array.getLength(obj);
205         }
206         
207         if (obj instanceof String)
208         {
209             return ((String) obj).length();
210         }
211         
212         if (obj instanceof Map)
213         {
214             return ((Map<?, ?>) obj).size();
215         }
216         
217         throw new IllegalArgumentException("Object type not supported: " + obj.getClass().getName());
218     }
219 
220     @JSFFaceletFunction(name="fn:replace")
221     public static String replace(String value, String a, String b)
222     {
223         if (value == null)
224         {
225             return "";
226         }
227         if (value.length() == 0)
228         {
229             return "";
230         }
231         if (a == null)
232         {
233             return value;
234         }
235         if (a.length() == 0)
236         {
237             return value;
238         }
239         if (b == null)
240         {
241             b = "";
242         }
243         
244         return value.replaceAll(a, b);
245     }
246 
247     @JSFFaceletFunction(name="fn:split")
248     public static String[] split(String value, String d)
249     {
250         if (value == null)
251         {
252             return new String[]{""};
253         }
254         if (value.length() == 0)
255         {
256             return new String[]{""};
257         }
258         if (d == null)
259         {
260             return new String[]{value};
261         }
262         if (d.length() == 0)
263         {
264             return new String[]{value};
265         }        
266         
267         StringTokenizer st = new StringTokenizer(value, d);
268         int numTokens = st.countTokens();
269         if (numTokens == 0)
270         {
271             return new String[]{value};
272         }
273         String[] array = new String[numTokens];
274         int i = 0;
275         while (st.hasMoreTokens())
276         {
277             array[i] = st.nextToken();
278             i++;
279         }
280         return array;
281     }
282 
283     @JSFFaceletFunction(name="fn:startsWith")
284     public static boolean startsWith(String value, String p)
285     {
286         if (value == null || p == null)
287         {
288             return false;
289         }
290         
291         return value.startsWith(p);
292     }
293 
294     @JSFFaceletFunction(name="fn:substring")
295     public static String substring(String v, int s, int e)
296     {
297         if (v == null)
298         {
299             return "";
300         }
301         if (v.length() == 0)
302         {
303             return "";
304         }
305         if (s >= v.length())
306         {
307             return "";
308         }
309         if (s < 0)
310         {
311             s = 0;
312         }
313         if (e >= v.length())
314         {
315             e = v.length();
316         }
317         if (e < s)
318         {
319             return ""; 
320         }
321         
322         return v.substring(s, e);
323     }
324 
325     @JSFFaceletFunction(name="fn:substringAfter")
326     public static String substringAfter(String v, String p)
327     {
328         if (v == null)
329         {
330             return "";
331         }
332         if (v.length() == 0)
333         {
334             return "";
335         }
336         
337         int i = v.indexOf(p);
338         if (i >= 0)
339         {
340             return v.substring(i + p.length());
341         }
342         
343         return "";
344     }
345 
346     @JSFFaceletFunction(name="fn:substringBefore")
347     public static String substringBefore(String v, String s)
348     {
349         if (v == null)
350         {
351             return "";
352         }
353         if (v.length() == 0)
354         {
355             return "";
356         }
357         
358         int i = v.indexOf(s);
359         if (i > 0)
360         {
361             return v.substring(0, i);
362         }
363         
364         return "";
365     }
366 
367     @JSFFaceletFunction(name="fn:toLowerCase")
368     public static String toLowerCase(String v)
369     {
370         if (v == null)
371         {
372             return "";
373         }
374         if (v.length() == 0)
375         {
376             return "";
377         }
378         
379         return v.toLowerCase();
380     }
381 
382     @JSFFaceletFunction(name="fn:toUpperCase")
383     public static String toUpperCase(String v)
384     {
385         if (v == null)
386         {
387             return "";
388         }
389         if (v.length() == 0)
390         {
391             return "";
392         }
393         
394         return v.toUpperCase();
395     }
396 
397     @JSFFaceletFunction(name="fn:trim")
398     public static String trim(String v)
399     {
400         if (v == null)
401         {
402             return "";
403         }
404         if (v.length() == 0)
405         {
406             return "";
407         }
408         return v.trim();
409     }
410 
411 }