| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.openejb.config; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.openejb.OpenEJBException; |
| import org.apache.openejb.jee.EjbJar; |
| import org.apache.openejb.jee.EnterpriseBean; |
| import org.apache.openejb.jee.EnvEntry; |
| import org.apache.openejb.jee.InjectionTarget; |
| import org.apache.openejb.jee.JndiConsumer; |
| |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Method; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Set; |
| |
| /** |
| * @version $Rev$ $Date$ |
| */ |
| public class CleanEnvEntries implements DynamicDeployer { |
| |
| @Override |
| public AppModule deploy(AppModule appModule) throws OpenEJBException { |
| |
| // Any EnvEntry types missing the <value> and having no <lookup> should be removed |
| appModule = removeUnsetEnvEntries(appModule); |
| |
| // Any EnvEntry types having the <value> but missing the type should have the type implied |
| // based on the injection points |
| appModule = fillInMissingType(appModule); |
| |
| return appModule; |
| } |
| |
| public AppModule removeUnsetEnvEntries(AppModule appModule) throws OpenEJBException { |
| |
| for (ClientModule module : appModule.getClientModules()) { |
| final JndiConsumer consumer = module.getApplicationClient(); |
| if (consumer == null) continue; |
| |
| removeUnsetEnvEntries(consumer); |
| } |
| |
| for (WebModule module : appModule.getWebModules()) { |
| final JndiConsumer consumer = module.getWebApp(); |
| if (consumer == null) continue; |
| |
| removeUnsetEnvEntries(consumer); |
| } |
| |
| for (EjbModule module : appModule.getEjbModules()) { |
| final EjbJar ejbJar = module.getEjbJar(); |
| if (ejbJar == null) continue; |
| |
| for (EnterpriseBean consumer : ejbJar.getEnterpriseBeans()) { |
| removeUnsetEnvEntries(consumer); |
| } |
| } |
| |
| return appModule; |
| } |
| |
| private void removeUnsetEnvEntries(JndiConsumer consumer) { |
| final Iterator<EnvEntry> entries = consumer.getEnvEntry().iterator(); |
| while (entries.hasNext()) { |
| final EnvEntry entry = entries.next(); |
| if (entry.getEnvEntryValue() != null) continue; |
| if (entry.getLookupName() != null) continue; |
| |
| entries.remove(); |
| } |
| } |
| |
| |
| public AppModule fillInMissingType(AppModule appModule) throws OpenEJBException { |
| |
| for (ClientModule module : appModule.getClientModules()) { |
| final JndiConsumer consumer = module.getApplicationClient(); |
| if (consumer == null) continue; |
| |
| fillInMissingType(consumer, module); |
| } |
| |
| for (WebModule module : appModule.getWebModules()) { |
| final JndiConsumer consumer = module.getWebApp(); |
| if (consumer == null) continue; |
| |
| fillInMissingType(consumer, module); |
| } |
| |
| for (EjbModule module : appModule.getEjbModules()) { |
| final EjbJar ejbJar = module.getEjbJar(); |
| if (ejbJar == null) continue; |
| |
| for (EnterpriseBean consumer : ejbJar.getEnterpriseBeans()) { |
| fillInMissingType(consumer, module); |
| } |
| } |
| |
| return appModule; |
| } |
| |
| private void fillInMissingType(JndiConsumer consumer, DeploymentModule module) { |
| final ClassLoader loader = module.getClassLoader(); |
| |
| for (EnvEntry entry : consumer.getEnvEntry()) { |
| fillInMissingType(loader, entry); |
| } |
| |
| } |
| |
| private void fillInMissingType(ClassLoader loader, EnvEntry entry) { |
| if (entry.getType() != null) return; |
| |
| // If it has the lookup supplied we don't care if there is no type |
| if (entry.getLookupName() != null) return; |
| |
| // We can't imply type without at least one injection point |
| if (entry.getInjectionTarget().size() == 0) return; |
| |
| final Set<Class> types = new HashSet<Class>(); |
| |
| for (InjectionTarget target : entry.getInjectionTarget()) { |
| if (target.getInjectionTargetClass() == null) continue; |
| if (target.getInjectionTargetName() == null) continue; |
| |
| types.add(getType(loader, target)); |
| } |
| |
| normalize(types); |
| |
| final Class<?> type = (types.size() == 1) ? types.iterator().next() : String.class; |
| |
| entry.setType(type.getName()); |
| } |
| |
| private void normalize(Set<Class> types) { |
| types.remove(Object.class); |
| |
| if (types.contains(int.class)) { |
| types.remove(int.class); |
| types.add(Integer.class); |
| } |
| |
| if (types.contains(char.class)) { |
| types.remove(char.class); |
| types.add(Character.class); |
| } |
| |
| if (types.contains(short.class)) { |
| types.remove(short.class); |
| types.add(Short.class); |
| } |
| |
| if (types.contains(long.class)) { |
| types.remove(long.class); |
| types.add(Long.class); |
| } |
| |
| if (types.contains(float.class)) { |
| types.remove(float.class); |
| types.add(Float.class); |
| } |
| |
| if (types.contains(double.class)) { |
| types.remove(double.class); |
| types.add(Double.class); |
| } |
| |
| if (types.contains(boolean.class)) { |
| types.remove(boolean.class); |
| types.add(Boolean.class); |
| } |
| |
| if (types.contains(byte.class)) { |
| types.remove(byte.class); |
| types.add(Byte.class); |
| } |
| |
| } |
| |
| private Class<?> getType(ClassLoader loader, InjectionTarget target) { |
| try { |
| final Class<?> clazz = loader.loadClass(target.getInjectionTargetClass()); |
| |
| try { |
| final Field field = clazz.getDeclaredField(target.getInjectionTargetName()); |
| return field.getType(); |
| } catch (NoSuchFieldException e) { |
| } |
| |
| // TODO Technically we should match by case |
| final String bestName = "set" + StringUtils.capitalize(target.getInjectionTargetName()); |
| final String name = "set" + target.getInjectionTargetName().toLowerCase(); |
| Class<?> found = null; |
| for (Method method : clazz.getDeclaredMethods()) { |
| if (method.getParameterTypes().length == 1) { |
| if (method.getName().equals(bestName)) { |
| return method.getParameterTypes()[0]; |
| } else if (method.getName().toLowerCase().equals(name)) { |
| found = method.getParameterTypes()[0]; |
| } |
| } |
| } |
| |
| if (found != null) { |
| return found; |
| } |
| |
| } catch (Throwable e) { |
| } |
| |
| return Object.class; |
| } |
| |
| |
| } |