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.event;
031:
032: import java.util.*;
033: import java.lang.annotation.*;
034: import java.lang.reflect.*;
035: import javax.webbeans.*;
036:
037: import com.caucho.config.*;
038: import com.caucho.util.*;
039: import com.caucho.webbeans.cfg.*;
040: import com.caucho.webbeans.component.*;
041: import com.caucho.webbeans.manager.*;
042:
043: /**
044: * Implements a single observer.
045: */
046: public class ObserverImpl {
047: private static final L10N L = new L10N(ObserverImpl.class);
048:
049: private static final Object[] NULL_ARGS = new Object[0];
050:
051: private final ComponentImpl _component;
052:
053: private final Method _method;
054: private final int _paramIndex;
055:
056: private boolean _hasBinding;
057: private boolean _ifExists;
058:
059: private ComponentImpl[] _args;
060:
061: private ArrayList<WbBinding> _bindingList = new ArrayList<WbBinding>();
062:
063: public ObserverImpl(ComponentImpl comp, Method method,
064: int paramIndex) {
065: _component = comp;
066: _method = method;
067: _method.setAccessible(true);
068: _paramIndex = paramIndex;
069:
070: for (Annotation ann : method.getParameterAnnotations()[paramIndex]) {
071: if (ann instanceof IfExists)
072: _ifExists = true;
073: }
074:
075: bind();
076: }
077:
078: public Class getType() {
079: return _method.getParameterTypes()[_paramIndex];
080: }
081:
082: /**
083: * Adds a component binding.
084: */
085: public void setBindingList(ArrayList<WbBinding> bindingList) {
086: _bindingList = bindingList;
087: }
088:
089: public ArrayList<WbBinding> getBindingList() {
090: return _bindingList;
091: }
092:
093: /**
094: * Initialization.
095: */
096: public void init() {
097: // _webbeans.addWbComponent(this);
098:
099: /*
100: if (_name == null) {
101: Named named = (Named) _cl.getAnnotation(Named.class);
102:
103: if (named != null)
104: _name = named.value();
105:
106: if (_name == null || "".equals(_name)) {
107: String className = _targetType.getName();
108: int p = className.lastIndexOf('.');
109:
110: char ch = Character.toLowerCase(className.charAt(p + 1));
111:
112: _name = ch + className.substring(p + 2);
113: }
114: }
115: */
116: }
117:
118: public void bind() {
119: synchronized (this ) {
120: if (_args != null)
121: return;
122:
123: Type[] param = _method.getGenericParameterTypes();
124: Annotation[][] annList = _method.getParameterAnnotations();
125:
126: _args = new ComponentImpl[param.length];
127:
128: WebBeansContainer webBeans = _component.getWebBeans()
129: .getContainer();
130: String loc = LineConfigException.loc(_method);
131:
132: for (int i = 0; i < param.length; i++) {
133: if (hasObserves(annList[i]))
134: continue;
135:
136: ComponentImpl comp = webBeans.bind(loc, param[i],
137: annList[i]);
138:
139: if (comp == null) {
140: throw new ConfigException(
141: loc
142: + L
143: .l(
144: "Parameter '{0}' binding does not have a matching component",
145: getSimpleName(param[i])));
146: }
147:
148: _args[i] = comp;
149: }
150: }
151: }
152:
153: private boolean hasObserves(Annotation[] annList) {
154: for (Annotation ann : annList) {
155: if (ann instanceof Observes)
156: return true;
157: }
158:
159: return false;
160: }
161:
162: public boolean isMatch(Annotation[] bindList) {
163: int size = _bindingList.size();
164:
165: if (bindList.length < size)
166: return false;
167:
168: for (int i = 0; i < size; i++) {
169: WbBinding binding = _bindingList.get(i);
170:
171: boolean isMatch = false;
172: for (Annotation ann : bindList) {
173: if (binding.isMatch(ann)) {
174: isMatch = true;
175: break;
176: }
177: }
178:
179: if (!isMatch)
180: return false;
181: }
182:
183: return true;
184: }
185:
186: public void raiseEvent(Object event) {
187: Object obj;
188:
189: if (_ifExists)
190: obj = _component.getIfExists();
191: else
192: obj = _component.get();
193:
194: try {
195: if (obj != null) {
196: Object[] args = new Object[_args.length];
197:
198: for (int i = 0; i < _args.length; i++) {
199: ComponentImpl comp = _args[i];
200:
201: if (comp != null)
202: args[i] = comp.get();
203: else
204: args[i] = event;
205: }
206:
207: _method.invoke(obj, args);
208: }
209: } catch (RuntimeException e) {
210: throw e;
211: } catch (InvocationTargetException e) {
212: throw new RuntimeException(e.getCause());
213: } catch (Exception e) {
214: throw new RuntimeException(e);
215: }
216: }
217:
218: public boolean equals(Object obj) {
219: if (this == obj)
220: return true;
221: else if (!(obj instanceof ObserverImpl))
222: return false;
223:
224: ObserverImpl comp = (ObserverImpl) obj;
225:
226: if (!_component.equals(comp._component)) {
227: return false;
228: }
229:
230: int size = _bindingList.size();
231:
232: if (size != comp._bindingList.size()) {
233: return false;
234: }
235:
236: for (int i = size - 1; i >= 0; i--) {
237: if (!comp._bindingList.contains(_bindingList.get(i))) {
238: return false;
239: }
240: }
241:
242: return true;
243: }
244:
245: public String toString() {
246: StringBuilder sb = new StringBuilder();
247:
248: sb.append(_method.getDeclaringClass().getSimpleName());
249: sb.append(".");
250: sb.append(_method.getName());
251: sb.append("[");
252:
253: ComponentImpl comp = _component;
254: sb.append(comp.getTargetSimpleName());
255: sb.append("]");
256:
257: return sb.toString();
258: }
259:
260: protected static String getSimpleName(Type type) {
261: if (type instanceof Class)
262: return ((Class) type).getSimpleName();
263: else
264: return String.valueOf(type);
265: }
266: }
|