001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.naming.deployment;
019
020 import java.lang.reflect.Field;
021 import java.lang.reflect.Method;
022 import java.util.List;
023 import java.util.Map;
024 import java.util.HashMap;
025
026 import javax.annotation.Resource;
027
028 import org.apache.commons.logging.Log;
029 import org.apache.commons.logging.LogFactory;
030 import org.apache.geronimo.common.DeploymentException;
031 import org.apache.geronimo.gbean.GBeanInfo;
032 import org.apache.geronimo.gbean.GBeanInfoBuilder;
033 import org.apache.geronimo.gbean.GBeanLifecycle;
034 import org.apache.geronimo.j2ee.deployment.Module;
035 import org.apache.geronimo.j2ee.deployment.annotation.AnnotatedApp;
036 import org.apache.geronimo.j2ee.deployment.annotation.ResourceAnnotationHelper;
037 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
038 import org.apache.geronimo.naming.reference.KernelReference;
039 import org.apache.geronimo.xbeans.javaee.DescriptionType;
040 import org.apache.geronimo.xbeans.javaee.EnvEntryType;
041 import org.apache.geronimo.xbeans.javaee.EnvEntryTypeValuesType;
042 import org.apache.geronimo.xbeans.javaee.InjectionTargetType;
043 import org.apache.geronimo.xbeans.javaee.JndiNameType;
044 import org.apache.geronimo.xbeans.javaee.XsdStringType;
045 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
046 import org.apache.xmlbeans.QNameSet;
047 import org.apache.xmlbeans.XmlObject;
048
049 /**
050 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
051 */
052 public class EnvironmentEntryBuilder extends AbstractNamingBuilder implements GBeanLifecycle {
053
054 private static final Log log = LogFactory.getLog(EnvironmentEntryBuilder.class);
055 private static final Map<String, String> NAMESPACE_UPDATES = new HashMap<String, String>();
056 static {
057 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/naming", "http://geronimo.apache.org/xml/ns/naming-1.2");
058 NAMESPACE_UPDATES.put("http://geronimo.apache.org/xml/ns/naming-1.1", "http://geronimo.apache.org/xml/ns/naming-1.2");
059 }
060
061 private final QNameSet envEntryQNameSet;
062
063 public EnvironmentEntryBuilder(String[] eeNamespaces) {
064 envEntryQNameSet = buildQNameSet(eeNamespaces, "env-entry");
065 }
066
067 public void doStart() throws Exception {
068 XmlBeansUtil.registerNamespaceUpdates(NAMESPACE_UPDATES);
069 }
070
071 public void doStop() {
072 XmlBeansUtil.unregisterNamespaceUpdates(NAMESPACE_UPDATES);
073 }
074
075 public void doFail() {
076 doStop();
077 }
078
079 public void buildNaming(XmlObject specDD, XmlObject plan, Module module, Map componentContext) throws DeploymentException {
080
081 // Discover and process any @Resource annotations (if !metadata-complete)
082 if ((module != null) && (module.getClassFinder() != null)) {
083
084 // Process all the annotations for this naming builder type
085 try {
086 ResourceAnnotationHelper.processAnnotations(module.getAnnotatedApp(), module.getClassFinder(), EnvEntryRefProcessor.INSTANCE);
087 }
088 catch (Exception e) {
089 log.warn("Unable to process @Resource annotations for module" + module.getName(), e);
090 }
091 }
092
093 List<EnvEntryType> envEntriesUntyped = convert(specDD.selectChildren(envEntryQNameSet), JEE_CONVERTER, EnvEntryType.class, EnvEntryType.type);
094 for (EnvEntryType envEntry: envEntriesUntyped) {
095 String name = getStringValue(envEntry.getEnvEntryName());
096 addInjections(name, envEntry.getInjectionTargetArray(), componentContext);
097 String type = getStringValue(envEntry.getEnvEntryType());
098 String text = getStringValue(envEntry.getEnvEntryValue());
099 try {
100 Object value;
101 if (text == null) {
102 if ("org.apache.geronimo.kernel.Kernel".equals(type)) {
103 value = new KernelReference();
104 } else {
105 value = null;
106 }
107 } else if ("java.lang.String".equals(type)) {
108 value = text;
109 } else if ("java.lang.Character".equals(type)) {
110 value = text.charAt(0);
111 } else if ("java.lang.Boolean".equals(type)) {
112 value = Boolean.valueOf(text);
113 } else if ("java.lang.Byte".equals(type)) {
114 value = Byte.valueOf(text);
115 } else if ("java.lang.Short".equals(type)) {
116 value = Short.valueOf(text);
117 } else if ("java.lang.Integer".equals(type)) {
118 value = Integer.valueOf(text);
119 } else if ("java.lang.Long".equals(type)) {
120 value = Long.valueOf(text);
121 } else if ("java.lang.Float".equals(type)) {
122 value = Float.valueOf(text);
123 } else if ("java.lang.Double".equals(type)) {
124 value = Double.valueOf(text);
125 } else {
126 throw new DeploymentException("unrecognized type: " + type);
127 }
128 getJndiContextMap(componentContext).put(ENV + name, value);
129 } catch (NumberFormatException e) {
130 throw new DeploymentException("Invalid env-entry value for name: " + name, e);
131 }
132 }
133
134 }
135
136 public QNameSet getSpecQNameSet() {
137 return envEntryQNameSet;
138 }
139
140 public QNameSet getPlanQNameSet() {
141 return QNameSet.EMPTY;
142 }
143
144 public static class EnvEntryRefProcessor extends ResourceAnnotationHelper.ResourceProcessor {
145
146 public static final EnvEntryRefProcessor INSTANCE = new EnvEntryRefProcessor();
147
148 private EnvEntryRefProcessor() {
149 }
150
151 public boolean processResource(AnnotatedApp annotatedApp, Resource annotation, Class cls, Method method, Field field) {
152 String resourceName = getResourceName(annotation, method, field);
153 String resourceType = getResourceType(annotation, method, field);
154 if (resourceType.equals("java.lang.String") ||
155 resourceType.equals("java.lang.Character") ||
156 resourceType.equals("java.lang.Integer") ||
157 resourceType.equals("java.lang.Boolean") ||
158 resourceType.equals("java.lang.Double") ||
159 resourceType.equals("java.lang.Byte") ||
160 resourceType.equals("java.lang.Short") ||
161 resourceType.equals("java.lang.Long") ||
162 resourceType.equals("java.lang.Float")) {
163
164 log.debug("addResource(): <env-entry> found");
165
166 boolean exists = false;
167 EnvEntryType[] envEntries = annotatedApp.getEnvEntryArray();
168 for (EnvEntryType envEntry : envEntries) {
169 if (getStringValue(envEntry.getEnvEntryName()).equals(resourceName)) {
170 exists = true;
171 if (method != null || field != null) {
172 InjectionTargetType[] targets = envEntry.getInjectionTargetArray();
173 if (!hasTarget(method, field, targets)) {
174 configureInjectionTarget(envEntry.addNewInjectionTarget(), method, field);
175 }
176 }
177 break;
178 }
179 }
180 if (!exists) {
181 try {
182
183 log.debug("addResource(): Does not exist in DD: " + resourceName);
184
185 // Doesn't exist in deployment descriptor -- add new
186 EnvEntryType envEntry = annotatedApp.addNewEnvEntry();
187
188 //------------------------------------------------------------------------------
189 // <env-entry> required elements:
190 //------------------------------------------------------------------------------
191
192 // env-entry-name
193 JndiNameType envEntryName = envEntry.addNewEnvEntryName();
194 envEntryName.setStringValue(resourceName);
195
196 if (!resourceType.equals("")) {
197 // env-entry-type
198 EnvEntryTypeValuesType envEntryType = envEntry.addNewEnvEntryType();
199 envEntryType.setStringValue(resourceType);
200 } else if (method != null || field != null) {
201 // injectionTarget
202 InjectionTargetType injectionTarget = envEntry.addNewInjectionTarget();
203 configureInjectionTarget(injectionTarget, method, field);
204 }
205
206 // env-entry-value
207 String mappdedNameAnnotation = annotation.mappedName();
208 if (!mappdedNameAnnotation.equals("")) {
209 XsdStringType value = envEntry.addNewEnvEntryValue();
210 value.setStringValue(mappdedNameAnnotation);
211 envEntry.setMappedName(value);
212 }
213
214 //------------------------------------------------------------------------------
215 // <env-entry> optional elements:
216 //------------------------------------------------------------------------------
217
218 // description
219 String descriptionAnnotation = annotation.description();
220 if (!descriptionAnnotation.equals("")) {
221 DescriptionType description = envEntry.addNewDescription();
222 description.setStringValue(descriptionAnnotation);
223 }
224
225 }
226 catch (Exception anyException) {
227 log.debug("ResourceAnnotationHelper: Exception caught while processing <env-entry>");
228 }
229 }
230 }
231 return false;
232 }
233 }
234
235 public static final GBeanInfo GBEAN_INFO;
236
237 static {
238 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(EnvironmentEntryBuilder.class, NameFactory.MODULE_BUILDER);
239 infoBuilder.addAttribute("eeNamespaces", String[].class, true, true);
240 infoBuilder.setConstructor(new String[] {"eeNamespaces"});
241
242 GBEAN_INFO = infoBuilder.getBeanInfo();
243 }
244
245 public static GBeanInfo getGBeanInfo() {
246 return GBEAN_INFO;
247 }
248
249 }