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    
025    import javax.annotation.Resource;
026    
027    import org.apache.commons.logging.Log;
028    import org.apache.commons.logging.LogFactory;
029    import org.apache.geronimo.common.DeploymentException;
030    import org.apache.geronimo.gbean.GBeanInfo;
031    import org.apache.geronimo.gbean.GBeanInfoBuilder;
032    import org.apache.geronimo.j2ee.deployment.Module;
033    import org.apache.geronimo.j2ee.deployment.annotation.AnnotatedApp;
034    import org.apache.geronimo.j2ee.deployment.annotation.ResourceAnnotationHelper;
035    import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
036    import org.apache.geronimo.naming.reference.KernelReference;
037    import org.apache.geronimo.xbeans.javaee.DescriptionType;
038    import org.apache.geronimo.xbeans.javaee.EnvEntryType;
039    import org.apache.geronimo.xbeans.javaee.EnvEntryTypeValuesType;
040    import org.apache.geronimo.xbeans.javaee.InjectionTargetType;
041    import org.apache.geronimo.xbeans.javaee.JndiNameType;
042    import org.apache.geronimo.xbeans.javaee.XsdStringType;
043    import org.apache.xmlbeans.QNameSet;
044    import org.apache.xmlbeans.XmlObject;
045    
046    /**
047     * @version $Rev: 566267 $ $Date: 2007-08-15 13:07:17 -0400 (Wed, 15 Aug 2007) $
048     */
049    public class EnvironmentEntryBuilder extends AbstractNamingBuilder {
050    
051        private static final Log log = LogFactory.getLog(EnvironmentEntryBuilder.class);
052    
053        private final QNameSet envEntryQNameSet;
054    
055        public EnvironmentEntryBuilder(String[] eeNamespaces) {
056            envEntryQNameSet = buildQNameSet(eeNamespaces, "env-entry");
057        }
058    
059        public void buildNaming(XmlObject specDD, XmlObject plan, Module module, Map componentContext) throws DeploymentException {
060    
061            // Discover and process any @Resource annotations (if !metadata-complete)
062            if ((module != null) && (module.getClassFinder() != null)) {
063    
064                // Process all the annotations for this naming builder type
065                try {
066                    ResourceAnnotationHelper.processAnnotations(module.getAnnotatedApp(), module.getClassFinder(), EnvEntryRefProcessor.INSTANCE);
067                }
068                catch (Exception e) {
069                    log.warn("Unable to process @Resource annotations for module" + module.getName(), e);
070                }
071            }
072    
073            List<EnvEntryType> envEntriesUntyped = convert(specDD.selectChildren(envEntryQNameSet), JEE_CONVERTER, EnvEntryType.class, EnvEntryType.type);
074            for (EnvEntryType envEntry: envEntriesUntyped) {
075                String name = getStringValue(envEntry.getEnvEntryName());
076                addInjections(name, envEntry.getInjectionTargetArray(), componentContext);
077                String type = getStringValue(envEntry.getEnvEntryType());
078                String text = getStringValue(envEntry.getEnvEntryValue());
079                try {
080                    Object value;
081                    if (text == null) {
082                        if ("org.apache.geronimo.kernel.Kernel".equals(type)) {
083                            value = new KernelReference();
084                        } else {
085                            value = null;
086                        }
087                    } else if ("java.lang.String".equals(type)) {
088                        value = text;
089                    } else if ("java.lang.Character".equals(type)) {
090                        value = text.charAt(0);
091                    } else if ("java.lang.Boolean".equals(type)) {
092                        value = Boolean.valueOf(text);
093                    } else if ("java.lang.Byte".equals(type)) {
094                        value = Byte.valueOf(text);
095                    } else if ("java.lang.Short".equals(type)) {
096                        value = Short.valueOf(text);
097                    } else if ("java.lang.Integer".equals(type)) {
098                        value = Integer.valueOf(text);
099                    } else if ("java.lang.Long".equals(type)) {
100                        value = Long.valueOf(text);
101                    } else if ("java.lang.Float".equals(type)) {
102                        value = Float.valueOf(text);
103                    } else if ("java.lang.Double".equals(type)) {
104                        value = Double.valueOf(text);
105                    } else {
106                        throw new DeploymentException("unrecognized type: " + type);
107                    }
108                    getJndiContextMap(componentContext).put(ENV + name, value);
109                } catch (NumberFormatException e) {
110                    throw new DeploymentException("Invalid env-entry value for name: " + name, e);
111                }
112            }
113    
114        }
115    
116        public QNameSet getSpecQNameSet() {
117            return envEntryQNameSet;
118        }
119    
120        public QNameSet getPlanQNameSet() {
121            return QNameSet.EMPTY;
122        }
123    
124        public static class EnvEntryRefProcessor extends ResourceAnnotationHelper.ResourceProcessor {
125    
126            public static final EnvEntryRefProcessor INSTANCE = new EnvEntryRefProcessor();
127    
128            private EnvEntryRefProcessor() {
129            }
130    
131            public boolean processResource(AnnotatedApp annotatedApp, Resource annotation, Class cls, Method method, Field field) {
132                String resourceName = getResourceName(annotation, method, field);
133                String resourceType = getResourceType(annotation, method, field);
134                if (resourceType.equals("java.lang.String") ||
135                        resourceType.equals("java.lang.Character") ||
136                        resourceType.equals("java.lang.Integer") ||
137                        resourceType.equals("java.lang.Boolean") ||
138                        resourceType.equals("java.lang.Double") ||
139                        resourceType.equals("java.lang.Byte") ||
140                        resourceType.equals("java.lang.Short") ||
141                        resourceType.equals("java.lang.Long") ||
142                        resourceType.equals("java.lang.Float")) {
143    
144                    log.debug("addResource(): <env-entry> found");
145    
146                    boolean exists = false;
147                    EnvEntryType[] envEntries = annotatedApp.getEnvEntryArray();
148                    for (EnvEntryType envEntry : envEntries) {
149                        if (getStringValue(envEntry.getEnvEntryName()).equals(resourceName)) {
150                            exists = true;
151                            if (method != null || field != null) {
152                                InjectionTargetType[] targets = envEntry.getInjectionTargetArray();
153                                if (!hasTarget(method, field, targets)) {
154                                    configureInjectionTarget(envEntry.addNewInjectionTarget(), method, field);
155                                }
156                            }
157                            break;
158                        }
159                    }
160                    if (!exists) {
161                        try {
162    
163                            log.debug("addResource(): Does not exist in DD: " + resourceName);
164    
165                            // Doesn't exist in deployment descriptor -- add new
166                            EnvEntryType envEntry = annotatedApp.addNewEnvEntry();
167    
168                            //------------------------------------------------------------------------------
169                            // <env-entry> required elements:
170                            //------------------------------------------------------------------------------
171    
172                            // env-entry-name
173                            JndiNameType envEntryName = envEntry.addNewEnvEntryName();
174                            envEntryName.setStringValue(resourceName);
175    
176                            if (!resourceType.equals("")) {
177                                // env-entry-type
178                                EnvEntryTypeValuesType envEntryType = envEntry.addNewEnvEntryType();
179                                envEntryType.setStringValue(resourceType);
180                            } else if (method != null || field != null) {
181                                // injectionTarget
182                                InjectionTargetType injectionTarget = envEntry.addNewInjectionTarget();
183                                configureInjectionTarget(injectionTarget, method, field);
184                            }
185    
186                            // env-entry-value
187                            String mappdedNameAnnotation = annotation.mappedName();
188                            if (!mappdedNameAnnotation.equals("")) {
189                                XsdStringType value = envEntry.addNewEnvEntryValue();
190                                value.setStringValue(mappdedNameAnnotation);
191                                envEntry.setMappedName(value);
192                            }
193    
194                            //------------------------------------------------------------------------------
195                            // <env-entry> optional elements:
196                            //------------------------------------------------------------------------------
197    
198                            // description
199                            String descriptionAnnotation = annotation.description();
200                            if (!descriptionAnnotation.equals("")) {
201                                DescriptionType description = envEntry.addNewDescription();
202                                description.setStringValue(descriptionAnnotation);
203                            }
204    
205                        }
206                        catch (Exception anyException) {
207                            log.debug("ResourceAnnotationHelper: Exception caught while processing <env-entry>");
208                        }
209                    }
210                }
211                return false;
212            }
213        }
214    
215        public static final GBeanInfo GBEAN_INFO;
216    
217        static {
218            GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(EnvironmentEntryBuilder.class, NameFactory.MODULE_BUILDER);
219            infoBuilder.addAttribute("eeNamespaces", String[].class, true, true);
220            infoBuilder.setConstructor(new String[] {"eeNamespaces"});
221    
222            GBEAN_INFO = infoBuilder.getBeanInfo();
223        }
224    
225        public static GBeanInfo getGBeanInfo() {
226            return GBEAN_INFO;
227        }
228    
229    }