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 }