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    }