PageRenderTime 87ms CodeModel.GetById 30ms app.highlight 39ms RepoModel.GetById 2ms app.codeStats 1ms

/jboss-as-7.1.1.Final/web/src/main/java/org/jboss/as/web/deployment/component/WebComponentProcessor.java

#
Java | 223 lines | 154 code | 17 blank | 52 comment | 59 complexity | da770451c7eea04dd11758cdc1c39b49 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1/*
  2 * JBoss, Home of Professional Open Source.
  3 * Copyright 2011, Red Hat, Inc., and individual contributors
  4 * as indicated by the @author tags. See the copyright.txt file in the
  5 * distribution for a full listing of individual contributors.
  6 *
  7 * This is free software; you can redistribute it and/or modify it
  8 * under the terms of the GNU Lesser General Public License as
  9 * published by the Free Software Foundation; either version 2.1 of
 10 * the License, or (at your option) any later version.
 11 *
 12 * This software is distributed in the hope that it will be useful,
 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 15 * Lesser General Public License for more details.
 16 *
 17 * You should have received a copy of the GNU Lesser General Public
 18 * License along with this software; if not, write to the Free
 19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 21 */
 22
 23package org.jboss.as.web.deployment.component;
 24
 25import static org.jboss.as.web.WebMessages.MESSAGES;
 26
 27import org.jboss.as.ee.component.Attachments;
 28import org.jboss.as.ee.component.ComponentDescription;
 29import org.jboss.as.ee.component.EEApplicationClasses;
 30import org.jboss.as.ee.component.EEModuleDescription;
 31import org.jboss.as.ee.structure.DeploymentType;
 32import org.jboss.as.ee.structure.DeploymentTypeMarker;
 33import org.jboss.as.server.deployment.DeploymentPhaseContext;
 34import org.jboss.as.server.deployment.DeploymentUnit;
 35import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
 36import org.jboss.as.server.deployment.DeploymentUnitProcessor;
 37import org.jboss.as.server.deployment.annotation.CompositeIndex;
 38import org.jboss.as.web.deployment.TldsMetaData;
 39import org.jboss.as.web.deployment.WarMetaData;
 40import org.jboss.as.web.deployment.WebAttachments;
 41import org.jboss.jandex.ClassInfo;
 42import org.jboss.jandex.DotName;
 43import org.jboss.metadata.web.spec.FilterMetaData;
 44import org.jboss.metadata.web.spec.ListenerMetaData;
 45import org.jboss.metadata.web.spec.ServletMetaData;
 46import org.jboss.metadata.web.spec.TagMetaData;
 47import org.jboss.metadata.web.spec.TldMetaData;
 48import org.jboss.metadata.web.spec.WebCommonMetaData;
 49import org.jboss.metadata.web.spec.WebFragmentMetaData;
 50import org.jboss.metadata.web.spec.WebMetaData;
 51
 52import java.util.HashMap;
 53import java.util.HashSet;
 54import java.util.Map;
 55import java.util.Set;
 56
 57import javax.servlet.AsyncListener;
 58
 59/**
 60 * Processor that figures out what type of component a servlet/listener is, and registers the appropriate metadata.
 61 * The different types are:
 62 * <ul>
 63 * <li>Managed Bean - If the servlet is annotated with the <code>ManagedBean</code> annotation</li>
 64 * <li>CDI Bean - If the servlet is deployed in a bean archive</li>
 65 * <li>EE Component - If this is an EE deployment and the servlet is not one of the above</li>
 66 * <li>Normal Servlet - If the EE subsystem is disabled</li>
 67 * </ul>
 68 * <p/>
 69 * For ManagedBean Servlets no action is necessary at this stage, as the servlet is already registered as a component.
 70 * For CDI and EE components a component definition is added to the deployment.
 71 * <p/>
 72 * For now we are just using managed bean components as servlets. We may need a custom component type in future.
 73 */
 74public class WebComponentProcessor implements DeploymentUnitProcessor {
 75
 76    /**
 77     * Tags in these packages do not need to be computerized
 78     */
 79    private static final String[] BUILTIN_TAGLIBS = {"org.apache.taglibs.standard", "com.sun.faces.taglib.jsf_core",  "com.sun.faces.ext.taglib", "com.sun.faces.taglib.html_basic",};
 80
 81    /**
 82     * Dotname for AsyncListener, which can be injected dynamically.
 83     */
 84    private static final DotName ASYNC_LISTENER_INTERFACE = DotName.createSimple(AsyncListener.class.getName());
 85
 86    @Override
 87    public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
 88        final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
 89
 90        if (!DeploymentTypeMarker.isType(DeploymentType.WAR, deploymentUnit)) {
 91            return;
 92        }
 93
 94        final Map<String, ComponentDescription> componentByClass = new HashMap<String, ComponentDescription>();
 95        final Map<String, ComponentInstantiator> webComponents = new HashMap<String, ComponentInstantiator>();
 96        final EEModuleDescription moduleDescription = deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION);
 97        final EEApplicationClasses applicationClassesDescription = deploymentUnit.getAttachment(Attachments.EE_APPLICATION_CLASSES_DESCRIPTION);
 98        final CompositeIndex compositeIndex = deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.COMPOSITE_ANNOTATION_INDEX);
 99        final String applicationName = deploymentUnit.getParent() == null ? deploymentUnit.getName() : deploymentUnit.getParent().getName();
100        if (moduleDescription == null) {
101            return; //not an ee deployment
102        }
103        for (ComponentDescription component : moduleDescription.getComponentDescriptions()) {
104            componentByClass.put(component.getComponentClassName(), component);
105        }
106
107        final WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY);
108        final TldsMetaData tldsMetaData = deploymentUnit.getAttachment(TldsMetaData.ATTACHMENT_KEY);
109        final Set<String> classes = getAllComponentClasses(deploymentUnit, compositeIndex, warMetaData, tldsMetaData);
110        for (String clazz : classes) {
111            if (clazz == null || clazz.trim().isEmpty()) {
112                continue;
113            }
114            ComponentDescription description = componentByClass.get(clazz);
115            if (description != null) {
116                //for now just make sure it has a single view
117                //this will generally be a managed bean, but it could also be an EJB
118                //TODO: make sure the component is a managed bean
119                if (!(description.getViews().size() == 1)) {
120                    throw MESSAGES.wrongComponentType(clazz);
121                }
122                ManagedBeanComponentInstantiator instantiator = new ManagedBeanComponentInstantiator(deploymentUnit, description);
123                webComponents.put(clazz, instantiator);
124            } else {
125                //we do not make the standard tags into components, as there is no need
126                if (compositeIndex.getClassByName(DotName.createSimple(clazz)) == null) {
127                    boolean found = false;
128                    for (String pack : BUILTIN_TAGLIBS) {
129                        if (clazz.startsWith(pack)) {
130                            found = true;
131                            break;
132                        }
133                    }
134                    if(found) {
135                        continue;
136                    }
137                }
138                description = new WebComponentDescription(clazz, clazz, moduleDescription, deploymentUnit.getServiceName(), applicationClassesDescription);
139                moduleDescription.addComponent(description);
140                webComponents.put(clazz, new WebComponentInstantiator(deploymentUnit, description));
141            }
142        }
143        deploymentUnit.putAttachment(WebAttachments.WEB_COMPONENT_INSTANTIATORS, webComponents);
144    }
145
146    @Override
147    public void undeploy(DeploymentUnit context) {
148    }
149
150    /**
151     * Gets all classes that are eligible for injection etc
152     *
153     * @param metaData
154     * @return
155     */
156    private Set<String> getAllComponentClasses(DeploymentUnit deploymentUnit, CompositeIndex index, WarMetaData metaData, TldsMetaData tldsMetaData) {
157        final Set<String> classes = new HashSet<String>();
158        if (metaData.getAnnotationsMetaData() != null)
159            for (Map.Entry<String, WebMetaData> webMetaData : metaData.getAnnotationsMetaData().entrySet()) {
160                getAllComponentClasses(webMetaData.getValue(), classes);
161            }
162        if (metaData.getSharedWebMetaData() != null)
163            getAllComponentClasses(metaData.getSharedWebMetaData(), classes);
164        if (metaData.getWebFragmentsMetaData() != null)
165            for (Map.Entry<String, WebFragmentMetaData> webMetaData : metaData.getWebFragmentsMetaData().entrySet()) {
166                getAllComponentClasses(webMetaData.getValue(), classes);
167            }
168        if (metaData.getWebMetaData() != null)
169            getAllComponentClasses(metaData.getWebMetaData(), classes);
170        if (tldsMetaData == null)
171            return classes;
172        if (tldsMetaData.getSharedTlds(deploymentUnit) != null)
173            for (TldMetaData tldMetaData : tldsMetaData.getSharedTlds(deploymentUnit)) {
174                getAllComponentClasses(tldMetaData, classes);
175            }
176        if (tldsMetaData.getTlds() != null)
177            for (Map.Entry<String, TldMetaData> tldMetaData : tldsMetaData.getTlds().entrySet()) {
178                getAllComponentClasses(tldMetaData.getValue(), classes);
179            }
180        getAllAsyncListenerClasses(index, classes);
181        return classes;
182    }
183
184    private void getAllComponentClasses(WebCommonMetaData metaData, Set<String> classes) {
185        if (metaData.getServlets() != null)
186            for (ServletMetaData servlet : metaData.getServlets()) {
187                if (servlet.getServletClass() != null) {
188                    classes.add(servlet.getServletClass());
189                }
190            }
191        if (metaData.getFilters() != null)
192            for (FilterMetaData filter : metaData.getFilters()) {
193                classes.add(filter.getFilterClass());
194            }
195        if (metaData.getListeners() != null)
196            for (ListenerMetaData listener : metaData.getListeners()) {
197                classes.add(listener.getListenerClass());
198            }
199    }
200
201    private void getAllComponentClasses(TldMetaData metaData, Set<String> classes) {
202        if (metaData.getValidator() != null) {
203            classes.add(metaData.getValidator().getValidatorClass());
204        }
205        if (metaData.getListeners() != null)
206            for (ListenerMetaData listener : metaData.getListeners()) {
207                classes.add(listener.getListenerClass());
208            }
209        if (metaData.getTags() != null)
210            for (TagMetaData tag : metaData.getTags()) {
211                classes.add(tag.getTagClass());
212            }
213    }
214
215    private void getAllAsyncListenerClasses(CompositeIndex index, Set<String> classes) {
216        if (index != null) {
217            Set<ClassInfo> classInfos = index.getAllKnownImplementors(ASYNC_LISTENER_INTERFACE);
218            for (ClassInfo classInfo : classInfos) {
219                classes.add(classInfo.name().toString());
220            }
221        }
222    }
223}