From 14b4cebe23437eb4a1e02661b1ccd37b1e059243 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Tue, 7 Aug 2018 14:48:17 +1000 Subject: [PATCH] Start porting some of the Servlet annotation processing logic from WildFly --- .../jboss/shamrock/example/TestServlet.java | 7 +- .../jaxrs/JaxrsScanningProcessor.java | 2 +- pom.xml | 6 + undertow/deployment/pom.xml | 4 + .../undertow/ServletAnnotationProcessor.java | 540 +++++++++++++++++- .../jboss/shamrock/undertow/ServletData.java | 10 + .../runtime/UndertowDeploymentTemplate.java | 18 +- 7 files changed, 557 insertions(+), 30 deletions(-) diff --git a/examples/strict/src/main/java/org/jboss/shamrock/example/TestServlet.java b/examples/strict/src/main/java/org/jboss/shamrock/example/TestServlet.java index 645f9554b..4d2ae7be6 100644 --- a/examples/strict/src/main/java/org/jboss/shamrock/example/TestServlet.java +++ b/examples/strict/src/main/java/org/jboss/shamrock/example/TestServlet.java @@ -2,16 +2,19 @@ package org.jboss.shamrock.example; import java.io.IOException; +import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -@WebServlet(name = "MyServlet", urlPatterns = "/test") +@WebServlet(name = "MyServlet", urlPatterns = "/test", initParams = {@WebInitParam(name = "message", value = "A message")}) public class TestServlet extends HttpServlet { + + @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - resp.getWriter().write("A message"); + resp.getWriter().write(getInitParameter("message")); } } diff --git a/jaxrs/deployment/src/main/java/org/jboss/shamrock/jaxrs/JaxrsScanningProcessor.java b/jaxrs/deployment/src/main/java/org/jboss/shamrock/jaxrs/JaxrsScanningProcessor.java index 76eba1775..e8d70e863 100755 --- a/jaxrs/deployment/src/main/java/org/jboss/shamrock/jaxrs/JaxrsScanningProcessor.java +++ b/jaxrs/deployment/src/main/java/org/jboss/shamrock/jaxrs/JaxrsScanningProcessor.java @@ -105,7 +105,7 @@ public class JaxrsScanningProcessor implements ResourceProcessor { UndertowDeploymentTemplate undertow = recorder.getRecordingProxy(UndertowDeploymentTemplate.class); InjectionInstance instanceFactory = (InjectionInstance) recorder.newInstanceFactory(HttpServlet30Dispatcher.class.getName()); InstanceFactory factory = undertow.createInstanceFactory(instanceFactory); - undertow.registerServlet(null, JAX_RS_SERVLET_NAME, recorder.classProxy(HttpServlet30Dispatcher.class.getName()), true, factory); + undertow.registerServlet(null, JAX_RS_SERVLET_NAME, recorder.classProxy(HttpServlet30Dispatcher.class.getName()), true, 1, factory); undertow.addServletMapping(null, JAX_RS_SERVLET_NAME, path + "/*"); Collection paths = index.getAnnotations(PATH); if (paths != null) { diff --git a/pom.xml b/pom.xml index faea98c79..10f06f412 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,7 @@ 2.0 1.0.0.Alpha7 5.3.3.Final + 11.0.0.Final @@ -233,6 +234,11 @@ jboss-invocation ${jboss-invocation.version} + + org.jboss.metadata + jboss-metadata-web + ${jboss-metadata-web.version} + org.jboss.resteasy resteasy-cdi diff --git a/undertow/deployment/pom.xml b/undertow/deployment/pom.xml index f283fa4ef..3d7322fd8 100644 --- a/undertow/deployment/pom.xml +++ b/undertow/deployment/pom.xml @@ -25,6 +25,10 @@ org.jboss.shamrock shamrock-undertow-runtime + + org.jboss.metadata + jboss-metadata-web + diff --git a/undertow/deployment/src/main/java/org/jboss/shamrock/undertow/ServletAnnotationProcessor.java b/undertow/deployment/src/main/java/org/jboss/shamrock/undertow/ServletAnnotationProcessor.java index 79757ed7c..6a05f0daa 100644 --- a/undertow/deployment/src/main/java/org/jboss/shamrock/undertow/ServletAnnotationProcessor.java +++ b/undertow/deployment/src/main/java/org/jboss/shamrock/undertow/ServletAnnotationProcessor.java @@ -1,15 +1,56 @@ package org.jboss.shamrock.undertow; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.security.DeclareRoles; +import javax.annotation.security.RunAs; import javax.inject.Inject; import javax.servlet.Servlet; +import javax.servlet.annotation.MultipartConfig; +import javax.servlet.annotation.ServletSecurity; +import javax.servlet.annotation.WebFilter; +import javax.servlet.annotation.WebListener; import javax.servlet.annotation.WebServlet; +import org.jboss.annotation.javaee.Descriptions; +import org.jboss.annotation.javaee.DisplayNames; +import org.jboss.annotation.javaee.Icons; import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationTarget; import org.jboss.jandex.AnnotationValue; +import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.IndexView; +import org.jboss.metadata.javaee.spec.DescriptionGroupMetaData; +import org.jboss.metadata.javaee.spec.DescriptionImpl; +import org.jboss.metadata.javaee.spec.DescriptionsImpl; +import org.jboss.metadata.javaee.spec.DisplayNameImpl; +import org.jboss.metadata.javaee.spec.DisplayNamesImpl; +import org.jboss.metadata.javaee.spec.IconImpl; +import org.jboss.metadata.javaee.spec.IconsImpl; +import org.jboss.metadata.javaee.spec.ParamValueMetaData; +import org.jboss.metadata.javaee.spec.RunAsMetaData; +import org.jboss.metadata.javaee.spec.SecurityRoleMetaData; +import org.jboss.metadata.javaee.spec.SecurityRolesMetaData; +import org.jboss.metadata.web.spec.AnnotationMetaData; +import org.jboss.metadata.web.spec.AnnotationsMetaData; +import org.jboss.metadata.web.spec.DispatcherType; +import org.jboss.metadata.web.spec.EmptyRoleSemanticType; +import org.jboss.metadata.web.spec.FilterMappingMetaData; +import org.jboss.metadata.web.spec.FilterMetaData; +import org.jboss.metadata.web.spec.FiltersMetaData; +import org.jboss.metadata.web.spec.HttpMethodConstraintMetaData; +import org.jboss.metadata.web.spec.ListenerMetaData; +import org.jboss.metadata.web.spec.MultipartConfigMetaData; +import org.jboss.metadata.web.spec.ServletMappingMetaData; +import org.jboss.metadata.web.spec.ServletMetaData; +import org.jboss.metadata.web.spec.ServletSecurityMetaData; +import org.jboss.metadata.web.spec.ServletsMetaData; +import org.jboss.metadata.web.spec.TransportGuaranteeType; +import org.jboss.metadata.web.spec.WebMetaData; import org.jboss.shamrock.deployment.ArchiveContext; import org.jboss.shamrock.deployment.ProcessorContext; import org.jboss.shamrock.deployment.ResourceProcessor; @@ -20,11 +61,20 @@ import org.jboss.shamrock.runtime.InjectionInstance; import org.jboss.shamrock.undertow.runtime.UndertowDeploymentTemplate; import io.undertow.servlet.api.InstanceFactory; +import io.undertow.servlet.api.ServletInfo; import io.undertow.servlet.handlers.DefaultServlet; public class ServletAnnotationProcessor implements ResourceProcessor { - private static final DotName WEB_SERVLET = DotName.createSimple(WebServlet.class.getName()); + + private static final DotName webFilter = DotName.createSimple(WebFilter.class.getName()); + private static final DotName webListener = DotName.createSimple(WebListener.class.getName()); + private static final DotName webServlet = DotName.createSimple(WebServlet.class.getName()); + private static final DotName runAs = DotName.createSimple(RunAs.class.getName()); + private static final DotName declareRoles = DotName.createSimple(DeclareRoles.class.getName()); + private static final DotName multipartConfig = DotName.createSimple(MultipartConfig.class.getName()); + private static final DotName servletSecurity = DotName.createSimple(ServletSecurity.class.getName()); + @Inject private ShamrockConfig config; @@ -43,36 +93,48 @@ public class ServletAnnotationProcessor implements ResourceProcessor { template.createDeployment("test"); } final IndexView index = archiveContext.getIndex(); - Collection annotations = index.getAnnotations(WEB_SERVLET); - if (annotations != null && annotations.size() > 0) { - try (BytecodeRecorder context = processorContext.addStaticInitTask(RuntimePriority.UNDERTOW_REGISTER_SERVLET)) { - UndertowDeploymentTemplate template = context.getRecordingProxy(UndertowDeploymentTemplate.class); - for (AnnotationInstance annotation : annotations) { - String name = annotation.value("name").asString(); - AnnotationValue asyncSupported = annotation.value("asyncSupported"); - String servletClass = annotation.target().asClass().toString(); - processorContext.addReflectiveClass(false, false, servletClass); - InjectionInstance injection = (InjectionInstance) context.newInstanceFactory(servletClass); + WebMetaData result = processAnnotations(index); + + try (BytecodeRecorder context = processorContext.addStaticInitTask(RuntimePriority.UNDERTOW_REGISTER_SERVLET)) { + UndertowDeploymentTemplate template = context.getRecordingProxy(UndertowDeploymentTemplate.class); + + + if (result.getServlets() != null) { + for (ServletMetaData servlet : result.getServlets()) { + processorContext.addReflectiveClass(false, false, servlet.getServletClass()); + InjectionInstance injection = (InjectionInstance) context.newInstanceFactory(servlet.getServletClass()); InstanceFactory factory = template.createInstanceFactory(injection); - template.registerServlet(null, name, context.classProxy(servletClass), asyncSupported != null && asyncSupported.asBoolean(), factory); - String[] mappings = annotation.value("urlPatterns").asStringArray(); - for (String m : mappings) { - template.addServletMapping(null, name, m); + AtomicReference sref = template.registerServlet(null, servlet.getServletName(), + context.classProxy(servlet.getServletClass()), + servlet.isAsyncSupported(), + servlet.getLoadOnStartupInt(), + factory); + if (servlet.getInitParam() != null) { + for (ParamValueMetaData init : servlet.getInitParam()) { + template.addInitParam(sref, init.getParamName(), init.getParamValue()); + } } } - - for (ServletData servlet : deployment.getServlets()) { - - String servletClass = servlet.getServletClass(); - InjectionInstance injection = (InjectionInstance) context.newInstanceFactory(servletClass); - InstanceFactory factory = template.createInstanceFactory(injection); - template.registerServlet(null, servlet.getName(), context.classProxy(servletClass), true, factory); - - for (String m : servlet.getMapings()) { - template.addServletMapping(null, servlet.getName(), m); + } + if (result.getServletMappings() != null) { + for (ServletMappingMetaData mapping : result.getServletMappings()) { + for (String m : mapping.getUrlPatterns()) { + template.addServletMapping(null, mapping.getServletName(), m); } } } + + for (ServletData servlet : deployment.getServlets()) { + + String servletClass = servlet.getServletClass(); + InjectionInstance injection = (InjectionInstance) context.newInstanceFactory(servletClass); + InstanceFactory factory = template.createInstanceFactory(injection); + template.registerServlet(null, servlet.getName(), context.classProxy(servletClass), true, servlet.getLoadOnStartup(), factory); + + for (String m : servlet.getMapings()) { + template.addServletMapping(null, servlet.getName(), m); + } + } } @@ -91,4 +153,432 @@ public class ServletAnnotationProcessor implements ResourceProcessor { public int getPriority() { return 100; } + + /** + * Process a single index. + * + * @param index the annotation index + */ + protected WebMetaData processAnnotations(IndexView index) { + WebMetaData metaData = new WebMetaData(); + // @WebServlet + final Collection webServletAnnotations = index.getAnnotations(webServlet); + if (webServletAnnotations != null && webServletAnnotations.size() > 0) { + ServletsMetaData servlets = new ServletsMetaData(); + List servletMappings = new ArrayList(); + for (final AnnotationInstance annotation : webServletAnnotations) { + ServletMetaData servlet = new ServletMetaData(); + AnnotationTarget target = annotation.target(); + ClassInfo classInfo = ClassInfo.class.cast(target); + servlet.setServletClass(classInfo.toString()); + AnnotationValue nameValue = annotation.value("name"); + if (nameValue == null || nameValue.asString().isEmpty()) { + servlet.setName(classInfo.toString()); + } else { + servlet.setName(nameValue.asString()); + } + AnnotationValue loadOnStartup = annotation.value("loadOnStartup"); + if (loadOnStartup != null && loadOnStartup.asInt() >= 0) { + servlet.setLoadOnStartupInt(loadOnStartup.asInt()); + } + AnnotationValue asyncSupported = annotation.value("asyncSupported"); + if (asyncSupported != null) { + servlet.setAsyncSupported(asyncSupported.asBoolean()); + } + AnnotationValue initParamsValue = annotation.value("initParams"); + if (initParamsValue != null) { + AnnotationInstance[] initParamsAnnotations = initParamsValue.asNestedArray(); + if (initParamsAnnotations != null && initParamsAnnotations.length > 0) { + List initParams = new ArrayList(); + for (AnnotationInstance initParamsAnnotation : initParamsAnnotations) { + ParamValueMetaData initParam = new ParamValueMetaData(); + AnnotationValue initParamName = initParamsAnnotation.value("name"); + AnnotationValue initParamValue = initParamsAnnotation.value(); + AnnotationValue initParamDescription = initParamsAnnotation.value("description"); + initParam.setParamName(initParamName.asString()); + initParam.setParamValue(initParamValue.asString()); + if (initParamDescription != null) { + Descriptions descriptions = getDescription(initParamDescription.asString()); + if (descriptions != null) { + initParam.setDescriptions(descriptions); + } + } + initParams.add(initParam); + } + servlet.setInitParam(initParams); + } + } + AnnotationValue descriptionValue = annotation.value("description"); + AnnotationValue displayNameValue = annotation.value("displayName"); + AnnotationValue smallIconValue = annotation.value("smallIcon"); + AnnotationValue largeIconValue = annotation.value("largeIcon"); + DescriptionGroupMetaData descriptionGroup = + getDescriptionGroup((descriptionValue == null) ? "" : descriptionValue.asString(), + (displayNameValue == null) ? "" : displayNameValue.asString(), + (smallIconValue == null) ? "" : smallIconValue.asString(), + (largeIconValue == null) ? "" : largeIconValue.asString()); + if (descriptionGroup != null) { + servlet.setDescriptionGroup(descriptionGroup); + } + ServletMappingMetaData servletMapping = new ServletMappingMetaData(); + servletMapping.setServletName(servlet.getName()); + List urlPatterns = new ArrayList(); + AnnotationValue urlPatternsValue = annotation.value("urlPatterns"); + if (urlPatternsValue != null) { + for (String urlPattern : urlPatternsValue.asStringArray()) { + urlPatterns.add(urlPattern); + } + } + urlPatternsValue = annotation.value(); + if (urlPatternsValue != null) { + for (String urlPattern : urlPatternsValue.asStringArray()) { + urlPatterns.add(urlPattern); + } + } + if (urlPatterns.size() > 0) { + servletMapping.setUrlPatterns(urlPatterns); + servletMappings.add(servletMapping); + } + servlets.add(servlet); + } + metaData.setServlets(servlets); + metaData.setServletMappings(servletMappings); + } + // @WebFilter + final Collection webFilterAnnotations = index.getAnnotations(webFilter); + if (webFilterAnnotations != null && webFilterAnnotations.size() > 0) { + FiltersMetaData filters = new FiltersMetaData(); + List filterMappings = new ArrayList(); + for (final AnnotationInstance annotation : webFilterAnnotations) { + FilterMetaData filter = new FilterMetaData(); + AnnotationTarget target = annotation.target(); + ClassInfo classInfo = ClassInfo.class.cast(target); + filter.setFilterClass(classInfo.toString()); + AnnotationValue nameValue = annotation.value("filterName"); + if (nameValue == null || nameValue.asString().isEmpty()) { + filter.setName(classInfo.toString()); + } else { + filter.setName(nameValue.asString()); + } + AnnotationValue asyncSupported = annotation.value("asyncSupported"); + if (asyncSupported != null) { + filter.setAsyncSupported(asyncSupported.asBoolean()); + } + AnnotationValue initParamsValue = annotation.value("initParams"); + if (initParamsValue != null) { + AnnotationInstance[] initParamsAnnotations = initParamsValue.asNestedArray(); + if (initParamsAnnotations != null && initParamsAnnotations.length > 0) { + List initParams = new ArrayList(); + for (AnnotationInstance initParamsAnnotation : initParamsAnnotations) { + ParamValueMetaData initParam = new ParamValueMetaData(); + AnnotationValue initParamName = initParamsAnnotation.value("name"); + AnnotationValue initParamValue = initParamsAnnotation.value(); + AnnotationValue initParamDescription = initParamsAnnotation.value("description"); + initParam.setParamName(initParamName.asString()); + initParam.setParamValue(initParamValue.asString()); + if (initParamDescription != null) { + Descriptions descriptions = getDescription(initParamDescription.asString()); + if (descriptions != null) { + initParam.setDescriptions(descriptions); + } + } + initParams.add(initParam); + } + filter.setInitParam(initParams); + } + } + AnnotationValue descriptionValue = annotation.value("description"); + AnnotationValue displayNameValue = annotation.value("displayName"); + AnnotationValue smallIconValue = annotation.value("smallIcon"); + AnnotationValue largeIconValue = annotation.value("largeIcon"); + DescriptionGroupMetaData descriptionGroup = + getDescriptionGroup((descriptionValue == null) ? "" : descriptionValue.asString(), + (displayNameValue == null) ? "" : displayNameValue.asString(), + (smallIconValue == null) ? "" : smallIconValue.asString(), + (largeIconValue == null) ? "" : largeIconValue.asString()); + if (descriptionGroup != null) { + filter.setDescriptionGroup(descriptionGroup); + } + filters.add(filter); + FilterMappingMetaData filterMapping = new FilterMappingMetaData(); + filterMapping.setFilterName(filter.getName()); + List urlPatterns = new ArrayList(); + List servletNames = new ArrayList(); + List dispatchers = new ArrayList(); + AnnotationValue urlPatternsValue = annotation.value("urlPatterns"); + if (urlPatternsValue != null) { + for (String urlPattern : urlPatternsValue.asStringArray()) { + urlPatterns.add(urlPattern); + } + } + urlPatternsValue = annotation.value(); + if (urlPatternsValue != null) { + for (String urlPattern : urlPatternsValue.asStringArray()) { + urlPatterns.add(urlPattern); + } + } + if (urlPatterns.size() > 0) { + filterMapping.setUrlPatterns(urlPatterns); + } + AnnotationValue servletNamesValue = annotation.value("servletNames"); + if (servletNamesValue != null) { + for (String servletName : servletNamesValue.asStringArray()) { + servletNames.add(servletName); + } + } + if (servletNames.size() > 0) { + filterMapping.setServletNames(servletNames); + } + AnnotationValue dispatcherTypesValue = annotation.value("dispatcherTypes"); + if (dispatcherTypesValue != null) { + for (String dispatcherValue : dispatcherTypesValue.asEnumArray()) { + dispatchers.add(DispatcherType.valueOf(dispatcherValue)); + } + } + if (dispatchers.size() > 0) { + filterMapping.setDispatchers(dispatchers); + } + if (urlPatterns.size() > 0 || servletNames.size() > 0) { + filterMappings.add(filterMapping); + } + } + metaData.setFilters(filters); + metaData.setFilterMappings(filterMappings); + } + // @WebListener + final Collection webListenerAnnotations = index.getAnnotations(webListener); + if (webListenerAnnotations != null && webListenerAnnotations.size() > 0) { + List listeners = new ArrayList(); + for (final AnnotationInstance annotation : webListenerAnnotations) { + ListenerMetaData listener = new ListenerMetaData(); + AnnotationTarget target = annotation.target(); + ClassInfo classInfo = ClassInfo.class.cast(target); + listener.setListenerClass(classInfo.toString()); + AnnotationValue descriptionValue = annotation.value(); + if (descriptionValue != null) { + DescriptionGroupMetaData descriptionGroup = getDescriptionGroup(descriptionValue.asString()); + if (descriptionGroup != null) { + listener.setDescriptionGroup(descriptionGroup); + } + } + listeners.add(listener); + } + metaData.setListeners(listeners); + } + // @RunAs + final Collection runAsAnnotations = index.getAnnotations(runAs); + if (runAsAnnotations != null && runAsAnnotations.size() > 0) { + AnnotationsMetaData annotations = metaData.getAnnotations(); + if (annotations == null) { + annotations = new AnnotationsMetaData(); + metaData.setAnnotations(annotations); + } + for (final AnnotationInstance annotation : runAsAnnotations) { + AnnotationTarget target = annotation.target(); + if (!(target instanceof ClassInfo)) { + continue; + } + ClassInfo classInfo = ClassInfo.class.cast(target); + AnnotationMetaData annotationMD = annotations.get(classInfo.toString()); + if (annotationMD == null) { + annotationMD = new AnnotationMetaData(); + annotationMD.setClassName(classInfo.toString()); + annotations.add(annotationMD); + } + RunAsMetaData runAs = new RunAsMetaData(); + runAs.setRoleName(annotation.value().asString()); + annotationMD.setRunAs(runAs); + } + } + // @DeclareRoles + final Collection declareRolesAnnotations = index.getAnnotations(declareRoles); + if (declareRolesAnnotations != null && declareRolesAnnotations.size() > 0) { + SecurityRolesMetaData securityRoles = metaData.getSecurityRoles(); + if (securityRoles == null) { + securityRoles = new SecurityRolesMetaData(); + metaData.setSecurityRoles(securityRoles); + } + for (final AnnotationInstance annotation : declareRolesAnnotations) { + for (String role : annotation.value().asStringArray()) { + SecurityRoleMetaData sr = new SecurityRoleMetaData(); + sr.setRoleName(role); + securityRoles.add(sr); + } + } + } + // @MultipartConfig + final Collection multipartConfigAnnotations = index.getAnnotations(multipartConfig); + if (multipartConfigAnnotations != null && multipartConfigAnnotations.size() > 0) { + AnnotationsMetaData annotations = metaData.getAnnotations(); + if (annotations == null) { + annotations = new AnnotationsMetaData(); + metaData.setAnnotations(annotations); + } + for (final AnnotationInstance annotation : multipartConfigAnnotations) { + AnnotationTarget target = annotation.target(); + ClassInfo classInfo = ClassInfo.class.cast(target); + AnnotationMetaData annotationMD = annotations.get(classInfo.toString()); + if (annotationMD == null) { + annotationMD = new AnnotationMetaData(); + annotationMD.setClassName(classInfo.toString()); + annotations.add(annotationMD); + } + MultipartConfigMetaData multipartConfig = new MultipartConfigMetaData(); + AnnotationValue locationValue = annotation.value("location"); + if (locationValue != null && locationValue.asString().length() > 0) { + multipartConfig.setLocation(locationValue.asString()); + } + AnnotationValue maxFileSizeValue = annotation.value("maxFileSize"); + if (maxFileSizeValue != null && maxFileSizeValue.asLong() != -1L) { + multipartConfig.setMaxFileSize(maxFileSizeValue.asLong()); + } + AnnotationValue maxRequestSizeValue = annotation.value("maxRequestSize"); + if (maxRequestSizeValue != null && maxRequestSizeValue.asLong() != -1L) { + multipartConfig.setMaxRequestSize(maxRequestSizeValue.asLong()); + } + AnnotationValue fileSizeThresholdValue = annotation.value("fileSizeThreshold"); + if (fileSizeThresholdValue != null && fileSizeThresholdValue.asInt() != 0) { + multipartConfig.setFileSizeThreshold(fileSizeThresholdValue.asInt()); + } + annotationMD.setMultipartConfig(multipartConfig); + } + } + // @ServletSecurity + final Collection servletSecurityAnnotations = index.getAnnotations(servletSecurity); + if (servletSecurityAnnotations != null && servletSecurityAnnotations.size() > 0) { + AnnotationsMetaData annotations = metaData.getAnnotations(); + if (annotations == null) { + annotations = new AnnotationsMetaData(); + metaData.setAnnotations(annotations); + } + for (final AnnotationInstance annotation : servletSecurityAnnotations) { + AnnotationTarget target = annotation.target(); + ClassInfo classInfo = ClassInfo.class.cast(target); + AnnotationMetaData annotationMD = annotations.get(classInfo.toString()); + if (annotationMD == null) { + annotationMD = new AnnotationMetaData(); + annotationMD.setClassName(classInfo.toString()); + annotations.add(annotationMD); + } + ServletSecurityMetaData servletSecurity = new ServletSecurityMetaData(); + AnnotationValue httpConstraintValue = annotation.value(); + List rolesAllowed = new ArrayList(); + if (httpConstraintValue != null) { + AnnotationInstance httpConstraint = httpConstraintValue.asNested(); + AnnotationValue httpConstraintERSValue = httpConstraint.value(); + if (httpConstraintERSValue != null) { + servletSecurity.setEmptyRoleSemantic(EmptyRoleSemanticType.valueOf(httpConstraintERSValue.asEnum())); + } + AnnotationValue httpConstraintTGValue = httpConstraint.value("transportGuarantee"); + if (httpConstraintTGValue != null) { + servletSecurity.setTransportGuarantee(TransportGuaranteeType.valueOf(httpConstraintTGValue.asEnum())); + } + AnnotationValue rolesAllowedValue = httpConstraint.value("rolesAllowed"); + if (rolesAllowedValue != null) { + for (String role : rolesAllowedValue.asStringArray()) { + rolesAllowed.add(role); + } + } + } + servletSecurity.setRolesAllowed(rolesAllowed); + AnnotationValue httpMethodConstraintsValue = annotation.value("httpMethodConstraints"); + if (httpMethodConstraintsValue != null) { + AnnotationInstance[] httpMethodConstraints = httpMethodConstraintsValue.asNestedArray(); + if (httpMethodConstraints.length > 0) { + List methodConstraints = new ArrayList(); + for (AnnotationInstance httpMethodConstraint : httpMethodConstraints) { + HttpMethodConstraintMetaData methodConstraint = new HttpMethodConstraintMetaData(); + AnnotationValue httpMethodConstraintValue = httpMethodConstraint.value(); + if (httpMethodConstraintValue != null) { + methodConstraint.setMethod(httpMethodConstraintValue.asString()); + } + AnnotationValue httpMethodConstraintERSValue = httpMethodConstraint.value("emptyRoleSemantic"); + if (httpMethodConstraintERSValue != null) { + methodConstraint.setEmptyRoleSemantic(EmptyRoleSemanticType.valueOf(httpMethodConstraintERSValue.asEnum())); + } + AnnotationValue httpMethodConstraintTGValue = httpMethodConstraint.value("transportGuarantee"); + if (httpMethodConstraintTGValue != null) { + methodConstraint.setTransportGuarantee(TransportGuaranteeType.valueOf(httpMethodConstraintTGValue.asEnum())); + } + AnnotationValue rolesAllowedValue = httpMethodConstraint.value("rolesAllowed"); + rolesAllowed = new ArrayList(); + if (rolesAllowedValue != null) { + for (String role : rolesAllowedValue.asStringArray()) { + rolesAllowed.add(role); + } + } + methodConstraint.setRolesAllowed(rolesAllowed); + methodConstraints.add(methodConstraint); + } + servletSecurity.setHttpMethodConstraints(methodConstraints); + } + } + annotationMD.setServletSecurity(servletSecurity); + } + } + return metaData; + } + + protected Descriptions getDescription(String description) { + DescriptionsImpl descriptions = null; + if (description.length() > 0) { + DescriptionImpl di = new DescriptionImpl(); + di.setDescription(description); + descriptions = new DescriptionsImpl(); + descriptions.add(di); + } + return descriptions; + } + + protected DisplayNames getDisplayName(String displayName) { + DisplayNamesImpl displayNames = null; + if (displayName.length() > 0) { + DisplayNameImpl dn = new DisplayNameImpl(); + dn.setDisplayName(displayName); + displayNames = new DisplayNamesImpl(); + displayNames.add(dn); + } + return displayNames; + } + + protected Icons getIcons(String smallIcon, String largeIcon) { + IconsImpl icons = null; + if (smallIcon.length() > 0 || largeIcon.length() > 0) { + IconImpl i = new IconImpl(); + i.setSmallIcon(smallIcon); + i.setLargeIcon(largeIcon); + icons = new IconsImpl(); + icons.add(i); + } + return icons; + } + + protected DescriptionGroupMetaData getDescriptionGroup(String description) { + DescriptionGroupMetaData dg = null; + if (description.length() > 0) { + dg = new DescriptionGroupMetaData(); + Descriptions descriptions = getDescription(description); + dg.setDescriptions(descriptions); + } + return dg; + } + + protected DescriptionGroupMetaData getDescriptionGroup(String description, String displayName, String smallIcon, + String largeIcon) { + DescriptionGroupMetaData dg = null; + if (description.length() > 0 || displayName.length() > 0 || smallIcon.length() > 0 || largeIcon.length() > 0) { + dg = new DescriptionGroupMetaData(); + Descriptions descriptions = getDescription(description); + if (descriptions != null) + dg.setDescriptions(descriptions); + DisplayNames displayNames = getDisplayName(displayName); + if (displayNames != null) + dg.setDisplayNames(displayNames); + Icons icons = getIcons(smallIcon, largeIcon); + if (icons != null) + dg.setIcons(icons); + } + return dg; + } + } diff --git a/undertow/deployment/src/main/java/org/jboss/shamrock/undertow/ServletData.java b/undertow/deployment/src/main/java/org/jboss/shamrock/undertow/ServletData.java index fb2b28604..17b2418de 100644 --- a/undertow/deployment/src/main/java/org/jboss/shamrock/undertow/ServletData.java +++ b/undertow/deployment/src/main/java/org/jboss/shamrock/undertow/ServletData.java @@ -7,6 +7,7 @@ public class ServletData { private final String name; private final String servletClass; + private int loadOnStartup; private final List mapings = new ArrayList<>(); public ServletData(String name, String servletClass) { @@ -25,4 +26,13 @@ public class ServletData { public List getMapings() { return mapings; } + + public int getLoadOnStartup() { + return loadOnStartup; + } + + public ServletData setLoadOnStartup(int loadOnStartup) { + this.loadOnStartup = loadOnStartup; + return this; + } } diff --git a/undertow/runtime/src/main/java/org/jboss/shamrock/undertow/runtime/UndertowDeploymentTemplate.java b/undertow/runtime/src/main/java/org/jboss/shamrock/undertow/runtime/UndertowDeploymentTemplate.java index 8ccc5f38d..1908331b9 100644 --- a/undertow/runtime/src/main/java/org/jboss/shamrock/undertow/runtime/UndertowDeploymentTemplate.java +++ b/undertow/runtime/src/main/java/org/jboss/shamrock/undertow/runtime/UndertowDeploymentTemplate.java @@ -1,5 +1,7 @@ package org.jboss.shamrock.undertow.runtime; +import java.util.concurrent.atomic.AtomicReference; + import javax.servlet.Servlet; import javax.servlet.ServletException; @@ -54,13 +56,25 @@ public class UndertowDeploymentTemplate { return new ShamrockInstanceFactory(injectionInstance); } - public void registerServlet(@ContextObject("deploymentInfo") DeploymentInfo info, String name, Class servletClass, boolean asyncSupported, InstanceFactory instanceFactory) throws Exception { + public AtomicReference registerServlet(@ContextObject("deploymentInfo") DeploymentInfo info, + String name, Class servletClass, + boolean asyncSupported, + int loadOnStartup, + InstanceFactory instanceFactory) throws Exception { ServletInfo servletInfo = new ServletInfo(name, (Class) servletClass, instanceFactory); - servletInfo.setLoadOnStartup(1); info.addServlet(servletInfo); servletInfo.setAsyncSupported(asyncSupported); + if(loadOnStartup > 0) { + servletInfo.setLoadOnStartup(loadOnStartup); + } + return new AtomicReference<>(servletInfo); } + public void addInitParam(AtomicReference info, String name, String value) { + info.get().addInitParam(name, value); + } + + public void addServletMapping(@ContextObject("deploymentInfo") DeploymentInfo info, String name, String mapping) throws Exception { ServletInfo sv = info.getServlets().get(name); sv.addMapping(mapping);