/** * @param context * @param scis * @throws Exception */ public void createServletContainerInitializerAnnotationHandlers( WebAppContext context, List<ServletContainerInitializer> scis) throws Exception { if (scis == null || scis.isEmpty()) return; // nothing to do List<ContainerInitializer> initializers = new ArrayList<ContainerInitializer>(); context.setAttribute(CONTAINER_INITIALIZERS, initializers); for (ServletContainerInitializer service : scis) { HandlesTypes annotation = service.getClass().getAnnotation(HandlesTypes.class); ContainerInitializer initializer = null; if (annotation != null) { // There is a HandlesTypes annotation on the on the ServletContainerInitializer Class<?>[] classes = annotation.value(); if (classes != null) { initializer = new ContainerInitializer(service, classes); // If we haven't already done so, we need to register a handler that will // process the whole class hierarchy to satisfy the ServletContainerInitializer if (context.getAttribute(CLASS_INHERITANCE_MAP) == null) { // MultiMap<String> map = new MultiMap<>(); ConcurrentHashMap<String, ConcurrentHashSet<String>> map = new ClassInheritanceMap(); context.setAttribute(CLASS_INHERITANCE_MAP, map); _classInheritanceHandler = new ClassInheritanceHandler(map); } for (Class<?> c : classes) { // The value of one of the HandlesTypes classes is actually an Annotation itself so // register a handler for it if (c.isAnnotation()) { if (LOG.isDebugEnabled()) LOG.debug("Registering annotation handler for " + c.getName()); _containerInitializerAnnotationHandlers.add( new ContainerInitializerAnnotationHandler(initializer, c)); } } } else { initializer = new ContainerInitializer(service, null); if (LOG.isDebugEnabled()) LOG.debug("No classes in HandlesTypes on initializer " + service.getClass()); } } else { initializer = new ContainerInitializer(service, null); if (LOG.isDebugEnabled()) LOG.debug("No annotation on initializer " + service.getClass()); } initializers.add(initializer); } // add a bean to the context which will call the servletcontainerinitializers when appropriate ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter) context.getAttribute(CONTAINER_INITIALIZER_STARTER); if (starter != null) throw new IllegalStateException("ServletContainerInitializersStarter already exists"); starter = new ServletContainerInitializersStarter(context); context.setAttribute(CONTAINER_INITIALIZER_STARTER, starter); context.addBean(starter, true); }
private ServletContainerInitializerInfo buildInitializerInfo( InstanceFactoryFactory factory, Class<? extends ServletContainerInitializer> clazz) { Set<Class<?>> types = new HashSet<>(); HandlesTypes handlesTypes = clazz.getAnnotation(HandlesTypes.class); if (handlesTypes != null) { for (Class<?> type : handlesTypes.value()) { if (type.isAnnotation()) { types.addAll(annotationDatabase.getTypes((Class<? extends Annotation>) type)); } } } InstanceFactory<? extends ServletContainerInitializer> instanceFactory = factory.getInstanceFactory(clazz); return new ServletContainerInitializerInfo(clazz, instanceFactory, types); }
/** Process SCIs. */ public void deploy(final DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); final ModuleSpecification moduleSpecification = deploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION); final ServiceModuleLoader loader = deploymentUnit.getAttachment(Attachments.SERVICE_MODULE_LOADER); if (!DeploymentTypeMarker.isType(DeploymentType.WAR, deploymentUnit)) { return; // Skip non web deployments } WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY); assert warMetaData != null; final Module module = deploymentUnit.getAttachment(Attachments.MODULE); if (module == null) { throw MESSAGES.failedToResolveModule(deploymentUnit); } final ClassLoader classLoader = module.getClassLoader(); ScisMetaData scisMetaData = deploymentUnit.getAttachment(ScisMetaData.ATTACHMENT_KEY); if (scisMetaData == null) { scisMetaData = new ScisMetaData(); deploymentUnit.putAttachment(ScisMetaData.ATTACHMENT_KEY, scisMetaData); } Set<ServletContainerInitializer> scis = scisMetaData.getScis(); if (scis == null) { scis = new HashSet<ServletContainerInitializer>(); scisMetaData.setScis(scis); } Map<ServletContainerInitializer, Set<Class<?>>> handlesTypes = scisMetaData.getHandlesTypes(); if (handlesTypes == null) { handlesTypes = new HashMap<ServletContainerInitializer, Set<Class<?>>>(); scisMetaData.setHandlesTypes(handlesTypes); } // Find the SCIs from shared modules for (ModuleDependency dependency : moduleSpecification.getSystemDependencies()) { try { Module depModule = loader.loadModule(dependency.getIdentifier()); ServiceLoader<ServletContainerInitializer> serviceLoader = depModule.loadService(ServletContainerInitializer.class); for (ServletContainerInitializer service : serviceLoader) { scis.add(service); } } catch (ModuleLoadException e) { if (dependency.isOptional() == false) { throw MESSAGES.errorLoadingSCIFromModule(dependency.getIdentifier(), e); } } } // Find local ServletContainerInitializer services List<String> order = warMetaData.getOrder(); Map<String, VirtualFile> localScis = warMetaData.getScis(); if (order != null && localScis != null) { for (String jar : order) { VirtualFile sci = localScis.get(jar); if (sci != null) { ServletContainerInitializer service = loadSci(classLoader, sci, jar, true); if (service != null) { scis.add(service); } } } } // Process HandlesTypes for ServletContainerInitializer Map<Class<?>, Set<ServletContainerInitializer>> typesMap = new HashMap<Class<?>, Set<ServletContainerInitializer>>(); for (ServletContainerInitializer service : scis) { if (service.getClass().isAnnotationPresent(HandlesTypes.class)) { HandlesTypes handlesTypesAnnotation = service.getClass().getAnnotation(HandlesTypes.class); Class<?>[] typesArray = handlesTypesAnnotation.value(); if (typesArray != null) { for (Class<?> type : typesArray) { Set<ServletContainerInitializer> servicesSet = typesMap.get(type); if (servicesSet == null) { servicesSet = new HashSet<ServletContainerInitializer>(); typesMap.put(type, servicesSet); } servicesSet.add(service); handlesTypes.put(service, new HashSet<Class<?>>()); } } } } Class<?>[] typesArray = typesMap.keySet().toArray(new Class<?>[0]); final CompositeIndex index = deploymentUnit.getAttachment(Attachments.COMPOSITE_ANNOTATION_INDEX); if (index == null) { throw MESSAGES.unableToResolveAnnotationIndex(deploymentUnit); } // Find classes which extend, implement, or are annotated by HandlesTypes for (Class<?> type : typesArray) { DotName className = DotName.createSimple(type.getName()); Set<ClassInfo> classInfos = processHandlesType(className, type, index); Set<Class<?>> classes = loadClassInfoSet(classInfos, classLoader); Set<ServletContainerInitializer> sciSet = typesMap.get(type); for (ServletContainerInitializer sci : sciSet) { handlesTypes.get(sci).addAll(classes); } } }
/** @see WebXmlParser#parse(InputStream) */ public WebApp parse(final Bundle bundle, final InputStream inputStream) { final WebApp webApp = new WebApp(); // changed to final because of inner // class. try { final Element rootElement = getRootElement(inputStream); if (rootElement != null) { // webApp = new WebApp(); // web-app attributes String version = getAttribute(rootElement, "version"); Integer majorVersion = null; if (version != null && !version.isEmpty() && version.length() > 2) { LOG.debug("version found in web.xml - " + version); try { majorVersion = Integer.parseInt(version.split("\\.")[0]); } catch (NumberFormatException nfe) { // munch do nothing here stay with null therefore // annotation scanning is disabled. } } else if (version != null && !version.isEmpty() && version.length() > 0) { try { majorVersion = Integer.parseInt(version); } catch (NumberFormatException e) { // munch do nothing here stay with null.... } } Boolean metaDataComplete = Boolean.parseBoolean(getAttribute(rootElement, "metadata-complete", "false")); webApp.setMetaDataComplete(metaDataComplete); LOG.debug("metadata-complete is: " + metaDataComplete); // web-app elements webApp.setDisplayName(getTextContent(getChild(rootElement, "display-name"))); parseContextParams(rootElement, webApp); parseSessionConfig(rootElement, webApp); parseServlets(rootElement, webApp); parseFilters(rootElement, webApp); parseListeners(rootElement, webApp); parseErrorPages(rootElement, webApp); parseWelcomeFiles(rootElement, webApp); parseMimeMappings(rootElement, webApp); parseSecurity(rootElement, webApp); LOG.debug("scanninf for ServletContainerInitializers"); ServiceLoader<ServletContainerInitializer> serviceLoader = ServiceLoader.load( ServletContainerInitializer.class, bundle.getClass().getClassLoader()); if (serviceLoader != null) { LOG.debug("ServletContainerInitializers found"); while (serviceLoader.iterator().hasNext()) { // for (ServletContainerInitializer service : // serviceLoader) { ServletContainerInitializer service = null; try { bundle.loadClass(ServletContainerInitializer.class.getName()); Object obj = serviceLoader.iterator().next(); if (obj instanceof ServletContainerInitializer) service = (ServletContainerInitializer) obj; else continue; } catch (ServiceConfigurationError e) { LOG.error("ServiceConfigurationError loading ServletContainerInitializer", e); continue; } catch (ClassNotFoundException e) { LOG.error("ServiceConfigurationError loading ServletContainerInitializer", e); continue; } WebAppServletContainerInitializer webAppServletContainerInitializer = new WebAppServletContainerInitializer(); webAppServletContainerInitializer.setServletContainerInitializer(service); if (!webApp.getMetaDataComplete() && majorVersion != null && majorVersion >= 3) { HandlesTypes annotation = service.getClass().getAnnotation(HandlesTypes.class); Class[] classes; if (annotation != null) { // add annotated classes to service classes = annotation.value(); webAppServletContainerInitializer.setClasses(classes); } } webApp.addServletContainerInitializer(webAppServletContainerInitializer); } } if (!webApp.getMetaDataComplete() && majorVersion != null && majorVersion >= 3) { LOG.debug("metadata-complete is either false or not set"); LOG.debug("scanning for annotated classes"); Enumeration<?> clazzes = bundle.findEntries("/", "*.class", true); for (; clazzes.hasMoreElements(); ) { URL clazzUrl = (URL) clazzes.nextElement(); Class<?> clazz; String clazzFile = clazzUrl.getFile(); LOG.debug("Class file found at :" + clazzFile); if (clazzFile.startsWith("/WEB-INF/classes")) clazzFile = clazzFile.replaceFirst("/WEB-INF/classes", ""); else if (clazzFile.startsWith("/WEB-INF/lib")) clazzFile = clazzFile.replaceFirst("/WEB-INF/lib", ""); String clazzName = clazzFile.replaceAll("/", ".").replaceAll(".class", "").replaceFirst(".", ""); try { clazz = bundle.loadClass(clazzName); } catch (ClassNotFoundException e) { LOG.debug("Class {} not found", clazzName); continue; } if (clazz.isAnnotationPresent(WebServlet.class)) { LOG.debug("found WebServlet annotation on class: " + clazz); WebServletAnnotationScanner annonScanner = new WebServletAnnotationScanner(bundle, clazz.getCanonicalName()); annonScanner.scan(webApp); } else if (clazz.isAnnotationPresent(WebFilter.class)) { LOG.debug("found WebFilter annotation on class: " + clazz); WebFilterAnnotationScanner filterScanner = new WebFilterAnnotationScanner(bundle, clazz.getCanonicalName()); filterScanner.scan(webApp); } else if (clazz.isAnnotationPresent(WebListener.class)) { LOG.debug("found WebListener annotation on class: " + clazz); addWebListener(webApp, clazz.getSimpleName()); } } LOG.debug("class scanning done"); } // special handling for finding JSF Context listeners wrapped in // *.tld files Enumeration tldEntries = bundle.getResources("*.tld"); // Enumeration tldEntries = bundle.findEntries("/", "*.tld", // true); while (tldEntries != null && tldEntries.hasMoreElements()) { URL url = (URL) tldEntries.nextElement(); Element rootTld = getRootElement(url.openStream()); if (rootTld != null) { parseListeners(rootTld, webApp); } } } else { LOG.warn("The parsed web.xml does not have a root element"); return null; } } catch (ParserConfigurationException ignore) { LOG.error("Cannot parse web.xml", ignore); } catch (IOException ignore) { LOG.error("Cannot parse web.xml", ignore); } catch (SAXException ignore) { LOG.error("Cannot parse web.xml", ignore); } return webApp; }