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.component;
031:
032: import com.caucho.config.*;
033: import com.caucho.config.j2ee.*;
034: import com.caucho.config.types.*;
035: import com.caucho.util.*;
036: import com.caucho.webbeans.*;
037: import com.caucho.webbeans.cfg.*;
038: import com.caucho.webbeans.context.*;
039: import com.caucho.webbeans.manager.WebBeansContainer;
040:
041: import java.lang.reflect.*;
042: import java.lang.annotation.*;
043: import java.util.ArrayList;
044:
045: import javax.annotation.*;
046: import javax.webbeans.*;
047:
048: /**
049: * Configuration for a @Produces method
050: */
051: public class ProducesComponent extends ComponentImpl {
052: private static final L10N L = new L10N(ProducesComponent.class);
053:
054: private static final Object[] NULL_ARGS = new Object[0];
055: private final ComponentImpl _producer;
056: private final Method _method;
057:
058: private ComponentImpl[] _args;
059:
060: private boolean _isBound;
061:
062: public ProducesComponent(WbWebBeans webbeans,
063: ComponentImpl producer, Method method) {
064: super (webbeans);
065:
066: _producer = producer;
067: _method = method;
068:
069: setTargetType(method.getGenericReturnType());
070: }
071:
072: /**
073: * Initialization.
074: */
075: public void init() {
076: super .init();
077: }
078:
079: public void introspect() {
080: ArrayList<WbBinding> bindingList = new ArrayList<WbBinding>();
081:
082: for (Annotation ann : _method.getAnnotations()) {
083: if (ann instanceof Named) {
084: setName(((Named) ann).value());
085: }
086:
087: if (ann.annotationType().isAnnotationPresent(
088: ComponentType.class)) {
089: if (getType() == null)
090: setType(_webbeans.createComponentType(ann
091: .annotationType()));
092: }
093:
094: if (ann.annotationType().isAnnotationPresent(
095: ScopeType.class)) {
096: if (getScope() == null)
097: setScope(_webbeans.getScopeContext(ann
098: .annotationType()));
099: }
100:
101: if (ann.annotationType().isAnnotationPresent(
102: BindingType.class)) {
103: bindingList.add(new WbBinding(ann));
104: }
105: }
106:
107: if (getName() == null) {
108: String methodName = _method.getName();
109:
110: if (methodName.startsWith("get") && methodName.length() > 3) {
111: setName(Character.toLowerCase(methodName.charAt(3))
112: + methodName.substring(4));
113: } else
114: setName(methodName);
115: }
116:
117: if (bindingList.size() > 0)
118: setBindingList(bindingList);
119:
120: if (getType() == null)
121: setType(_producer.getType());
122: }
123:
124: @Override
125: public Object createNew(ConfigContext env) {
126: try {
127: Object factory = _producer.get();
128:
129: if (_args == null)
130: bind();
131:
132: Object[] args;
133: if (_args.length > 0) {
134: args = new Object[_args.length];
135:
136: for (int i = 0; i < args.length; i++)
137: args[i] = _args[i].get();
138: } else
139: args = NULL_ARGS;
140:
141: Object value = _method.invoke(factory, args);
142:
143: if (env != null)
144: env.put(this , value);
145:
146: return value;
147: } catch (RuntimeException e) {
148: throw e;
149: } catch (Exception e) {
150: throw new RuntimeException(e);
151: }
152: }
153:
154: @Override
155: public void bind() {
156: synchronized (this ) {
157: if (_isBound)
158: return;
159:
160: _isBound = true;
161:
162: String loc = WebBeansContainer.location(_method);
163:
164: Type[] param = _method.getGenericParameterTypes();
165: Annotation[][] paramAnn = _method.getParameterAnnotations();
166:
167: _args = new ComponentImpl[param.length];
168:
169: for (int i = 0; i < param.length; i++) {
170: _args[i] = _webbeans.bindParameter(loc, param[i],
171: paramAnn[i]);
172:
173: if (_args[i] == null)
174: throw error(
175: _method,
176: L
177: .l(
178: "Type '{0}' for method parameter #{1} has no matching component.",
179: getSimpleName(param[i]), i));
180: }
181: }
182: }
183:
184: public String toString() {
185: StringBuilder sb = new StringBuilder();
186:
187: sb.append(getClass().getSimpleName());
188: sb.append("[");
189:
190: if (getName() != null) {
191: sb.append("name=");
192: sb.append(getName());
193: sb.append(", ");
194: }
195:
196: sb.append(getTargetSimpleName());
197: sb.append(", ");
198: sb.append(_method.getDeclaringClass().getSimpleName());
199: sb.append(".");
200: sb.append(_method.getName());
201: sb.append("(), @");
202: sb.append(getType().getType().getSimpleName());
203: sb.append("]");
204:
205: return sb.toString();
206: }
207: }
|