KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > micronova > jsp > tag > CodecFunctionMapper


1 /*
2
3 Copyright 2003-2007 MicroNova (R)
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or
7 without modification, are permitted provided that the following
8 conditions are met:
9
10     * Redistributions of source code must retain the above copyright
11     notice, this list of conditions and the following disclaimer.
12
13     * 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     * Neither the name of MicroNova nor the names of its contributors
18     may be used to endorse or promote products derived from this
19     software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.
32
33 */

34
35 package com.micronova.jsp.tag;
36
37 import javax.servlet.jsp.el.*;
38 import java.lang.reflect.*;
39 import java.util.*;
40 import com.micronova.util.*;
41
42 /** Codec Function Mapper for JSP2. Prefix "fn" is reserved for JSTL standard functions. Other codecs can be specified in one of the following ways:
43
44 CodecName:CodecMethod[_argSpec]
45
46 or
47
48 m:CodecName_CodecMethod[_argSpec]
49
50 The "argSpec" is either one of the following, if given:
51
52 min (default): method with min number of arguments
53 max: method with max number of arguments
54 integer: method with given number of arguments
55
56 */

57
58 public class CodecFunctionMapper implements FunctionMapper
59 {
60     protected static CodecFunctionMapper defaultCodecFunctionMapper;
61
62     protected static final String JavaDoc STANDARDFUNCTIONS = "org.apache.taglibs.standard.functions.Functions";
63     protected static Map standardFunctionsMap;
64
65     public static final String JavaDoc FIND_MIN = "min";
66     public static final String JavaDoc FIND_MAX = "max";
67
68     static
69     {
70         defaultCodecFunctionMapper = new CodecFunctionMapper();
71
72         try
73         {
74             standardFunctionsMap = new HashMap();
75
76             Method[] methods = Class.forName(STANDARDFUNCTIONS).getMethods();
77
78             for (int i = 0; i < methods.length; i ++)
79             {
80                 Method method = methods[i];
81
82                 standardFunctionsMap.put(method.getName(), method);
83             }
84         }
85         catch (Exception JavaDoc e)
86         {
87         }
88     }
89
90     protected static Method findMethodForName(Class JavaDoc classObject, String JavaDoc name, String JavaDoc findType)
91     {
92         Method[] methods = classObject.getMethods();
93
94         Method methodFound = null;
95         int methodFoundParamCount = 0;
96
97         for (int i = 0; i < methods.length; i ++)
98         {
99             Method method = methods[i];
100
101             if (name.equals(method.getName()))
102             {
103                 int paramCount = method.getParameterTypes().length;
104
105                 boolean isMatch = (methodFound == null);
106
107                 if (!isMatch)
108                 {
109                     if (FIND_MIN.equals(findType))
110                     {
111                         isMatch = (paramCount < methodFoundParamCount);
112                     }
113                     else if (FIND_MAX.equals(findType))
114                     {
115                         isMatch = (paramCount > methodFoundParamCount);
116                     }
117                 }
118                 
119                 if (isMatch)
120                 {
121                     methodFound = method;
122                     methodFoundParamCount = paramCount;
123                 }
124             }
125         }
126
127         return methodFound;
128     }
129
130
131     protected CodecFunctionMapper()
132     {
133         super();
134     }
135
136     public static FunctionMapper getInstance()
137     {
138         return defaultCodecFunctionMapper;
139     }
140
141     public Method resolveFunction(String JavaDoc prefix, String JavaDoc name)
142     {
143         try
144         {
145             // JSTL standard functions have "fn" prefix
146

147             if ("fn".equals(prefix))
148             {
149                 return (Method)standardFunctionsMap.get(name);
150             }
151
152             List namePartList = StringUtil.split(name, '_');
153             int namePartListSize = namePartList.size();
154
155             String JavaDoc codecName = prefix;
156             String JavaDoc codecMethod = name;
157             String JavaDoc argSpec = FIND_MIN;
158
159             if ("m".equals(prefix))
160             {
161                 codecName = (String JavaDoc)namePartList.get(0);
162                 codecMethod = (String JavaDoc)namePartList.get(1);
163                 
164                 if (namePartListSize > 2)
165                 {
166                     argSpec = (String JavaDoc)namePartList.get(2);
167                 }
168             }
169             else if (namePartListSize > 1)
170             {
171                 codecMethod = (String JavaDoc)namePartList.get(0);
172                 argSpec = (String JavaDoc)namePartList.get(1);
173             }
174
175             if (codecName.indexOf('.') < 0)
176             {
177                 codecName = EL.CODECPATH + codecName;
178             }
179
180             Class JavaDoc c = Class.forName(codecName);
181             
182             if (FIND_MAX.equals(argSpec) || FIND_MIN.equals(argSpec))
183             {
184                 return findMethodForName(c, codecMethod, argSpec);
185             }
186             else
187             {
188                 int numArgs = Integer.parseInt(argSpec);
189                 
190                 Class JavaDoc[] types = new Class JavaDoc[numArgs];
191             
192                 for (int i = numArgs; --i >=0;)
193                 {
194                     types[i] = Object JavaDoc.class;
195                 }
196                 
197                 return c.getDeclaredMethod(codecMethod, types);
198             }
199         }
200         catch (Exception JavaDoc e)
201         {
202             throw new RuntimeException JavaDoc(e);
203         }
204     }
205 }
206
Popular Tags