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.el;
20  
21  import java.io.Externalizable;
22  import java.io.IOException;
23  import java.io.ObjectInput;
24  import java.io.ObjectOutput;
25  import java.lang.reflect.Method;
26  import java.util.HashMap;
27  import java.util.Map;
28  
29  import javax.el.FunctionMapper;
30  
31  import org.apache.myfaces.view.facelets.util.ReflectionUtil;
32  
33  /**
34   * Default implementation of the FunctionMapper
35   * 
36   * @see java.lang.reflect.Method
37   * @see javax.el.FunctionMapper
38   * 
39   * @author Jacob Hookom
40   * @version $Id$
41   */
42  public final class DefaultFunctionMapper extends FunctionMapper implements Externalizable
43  {
44      private static final long serialVersionUID = 1L;
45  
46      private Map<String, Function> _functions = null;
47  
48      /*
49       * (non-Javadoc)
50       * 
51       * @see javax.el.FunctionMapper#resolveFunction(java.lang.String, java.lang.String)
52       */
53      public Method resolveFunction(String prefix, String localName)
54      {
55          if (_functions != null)
56          {
57              Function f = (Function) _functions.get(prefix + ":" + localName);
58              return f.getMethod();
59          }
60          
61          return null;
62      }
63  
64      public void addFunction(String prefix, String localName, Method m)
65      {
66          if (_functions == null)
67          {
68              _functions = new HashMap<String, Function>();
69          }
70          
71          Function f = new Function(prefix, localName, m);
72          synchronized (this)
73          {
74              _functions.put(prefix + ":" + localName, f);
75          }
76      }
77  
78      /*
79       * (non-Javadoc)
80       * 
81       * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
82       */
83      public void writeExternal(ObjectOutput out) throws IOException
84      {
85          out.writeObject(_functions);
86      }
87  
88      /*
89       * (non-Javadoc)
90       * 
91       * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
92       */
93      @SuppressWarnings("unchecked")
94      public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
95      {
96          _functions = (Map<String, Function>) in.readObject();
97      }
98  
99      @Override
100     public String toString()
101     {
102         StringBuffer sb = new StringBuffer(128);
103         sb.append("FunctionMapper[\n");
104         for (Function function : _functions.values())
105         {
106             sb.append(function).append('\n');
107         }
108         sb.append(']');
109         
110         return sb.toString();
111     }
112 
113     private static class Function implements Externalizable
114     {
115         private static final long serialVersionUID = 1L;
116 
117         protected transient Method _m;
118 
119         protected String _owner;
120 
121         protected String _name;
122 
123         protected String[] _types;
124 
125         protected String _prefix;
126 
127         protected String _localName;
128 
129         /**
130          * 
131          */
132         public Function(String prefix, String localName, Method m)
133         {
134             if (localName == null)
135             {
136                 throw new NullPointerException("LocalName cannot be null");
137             }
138             if (m == null)
139             {
140                 throw new NullPointerException("Method cannot be null");
141             }
142             
143             _prefix = prefix;
144             _localName = localName;
145             _m = m;
146         }
147 
148         public Function()
149         {
150             // for serialization
151         }
152 
153         /*
154          * (non-Javadoc)
155          * 
156          * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
157          */
158         public void writeExternal(ObjectOutput out) throws IOException
159         {
160             out.writeUTF(_prefix != null ? _prefix : "");
161             out.writeUTF(_localName);
162             out.writeUTF(_m.getDeclaringClass().getName());
163             out.writeUTF(_m.getName());
164             out.writeObject(ReflectionUtil.toTypeNameArray(this._m.getParameterTypes()));
165         }
166 
167         /*
168          * (non-Javadoc)
169          * 
170          * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
171          */
172         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
173         {
174             _prefix = in.readUTF();
175             if ("".equals(_prefix))
176             {
177                 _prefix = null;
178             }
179             
180             _localName = in.readUTF();
181             _owner = in.readUTF();
182             _name = in.readUTF();
183             _types = (String[]) in.readObject();
184         }
185 
186         public Method getMethod()
187         {
188             if (_m == null)
189             {
190                 try
191                 {
192                     Class<?> t = ReflectionUtil.forName(_owner);
193                     Class<?>[] p = ReflectionUtil.toTypeArray(_types);
194                     _m = t.getMethod(_name, p);
195                 }
196                 catch (Exception e)
197                 {
198                     e.printStackTrace();
199                 }
200             }
201             
202             return _m;
203         }
204 
205         public boolean matches(String prefix, String localName)
206         {
207             if (_prefix != null)
208             {
209                 if (prefix == null)
210                 {
211                     return false;
212                 }
213                 if (!_prefix.equals(prefix))
214                 {
215                     return false;
216                 }
217             }
218             
219             return _localName.equals(localName);
220         }
221 
222         /*
223          * (non-Javadoc)
224          * 
225          * @see java.lang.Object#equals(java.lang.Object)
226          */
227         @Override
228         public boolean equals(Object obj)
229         {
230             if (obj instanceof Function)
231             {
232                 return hashCode() == obj.hashCode();
233             }
234             
235             return false;
236         }
237 
238         /*
239          * (non-Javadoc)
240          * 
241          * @see java.lang.Object#hashCode()
242          */
243         @Override
244         public int hashCode()
245         {
246             return (_prefix + _localName).hashCode();
247         }
248 
249         @Override
250         public String toString()
251         {
252             StringBuffer sb = new StringBuffer(32);
253             sb.append("Function[");
254             if (_prefix != null)
255             {
256                 sb.append(_prefix).append(':');
257             }
258             sb.append(_name).append("] ");
259             sb.append(_m);
260             
261             return sb.toString();
262         }
263     }
264 }