001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.webbeans.cfg;
031:
032: import com.caucho.config.*;
033: import com.caucho.config.j2ee.*;
034: import com.caucho.util.*;
035:
036: import java.lang.reflect.*;
037: import java.lang.annotation.*;
038: import java.util.ArrayList;
039:
040: import javax.annotation.*;
041: import javax.webbeans.*;
042:
043: /**
044: * Configuration for the xml web bean component.
045: */
046: public class WbBinding {
047: private static final L10N L = new L10N(WbBinding.class);
048:
049: private String _signature;
050: private Class _cl;
051:
052: private ArrayList<WbBindingValue> _valueList = new ArrayList<WbBindingValue>();
053:
054: public WbBinding() {
055: }
056:
057: public WbBinding(Annotation ann) {
058: setClass(ann.annotationType());
059:
060: try {
061: for (Method method : _cl.getDeclaredMethods()) {
062: if (method.isAnnotationPresent(NonBinding.class))
063: continue;
064:
065: Object value = method.invoke(ann);
066:
067: _valueList.add(new WbBindingValue(method, value));
068: }
069: } catch (RuntimeException e) {
070: throw e;
071: } catch (Exception e) {
072: throw ConfigException.create(e);
073: }
074: }
075:
076: public void addValue(WbBindingValue value) {
077: _valueList.add(value);
078: }
079:
080: public void addValue(String name, Object value) {
081: try {
082: Method method = _cl.getMethod(name, new Class[0]);
083: _valueList.add(new WbBindingValue(method, value));
084: } catch (Exception e) {
085: throw new ConfigException(L.l(
086: "{0}: '{1}' is an unknown method.", _cl
087: .getSimpleName(), name));
088: }
089: }
090:
091: public void setClass(Class cl) {
092: _cl = cl;
093: }
094:
095: public void setText(String signature) {
096: _signature = signature;
097: }
098:
099: public Class getBindingClass() {
100: return _cl;
101: }
102:
103: public String getClassName() {
104: if (_cl != null)
105: return _cl.getName();
106: else
107: return null;
108: }
109:
110: /**
111: * Returns the binding values
112: */
113: public ArrayList<WbBindingValue> getValueList() {
114: return _valueList;
115: }
116:
117: /**
118: * Parses the function signature.
119: */
120: @PostConstruct
121: public void init() throws ConfigException {
122: if (_signature == null)
123: throw new ConfigException(L
124: .l("binding requires an annotation"));
125:
126: int p = _signature.indexOf('(');
127:
128: String className;
129:
130: if (p > 0)
131: className = _signature.substring(0, p);
132: else
133: className = _signature;
134:
135: try {
136: ClassLoader loader = Thread.currentThread()
137: .getContextClassLoader();
138:
139: _cl = Class.forName(className, false, loader);
140: } catch (RuntimeException e) {
141: throw e;
142: } catch (Exception e) {
143: throw ConfigException.create(e);
144: }
145: }
146:
147: public boolean isMatch(Annotation bindAnn) {
148: if (!bindAnn.annotationType().equals(_cl))
149: return false;
150:
151: for (int i = 0; i < _valueList.size(); i++) {
152: if (!_valueList.get(i).isMatch(bindAnn))
153: return false;
154: }
155:
156: return true;
157: }
158:
159: public boolean isMatch(Binding bind) {
160: if (!_cl.equals(bind.getBindingClass()))
161: return false;
162:
163: for (int i = 0; i < _valueList.size(); i++) {
164: if (!_valueList.get(i).isMatch(bind))
165: return false;
166: }
167:
168: return true;
169: }
170:
171: public boolean isBindingPresent(ArrayList<Annotation> bindingList) {
172: for (int i = 0; i < bindingList.size(); i++) {
173: Annotation ann = bindingList.get(i);
174:
175: if (ann.annotationType().equals(_cl))
176: return true;
177: }
178:
179: return false;
180: }
181:
182: public long generateCrc64(long crc64) {
183: crc64 = Crc64.generate(crc64, _cl.getName());
184:
185: for (WbBindingValue value : _valueList) {
186: crc64 = Crc64.generate(crc64, value.getName());
187: crc64 = Crc64.generate(crc64, String.valueOf(value
188: .getValue()));
189: }
190:
191: return crc64;
192: }
193:
194: public boolean equals(Object o) {
195: if (this == o)
196: return true;
197: else if (!(o instanceof WbBinding))
198: return false;
199:
200: WbBinding binding = (WbBinding) o;
201:
202: if (!_cl.equals(binding._cl))
203: return false;
204:
205: int size = _valueList.size();
206: if (size != binding._valueList.size()) {
207: return false;
208: }
209:
210: for (int i = size - 1; i >= 0; i--) {
211: WbBindingValue value = _valueList.get(i);
212:
213: if (!binding._valueList.contains(value)) {
214: return false;
215: }
216: }
217:
218: return true;
219: }
220:
221: /**
222: * Converts to a binding object
223: */
224: public Binding toBinding() {
225: Binding binding = new Binding(_cl);
226:
227: for (WbBindingValue value : _valueList) {
228: binding.put(value.getName(), value.getValue());
229: }
230:
231: return binding;
232: }
233:
234: /**
235: * Converts to a string signature
236: */
237: public String toSignature() {
238: if (_signature == null) {
239: StringBuilder sb = new StringBuilder();
240: sb.append(_cl.getName());
241: sb.append("(");
242:
243: for (int i = 0; i < _valueList.size(); i++) {
244: WbBindingValue value = _valueList.get(i);
245:
246: if (value.getValue() == null)
247: continue;
248:
249: if (i != 0)
250: sb.append(",");
251:
252: sb.append(value.getName());
253: sb.append("=");
254:
255: addValue(sb, value.getValue());
256: }
257:
258: sb.append(")");
259:
260: _signature = sb.toString();
261: }
262:
263: return _signature;
264: }
265:
266: private void addValue(StringBuilder sb, Object value) {
267: if (value.getClass().isArray()) {
268: sb.append("{");
269: Object[] array = (Object[]) value;
270: for (int i = 0; i < array.length; i++) {
271: if (i != 0)
272: sb.append(",");
273:
274: addValue(sb, array[i]);
275: }
276: sb.append("}");
277: } else if (value instanceof String) {
278: String string = (String) value;
279:
280: sb.append("\"");
281:
282: for (int i = 0; i < string.length(); i++) {
283: char ch = string.charAt(i);
284:
285: switch (ch) {
286: case '\\':
287: sb.append("\\\\");
288: break;
289: case '\"':
290: sb.append("\\\"");
291: break;
292: default:
293: sb.append(ch);
294: break;
295: }
296: }
297:
298: sb.append("\"");
299: } else
300: sb.append(value);
301: }
302:
303: public String toDebugString() {
304: StringBuilder sb = new StringBuilder();
305: sb.append("@");
306: sb.append(_cl.getSimpleName());
307:
308: if (_valueList.size() == 0)
309: return sb.toString();
310:
311: sb.append("(");
312: for (int i = 0; i < _valueList.size(); i++) {
313: WbBindingValue value = _valueList.get(i);
314:
315: if (i != 0)
316: sb.append(",");
317:
318: if (!value.getName().equals("value")) {
319: sb.append(value.getName());
320: sb.append("=");
321: }
322:
323: Object objValue = value.getValue();
324:
325: if (objValue instanceof String) {
326: sb.append("\"");
327: sb.append(objValue);
328: sb.append("\"");
329: } else
330: sb.append(objValue);
331: }
332:
333: sb.append(")");
334:
335: return sb.toString();
336: }
337:
338: public String toString() {
339: return toDebugString();
340: }
341:
342: public static class WbBindingValue {
343: private Method _method;
344: private Object _value;
345:
346: WbBindingValue(Method method, Object value) {
347: _method = method;
348: _value = value;
349: }
350:
351: public String getName() {
352: return _method.getName();
353: }
354:
355: public Object getValue() {
356: return _value;
357: }
358:
359: boolean isMatch(Annotation ann) {
360: try {
361: Object value = _method.invoke(ann);
362:
363: if (value == _value)
364: return true;
365: else if (value == null)
366: return false;
367: else
368: return value.equals(_value);
369: } catch (RuntimeException e) {
370: throw e;
371: } catch (Exception e) {
372: throw ConfigException.create(e);
373: }
374: }
375:
376: boolean isMatch(Binding binding) {
377: String key = _method.getName();
378:
379: Object value = binding.get(key);
380:
381: if (value == _value)
382: return true;
383: else if (value == null)
384: return false;
385: else
386: return value.equals(_value);
387: }
388:
389: public boolean equals(Object o) {
390: if (this == o)
391: return true;
392: else if (!(o instanceof WbBindingValue))
393: return false;
394:
395: WbBindingValue value = (WbBindingValue) o;
396:
397: if (!_method.equals(value._method))
398: return false;
399: else if (_value == value._value)
400: return true;
401: else
402: return _value != null && _value.equals(value._value);
403: }
404:
405: public String toString() {
406: return "WbBinding[" + _method.getName() + ", " + _value
407: + "]";
408: }
409: }
410: }
|