/*
 * JBoss, Home of Professional Open Source.
 * Copyright (c) 2012, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.as.ejb3.subsystem.deployment;

import org.jboss.as.controller.AbstractRuntimeOnlyHandler;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.as.ee.component.BasicComponent;
import org.jboss.as.ejb3.component.EJBComponent;
import org.jboss.as.server.deployment.Services;
import org.jboss.dmr.ModelNode;
import org.jboss.msc.service.ServiceName;
/**
 * @author Carlo de Wolf
 */
public abstract class AbstractRuntimeMetricsHandler extends AbstractRuntimeOnlyHandler {
    private static ServiceName componentServiceName(final OperationContext context, final ModelNode operation) {
        final PathAddress address = PathAddress.pathAddress(operation.require(ModelDescriptionConstants.OP_ADDR));
        final String parent;
        final String module;
        int i = 2;
        if (address.getElement(1).getKey().equals(ModelDescriptionConstants.SUBDEPLOYMENT)) {
            parent = resolveRuntimeName(context,address.getElement(0));
            module = address.getElement(1).getValue();
            i++;
        } else {
            parent = null;
            module = resolveRuntimeName(context,address.getElement(0));
        }
        final String component = address.getElement(i).getValue();
        final ServiceName deploymentUnitServiceName;
        if (parent == null) {
            deploymentUnitServiceName = Services.deploymentUnitName(module);
        }
        else {
            deploymentUnitServiceName = Services.deploymentUnitName(parent, module);
        }
        // Hmm, don't like the START bit
        return BasicComponent.serviceNameOf(deploymentUnitServiceName, component).append("START");
    }

    protected abstract void executeReadMetricStep(final OperationContext context, final ModelNode operation, final EJBComponent component) throws OperationFailedException;

    @Override
    protected void executeRuntimeStep(final OperationContext context, final ModelNode operation) throws OperationFailedException {
        final ServiceName componentServiceName = componentServiceName(context,operation);
        final EJBComponent component = (EJBComponent) context.getServiceRegistry(false).getRequiredService(componentServiceName).getValue();
        executeReadMetricStep(context, operation, component);
    }

    /**
     * Resolves runtime name of model resource.
     * @param context - operation context in which handler is invoked
     * @param address - deployment address
     * @return runtime name of module. Value which is returned is never null.
     */
    protected static String resolveRuntimeName(final OperationContext context, final PathElement address){
        final ModelNode runtimeName = context.readResourceFromRoot(PathAddress.pathAddress(address),false).getModel()
                .get(ModelDescriptionConstants.RUNTIME_NAME);
            return runtimeName.asString();
    }
}


/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2010, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.as.ee.managedbean.processors;

import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;

import javax.annotation.ManagedBean;

import org.jboss.as.ee.logging.EeLogger;
import org.jboss.as.ee.component.ComponentConfiguration;
import org.jboss.as.ee.component.EEModuleDescription;
import org.jboss.as.ee.component.ViewConfiguration;
import org.jboss.as.ee.component.ViewConfigurator;
import org.jboss.as.ee.component.ViewDescription;
import org.jboss.as.ee.component.deployers.EEResourceReferenceProcessorRegistry;
import org.jboss.as.ee.component.interceptors.InterceptorOrder;
import org.jboss.as.ee.managedbean.component.ManagedBeanComponentDescription;
import org.jboss.as.ee.managedbean.component.ManagedBeanCreateInterceptor;
import org.jboss.as.ee.managedbean.component.ManagedBeanResourceReferenceProcessor;
import org.jboss.as.ee.structure.EJBAnnotationPropertyReplacement;
import org.jboss.as.server.deployment.Attachments;
import org.jboss.as.server.deployment.DeploymentPhaseContext;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
import org.jboss.as.server.deployment.annotation.CompositeIndex;
import org.jboss.invocation.AccessCheckingInterceptor;
import org.jboss.invocation.ContextClassLoaderInterceptor;
import org.jboss.invocation.ImmediateInterceptorFactory;
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.metadata.property.PropertyReplacer;

import static org.jboss.as.ee.logging.EeLogger.ROOT_LOGGER;

/**
 * Deployment unit processor responsible for scanning a deployment to find classes with {@code javax.annotation.ManagedBean} annotations.
 * Note:  This processor only supports JSR-316 compliant managed beans.  So it will not handle complimentary spec additions (ex. EJB).
 *
 * @author John E. Bailey
 */
public class ManagedBeanAnnotationProcessor implements DeploymentUnitProcessor {

    static final DotName MANAGED_BEAN_ANNOTATION_NAME = DotName.createSimple(ManagedBean.class.getName());

    /**
     * Check the deployment annotation index for all classes with the @ManagedBean annotation.  For each class with the
     * annotation, collect all the required information to create a managed bean instance, and attach it to the context.
     *
     * @param phaseContext the deployment unit context
     * @throws DeploymentUnitProcessingException
     *
     */
    public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
        final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
        final EEResourceReferenceProcessorRegistry registry = deploymentUnit.getAttachment(org.jboss.as.ee.component.Attachments.RESOURCE_REFERENCE_PROCESSOR_REGISTRY);
        final EEModuleDescription moduleDescription = deploymentUnit.getAttachment(org.jboss.as.ee.component.Attachments.EE_MODULE_DESCRIPTION);
        final CompositeIndex compositeIndex = deploymentUnit.getAttachment(Attachments.COMPOSITE_ANNOTATION_INDEX);
        final PropertyReplacer replacer = EJBAnnotationPropertyReplacement.propertyReplacer(deploymentUnit);
        if(compositeIndex == null) {
            return;
        }
        final List<AnnotationInstance> instances = compositeIndex.getAnnotations(MANAGED_BEAN_ANNOTATION_NAME);
        if (instances == null || instances.isEmpty()) {
            return;
        }

        for (AnnotationInstance instance : instances) {
            AnnotationTarget target = instance.target();
            if (!(target instanceof ClassInfo)) {
                throw EeLogger.ROOT_LOGGER.classOnlyAnnotation("@ManagedBean", target);
            }
            final ClassInfo classInfo = (ClassInfo) target;
            // skip if it's not a valid managed bean class
            if (!assertManagedBeanClassValidity(classInfo)) {
                continue;
            }
            final String beanClassName = classInfo.name().toString();

            // Get the managed bean name from the annotation
            final AnnotationValue nameValue = instance.value();
            final String beanName = (nameValue == null || nameValue.asString().isEmpty()) ? beanClassName : replacer.replaceProperties(nameValue.asString());
            final ManagedBeanComponentDescription componentDescription = new ManagedBeanComponentDescription(beanName, beanClassName, moduleDescription, deploymentUnit.getServiceName());

            // Add the view
            ViewDescription viewDescription = new ViewDescription(componentDescription, beanClassName);
            viewDescription.getConfigurators().addFirst(new ViewConfigurator() {
                public void configure(final DeploymentPhaseContext context, final ComponentConfiguration componentConfiguration, final ViewDescription description, final ViewConfiguration configuration) throws DeploymentUnitProcessingException {
                    // Add MB association interceptors
                    configuration.addClientPostConstructInterceptor(ManagedBeanCreateInterceptor.FACTORY, InterceptorOrder.ClientPostConstruct.INSTANCE_CREATE);
                    final ClassLoader classLoader = componentConfiguration.getModuleClassLoader();
                    configuration.addViewInterceptor(AccessCheckingInterceptor.getFactory(), InterceptorOrder.View.CHECKING_INTERCEPTOR);
                    configuration.addViewInterceptor(new ImmediateInterceptorFactory(new ContextClassLoaderInterceptor(classLoader)), InterceptorOrder.View.TCCL_INTERCEPTOR);
                }
            });
            viewDescription.getBindingNames().addAll(Arrays.asList("java:module/" + beanName, "java:app/" + moduleDescription.getModuleName() + "/" + beanName));
            componentDescription.getViews().add(viewDescription);
            moduleDescription.addComponent(componentDescription);

            // register an EEResourceReferenceProcessor which can process @Resource references to this managed bean.
            registry.registerResourceReferenceProcessor(new ManagedBeanResourceReferenceProcessor(beanClassName));
        }
    }

    public void undeploy(DeploymentUnit context) {
    }

    /**
     * Returns true if the passed managedBeanClass meets the requirements set by the Managed bean spec about
     * bean implementation classes. The passed managedBeanClass must not be an interface and must not be final or abstract.
     * If it passes these requirements then this method returns true. Else it returns false.
     *
     * @param managedBeanClass The session bean class
     * @return
     */
    private static boolean assertManagedBeanClassValidity(final ClassInfo managedBeanClass) {
        final short flags = managedBeanClass.flags();
        final String className = managedBeanClass.name().toString();
        // must *not* be an interface
        if (Modifier.isInterface(flags)) {
            ROOT_LOGGER.invalidManagedBeanInterface("MB.2.1.1", className);
            return false;
        }
        // bean class must *not* be abstract or final
        if (Modifier.isAbstract(flags) || Modifier.isFinal(flags)) {
            ROOT_LOGGER.invalidManagedBeanAbstractOrFinal("MB.2.1.1", className);
            return false;
        }
        // valid class
        return true;
    }
}


/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2017, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.wildfly.extension.undertow;

import static org.jboss.as.controller.PersistentResourceXMLDescription.builder;

import org.jboss.as.controller.AttributeMarshaller;
import org.jboss.as.controller.AttributeParser;
import org.jboss.as.controller.PersistentResourceDefinition;
import org.jboss.as.controller.PersistentResourceXMLDescription;
import org.jboss.as.controller.PersistentResourceXMLParser;
import org.jboss.as.controller.operations.common.Util;
import org.wildfly.extension.undertow.filters.CustomFilterDefinition;
import org.wildfly.extension.undertow.filters.ErrorPageDefinition;
import org.wildfly.extension.undertow.filters.ExpressionFilterDefinition;
import org.wildfly.extension.undertow.filters.FilterDefinitions;
import org.wildfly.extension.undertow.filters.FilterRefDefinition;
import org.wildfly.extension.undertow.filters.GzipFilter;
import org.wildfly.extension.undertow.filters.ModClusterDefinition;
import org.wildfly.extension.undertow.filters.RequestLimitHandler;
import org.wildfly.extension.undertow.filters.ResponseHeaderFilter;
import org.wildfly.extension.undertow.filters.RewriteFilterDefinition;
import org.wildfly.extension.undertow.handlers.FileHandler;
import org.wildfly.extension.undertow.handlers.HandlerDefinitions;
import org.wildfly.extension.undertow.handlers.ReverseProxyHandler;
import org.wildfly.extension.undertow.handlers.ReverseProxyHandlerHost;

/**
 * @author Tomaz Cerar (c) 2012 Red Hat Inc.
 */
public class UndertowSubsystemParser_7_0 extends PersistentResourceXMLParser {
    private final PersistentResourceXMLDescription xmlDescription;

    UndertowSubsystemParser_7_0() {
        xmlDescription = builder(UndertowRootDefinition.INSTANCE.getPathElement(), Namespace.UNDERTOW_7_0.getUriString())
                .addAttributes(
                        UndertowRootDefinition.DEFAULT_SERVER,
                        UndertowRootDefinition.DEFAULT_VIRTUAL_HOST,
                        UndertowRootDefinition.DEFAULT_SERVLET_CONTAINER,
                        UndertowRootDefinition.INSTANCE_ID,
                        UndertowRootDefinition.DEFAULT_SECURITY_DOMAIN,
                        UndertowRootDefinition.STATISTICS_ENABLED)
                .addChild(
                        builder(ByteBufferPoolDefinition.INSTANCE.getPathElement())
                                .addAttributes(ByteBufferPoolDefinition.DIRECT, ByteBufferPoolDefinition.BUFFER_SIZE, ByteBufferPoolDefinition.MAX_POOL_SIZE, ByteBufferPoolDefinition.THREAD_LOCAL_CACHE_SIZE, ByteBufferPoolDefinition.LEAK_DETECTION_PERCENT)
                )
                .addChild(
                        builder(BufferCacheDefinition.INSTANCE.getPathElement())
                                .addAttributes(BufferCacheDefinition.BUFFER_SIZE, BufferCacheDefinition.BUFFERS_PER_REGION, BufferCacheDefinition.MAX_REGIONS)
                )
                .addChild(builder(ServerDefinition.INSTANCE.getPathElement())
                                .addAttributes(ServerDefinition.DEFAULT_HOST, ServerDefinition.SERVLET_CONTAINER)
                                .addChild(
                                        listenerBuilder(AjpListenerResourceDefinition.INSTANCE)
                                                // xsd ajp-listener-type
                                                .addAttributes(AjpListenerResourceDefinition.SCHEME,
                                                        ListenerResourceDefinition.REDIRECT_SOCKET,
                                                        AjpListenerResourceDefinition.MAX_AJP_PACKET_SIZE)
                                )
                                .addChild(
                                        listenerBuilder(HttpListenerResourceDefinition.INSTANCE)
                                                // xsd http-listener-type
                                                .addAttributes(
                                                        HttpListenerResourceDefinition.CERTIFICATE_FORWARDING,
                                                        ListenerResourceDefinition.REDIRECT_SOCKET,
                                                        HttpListenerResourceDefinition.PROXY_ADDRESS_FORWARDING,
                                                        HttpListenerResourceDefinition.ENABLE_HTTP2,
                                                        HttpListenerResourceDefinition.HTTP2_ENABLE_PUSH,
                                                        HttpListenerResourceDefinition.HTTP2_HEADER_TABLE_SIZE,
                                                        HttpListenerResourceDefinition.HTTP2_INITIAL_WINDOW_SIZE,
                                                        HttpListenerResourceDefinition.HTTP2_MAX_CONCURRENT_STREAMS,
                                                        HttpListenerResourceDefinition.HTTP2_MAX_FRAME_SIZE,
                                                        HttpListenerResourceDefinition.HTTP2_MAX_HEADER_LIST_SIZE,
                                                        HttpListenerResourceDefinition.REQUIRE_HOST_HTTP11,
                                                        HttpListenerResourceDefinition.PROXY_PROTOCOL)
                                ).addChild(
                                        listenerBuilder(HttpsListenerResourceDefinition.INSTANCE)
                                                // xsd https-listener-type
                                                .setMarshallDefaultValues(true)
                                                .addAttributes(
                                                        HttpsListenerResourceDefinition.SSL_CONTEXT,
                                                        HttpListenerResourceDefinition.PROXY_ADDRESS_FORWARDING,
                                                        HttpListenerResourceDefinition.CERTIFICATE_FORWARDING,
                                                        HttpsListenerResourceDefinition.SECURITY_REALM,
                                                        HttpsListenerResourceDefinition.VERIFY_CLIENT,
                                                        HttpsListenerResourceDefinition.ENABLED_CIPHER_SUITES,
                                                        HttpsListenerResourceDefinition.ENABLED_PROTOCOLS,
                                                        HttpsListenerResourceDefinition.ENABLE_HTTP2,
                                                        HttpsListenerResourceDefinition.ENABLE_SPDY,
                                                        HttpsListenerResourceDefinition.SSL_SESSION_CACHE_SIZE,
                                                        HttpsListenerResourceDefinition.SSL_SESSION_TIMEOUT,
                                                        HttpListenerResourceDefinition.HTTP2_ENABLE_PUSH,
                                                        HttpListenerResourceDefinition.HTTP2_HEADER_TABLE_SIZE,
                                                        HttpListenerResourceDefinition.HTTP2_INITIAL_WINDOW_SIZE,
                                                        HttpListenerResourceDefinition.HTTP2_MAX_CONCURRENT_STREAMS,
                                                        HttpListenerResourceDefinition.HTTP2_MAX_FRAME_SIZE,
                                                        HttpListenerResourceDefinition.HTTP2_MAX_HEADER_LIST_SIZE,
                                                        HttpListenerResourceDefinition.REQUIRE_HOST_HTTP11,
                                                        HttpListenerResourceDefinition.PROXY_PROTOCOL)
                                ).addChild(
                                        builder(HostDefinition.INSTANCE.getPathElement())
                                                .addAttributes(HostDefinition.ALIAS,
                                                        HostDefinition.DEFAULT_WEB_MODULE,
                                                        HostDefinition.DEFAULT_RESPONSE_CODE,
                                                        HostDefinition.DISABLE_CONSOLE_REDIRECT,
                                                        HostDefinition.QUEUE_REQUESTS_ON_START)
                                                .addChild(
                                                        builder(LocationDefinition.INSTANCE.getPathElement())
                                                                .addAttributes(LocationDefinition.HANDLER)
                                                                .addChild(filterRefBuilder())
                                                ).addChild(
                                                builder(AccessLogDefinition.INSTANCE.getPathElement())
                                                        .addAttributes(
                                                                AccessLogDefinition.PATTERN,
                                                                AccessLogDefinition.WORKER,
                                                                AccessLogDefinition.DIRECTORY,
                                                                AccessLogDefinition.RELATIVE_TO,
                                                                AccessLogDefinition.PREFIX,
                                                                AccessLogDefinition.SUFFIX,
                                                                AccessLogDefinition.ROTATE,
                                                                AccessLogDefinition.USE_SERVER_LOG,
                                                                AccessLogDefinition.EXTENDED,
                                                                AccessLogDefinition.PREDICATE)
                                        ).addChild(filterRefBuilder())
                                                .addChild(
                                                    builder(UndertowExtension.PATH_SSO)
                                                        .addAttribute(SingleSignOnDefinition.Attribute.DOMAIN.getDefinition())
                                                        .addAttribute(SingleSignOnDefinition.Attribute.PATH.getDefinition())
                                                        .addAttribute(SingleSignOnDefinition.Attribute.HTTP_ONLY.getDefinition())
                                                        .addAttribute(SingleSignOnDefinition.Attribute.SECURE.getDefinition())
                                                        .addAttribute(SingleSignOnDefinition.Attribute.COOKIE_NAME.getDefinition())
                                        ).addChild(builder(HttpInvokerDefinition.INSTANCE.getPathElement())
                                            .addAttributes(HttpInvokerDefinition.PATH, HttpInvokerDefinition.HTTP_AUTHENTICATION_FACTORY, HttpInvokerDefinition.SECURITY_REALM))
                                        )
                )
                .addChild(
                        builder(ServletContainerDefinition.INSTANCE.getPathElement())
                                .addAttribute(ServletContainerDefinition.ALLOW_NON_STANDARD_WRAPPERS)
                                .addAttribute(ServletContainerDefinition.DEFAULT_BUFFER_CACHE)
                                .addAttribute(ServletContainerDefinition.STACK_TRACE_ON_ERROR)
                                .addAttribute(ServletContainerDefinition.DEFAULT_ENCODING)
                                .addAttribute(ServletContainerDefinition.USE_LISTENER_ENCODING)
                                .addAttribute(ServletContainerDefinition.IGNORE_FLUSH)
                                .addAttribute(ServletContainerDefinition.EAGER_FILTER_INIT)
                                .addAttribute(ServletContainerDefinition.DEFAULT_SESSION_TIMEOUT)
                                .addAttribute(ServletContainerDefinition.DISABLE_CACHING_FOR_SECURED_PAGES)
                                .addAttribute(ServletContainerDefinition.DIRECTORY_LISTING)
                                .addAttribute(ServletContainerDefinition.PROACTIVE_AUTHENTICATION)
                                .addAttribute(ServletContainerDefinition.SESSION_ID_LENGTH)
                                .addAttribute(ServletContainerDefinition.MAX_SESSIONS)
                                .addAttribute(ServletContainerDefinition.DISABLE_FILE_WATCH_SERVICE)
                                .addAttribute(ServletContainerDefinition.DISABLE_SESSION_ID_REUSE)
                                .addAttribute(ServletContainerDefinition.FILE_CACHE_METADATA_SIZE)
                                .addAttribute(ServletContainerDefinition.FILE_CACHE_MAX_FILE_SIZE)
                                .addAttribute(ServletContainerDefinition.FILE_CACHE_TIME_TO_LIVE)
                                .addAttribute(ServletContainerDefinition.DEFAULT_COOKIE_VERSION)
                                .addChild(
                                        builder(JspDefinition.INSTANCE.getPathElement())
                                                .setXmlElementName(Constants.JSP_CONFIG)
                                                .addAttributes(
                                                        JspDefinition.DISABLED,
                                                        JspDefinition.DEVELOPMENT,
                                                        JspDefinition.KEEP_GENERATED,
                                                        JspDefinition.TRIM_SPACES,
                                                        JspDefinition.TAG_POOLING,
                                                        JspDefinition.MAPPED_FILE,
                                                        JspDefinition.CHECK_INTERVAL,
                                                        JspDefinition.MODIFICATION_TEST_INTERVAL,
                                                        JspDefinition.RECOMPILE_ON_FAIL,
                                                        JspDefinition.SMAP,
                                                        JspDefinition.DUMP_SMAP,
                                                        JspDefinition.GENERATE_STRINGS_AS_CHAR_ARRAYS,
                                                        JspDefinition.ERROR_ON_USE_BEAN_INVALID_CLASS_ATTRIBUTE,
                                                        JspDefinition.SCRATCH_DIR,
                                                        JspDefinition.SOURCE_VM,
                                                        JspDefinition.TARGET_VM,
                                                        JspDefinition.JAVA_ENCODING,
                                                        JspDefinition.X_POWERED_BY,
                                                        JspDefinition.DISPLAY_SOURCE_FRAGMENT,
                                                        JspDefinition.OPTIMIZE_SCRIPTLETS)
                                )
                                .addChild(
                                        builder(SessionCookieDefinition.INSTANCE.getPathElement())
                                                .addAttributes(
                                                        SessionCookieDefinition.NAME,
                                                        SessionCookieDefinition.DOMAIN,
                                                        SessionCookieDefinition.COMMENT,
                                                        SessionCookieDefinition.HTTP_ONLY,
                                                        SessionCookieDefinition.SECURE,
                                                        SessionCookieDefinition.MAX_AGE
                                                )
                                )
                                .addChild(
                                        builder(PersistentSessionsDefinition.INSTANCE.getPathElement())
                                                .addAttributes(
                                                        PersistentSessionsDefinition.PATH,
                                                        PersistentSessionsDefinition.RELATIVE_TO
                                                )
                                )
                                .addChild(
                                        builder(WebsocketsDefinition.INSTANCE.getPathElement())
                                                .setMarshallDefaultValues(true)
                                                .addAttributes(
                                                        WebsocketsDefinition.WORKER,
                                                        WebsocketsDefinition.BUFFER_POOL,
                                                        WebsocketsDefinition.DISPATCH_TO_WORKER,
                                                        WebsocketsDefinition.PER_MESSAGE_DEFLATE,
                                                        WebsocketsDefinition.DEFLATER_LEVEL
                                                )
                                )
                                .addChild(builder(MimeMappingDefinition.INSTANCE.getPathElement())
                                        .setXmlWrapperElement("mime-mappings")
                                        .addAttributes(
                                                MimeMappingDefinition.VALUE
                                        ))
                                .addChild(builder(WelcomeFileDefinition.INSTANCE.getPathElement()).setXmlWrapperElement("welcome-files"))
                                .addChild(builder(CrawlerSessionManagementDefinition.INSTANCE.getPathElement())
                                        .addAttributes(CrawlerSessionManagementDefinition.USER_AGENTS, CrawlerSessionManagementDefinition.SESSION_TIMEOUT))
                )
                .addChild(
                        builder(HandlerDefinitions.INSTANCE.getPathElement())
                                .setXmlElementName(Constants.HANDLERS)
                                .setNoAddOperation(true)
                                .addChild(
                                        builder(FileHandler.INSTANCE.getPathElement())
                                                .addAttributes(
                                                        FileHandler.PATH,
                                                        FileHandler.CACHE_BUFFER_SIZE,
                                                        FileHandler.CACHE_BUFFERS,
                                                        FileHandler.DIRECTORY_LISTING,
                                                        FileHandler.FOLLOW_SYMLINK,
                                                        FileHandler.SAFE_SYMLINK_PATHS,
                                                        FileHandler.CASE_SENSITIVE
                                                )
                                )
                                .addChild(
                                        builder(ReverseProxyHandler.INSTANCE.getPathElement())
                                                .addAttributes(
                                                        ReverseProxyHandler.CONNECTIONS_PER_THREAD,
                                                        ReverseProxyHandler.SESSION_COOKIE_NAMES,
                                                        ReverseProxyHandler.PROBLEM_SERVER_RETRY,
                                                        ReverseProxyHandler.MAX_REQUEST_TIME,
                                                        ReverseProxyHandler.REQUEST_QUEUE_SIZE,
                                                        ReverseProxyHandler.CACHED_CONNECTIONS_PER_THREAD,
                                                        ReverseProxyHandler.CONNECTION_IDLE_TIMEOUT,
                                                        ReverseProxyHandler.MAX_RETRIES)
                                                .addChild(builder(ReverseProxyHandlerHost.INSTANCE.getPathElement())
                                                        .setXmlElementName(Constants.HOST)
                                                        .addAttributes(
                                                                ReverseProxyHandlerHost.OUTBOUND_SOCKET_BINDING,
                                                                ReverseProxyHandlerHost.SCHEME,
                                                                ReverseProxyHandlerHost.PATH,
                                                                ReverseProxyHandlerHost.INSTANCE_ID,
                                                                ReverseProxyHandlerHost.SSL_CONTEXT,
                                                                ReverseProxyHandlerHost.SECURITY_REALM,
                                                                ReverseProxyHandlerHost.ENABLE_HTTP2))
                                )

                )
                .addChild(
                        builder(FilterDefinitions.INSTANCE.getPathElement())
                                .setXmlElementName(Constants.FILTERS)
                                .setNoAddOperation(true)
                                .addChild(
                                        builder(RequestLimitHandler.INSTANCE.getPathElement())
                                                .addAttributes(RequestLimitHandler.MAX_CONCURRENT_REQUESTS, RequestLimitHandler.QUEUE_SIZE)
                                ).addChild(
                                builder(ResponseHeaderFilter.INSTANCE.getPathElement())
                                        .addAttributes(ResponseHeaderFilter.NAME, ResponseHeaderFilter.VALUE)
                        ).addChild(
                                builder(GzipFilter.INSTANCE.getPathElement())
                        ).addChild(
                                builder(ErrorPageDefinition.INSTANCE.getPathElement())
                                        .addAttributes(ErrorPageDefinition.CODE, ErrorPageDefinition.PATH)
                        ).addChild(
                                builder(ModClusterDefinition.INSTANCE.getPathElement())
                                .addAttributes(ModClusterDefinition.MANAGEMENT_SOCKET_BINDING,
                                        ModClusterDefinition.ADVERTISE_SOCKET_BINDING,
                                        ModClusterDefinition.SECURITY_KEY,
                                        ModClusterDefinition.ADVERTISE_PROTOCOL,
                                        ModClusterDefinition.ADVERTISE_PATH,
                                        ModClusterDefinition.ADVERTISE_FREQUENCY,
                                        ModClusterDefinition.FAILOVER_STRATEGY,
                                        ModClusterDefinition.HEALTH_CHECK_INTERVAL,
                                        ModClusterDefinition.BROKEN_NODE_TIMEOUT,
                                        ModClusterDefinition.WORKER,
                                        ModClusterDefinition.MAX_REQUEST_TIME,
                                        ModClusterDefinition.MANAGEMENT_ACCESS_PREDICATE,
                                        ModClusterDefinition.CONNECTIONS_PER_THREAD,
                                        ModClusterDefinition.CACHED_CONNECTIONS_PER_THREAD,
                                        ModClusterDefinition.CONNECTION_IDLE_TIMEOUT,
                                        ModClusterDefinition.REQUEST_QUEUE_SIZE,
                                        ModClusterDefinition.SSL_CONTEXT,
                                        ModClusterDefinition.SECURITY_REALM,
                                        ModClusterDefinition.USE_ALIAS,
                                        ModClusterDefinition.ENABLE_HTTP2,
                                        ModClusterDefinition.MAX_AJP_PACKET_SIZE,
                                        ModClusterDefinition.HTTP2_ENABLE_PUSH,
                                        ModClusterDefinition.HTTP2_HEADER_TABLE_SIZE,
                                        ModClusterDefinition.HTTP2_INITIAL_WINDOW_SIZE,
                                        ModClusterDefinition.HTTP2_MAX_CONCURRENT_STREAMS,
                                        ModClusterDefinition.HTTP2_MAX_FRAME_SIZE,
                                        ModClusterDefinition.HTTP2_MAX_HEADER_LIST_SIZE,
                                        ModClusterDefinition.MAX_RETRIES)
                        ).addChild(
                                builder(CustomFilterDefinition.INSTANCE.getPathElement())
                                        .addAttributes(CustomFilterDefinition.CLASS_NAME, CustomFilterDefinition.MODULE, CustomFilterDefinition.PARAMETERS)
                                        .setXmlElementName("filter")
                        ).addChild(
                                builder(ExpressionFilterDefinition.INSTANCE.getPathElement())
                                        .addAttributes(ExpressionFilterDefinition.EXPRESSION, ExpressionFilterDefinition.MODULE)
                        ).addChild(
                                builder(RewriteFilterDefinition.INSTANCE.getPathElement())
                                        .addAttributes(RewriteFilterDefinition.TARGET, RewriteFilterDefinition.REDIRECT)
                        )

                )
                .addChild(
                        builder(ApplicationSecurityDomainDefinition.INSTANCE.getPathElement())
                            .setXmlWrapperElement(Constants.APPLICATION_SECURITY_DOMAINS)
                            .addAttributes(ApplicationSecurityDomainDefinition.HTTP_AUTHENTICATION_FACTORY, ApplicationSecurityDomainDefinition.OVERRIDE_DEPLOYMENT_CONFIG, ApplicationSecurityDomainDefinition.SECURITY_DOMAIN, ApplicationSecurityDomainDefinition.ENABLE_JACC)
                            .addChild(builder(UndertowExtension.PATH_SSO)
                                    .addAttribute(SingleSignOnDefinition.Attribute.DOMAIN.getDefinition())
                                    .addAttribute(SingleSignOnDefinition.Attribute.PATH.getDefinition())
                                    .addAttribute(SingleSignOnDefinition.Attribute.HTTP_ONLY.getDefinition())
                                    .addAttribute(SingleSignOnDefinition.Attribute.SECURE.getDefinition())
                                    .addAttribute(SingleSignOnDefinition.Attribute.COOKIE_NAME.getDefinition())
                                    .addAttribute(ApplicationSecurityDomainSingleSignOnDefinition.Attribute.KEY_STORE.getDefinition())
                                    .addAttribute(ApplicationSecurityDomainSingleSignOnDefinition.Attribute.KEY_ALIAS.getDefinition())
                                    .addAttribute(ApplicationSecurityDomainSingleSignOnDefinition.Attribute.SSL_CONTEXT.getDefinition())
                                    .addAttribute(ApplicationSecurityDomainSingleSignOnDefinition.Attribute.CREDENTIAL.getDefinition(), AttributeParser.OBJECT_PARSER, AttributeMarshaller.ATTRIBUTE_OBJECT)
                            )
                )
                 //here to make sure we always add filters & handlers path to mgmt model
                .setAdditionalOperationsGenerator((address, addOperation, operations) -> {
                        operations.add(Util.createAddOperation(address.append(UndertowExtension.PATH_FILTERS)));
                        operations.add(Util.createAddOperation(address.append(UndertowExtension.PATH_HANDLERS)));
                })
                .build();
    }

    @Override
    public PersistentResourceXMLDescription getParserDescription() {
                return xmlDescription;
        }

    /** Registers attributes common across listener types */
    private static PersistentResourceXMLDescription.PersistentResourceXMLBuilder listenerBuilder(PersistentResourceDefinition resource) {
        return builder(resource.getPathElement())
                // xsd socket-optionsType
                .addAttributes(
                        ListenerResourceDefinition.RECEIVE_BUFFER,
                        ListenerResourceDefinition.SEND_BUFFER,
                        ListenerResourceDefinition.BACKLOG,
                        ListenerResourceDefinition.KEEP_ALIVE,
                        ListenerResourceDefinition.READ_TIMEOUT,
                        ListenerResourceDefinition.WRITE_TIMEOUT,
                        ListenerResourceDefinition.MAX_CONNECTIONS)
                // xsd listener-type
                .addAttributes(
                        ListenerResourceDefinition.SOCKET_BINDING,
                        ListenerResourceDefinition.WORKER,
                        ListenerResourceDefinition.BUFFER_POOL,
                        ListenerResourceDefinition.ENABLED,
                        ListenerResourceDefinition.RESOLVE_PEER_ADDRESS,
                        ListenerResourceDefinition.MAX_ENTITY_SIZE,
                        ListenerResourceDefinition.BUFFER_PIPELINED_DATA,
                        ListenerResourceDefinition.MAX_HEADER_SIZE,
                        ListenerResourceDefinition.MAX_PARAMETERS,
                        ListenerResourceDefinition.MAX_HEADERS,
                        ListenerResourceDefinition.MAX_COOKIES,
                        ListenerResourceDefinition.ALLOW_ENCODED_SLASH,
                        ListenerResourceDefinition.DECODE_URL,
                        ListenerResourceDefinition.URL_CHARSET,
                        ListenerResourceDefinition.ALWAYS_SET_KEEP_ALIVE,
                        ListenerResourceDefinition.MAX_BUFFERED_REQUEST_SIZE,
                        ListenerResourceDefinition.RECORD_REQUEST_START_TIME,
                        ListenerResourceDefinition.ALLOW_EQUALS_IN_COOKIE_VALUE,
                        ListenerResourceDefinition.NO_REQUEST_TIMEOUT,
                        ListenerResourceDefinition.REQUEST_PARSE_TIMEOUT,
                        ListenerResourceDefinition.DISALLOWED_METHODS,
                        ListenerResourceDefinition.SECURE,
                        ListenerResourceDefinition.RFC6265_COOKIE_VALIDATION,
                        ListenerResourceDefinition.ALLOW_UNESCAPED_CHARACTERS_IN_URL);
    }

    private static PersistentResourceXMLDescription.PersistentResourceXMLBuilder filterRefBuilder() {
        return builder(FilterRefDefinition.INSTANCE.getPathElement())
                .addAttributes(FilterRefDefinition.PREDICATE, FilterRefDefinition.PRIORITY);
    }
}


/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2010, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.as.txn.subsystem;

import javax.management.MBeanServer;

import org.jboss.as.controller.Extension;
import org.jboss.as.controller.ExtensionContext;
import org.jboss.as.controller.ModelVersion;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.SubsystemRegistration;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.as.controller.descriptions.StandardResourceDescriptionResolver;
import org.jboss.as.controller.operations.common.GenericSubsystemDescribeHandler;
import org.jboss.as.controller.parsing.ExtensionParsingContext;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.controller.services.path.ResolvePathHandler;
import org.jboss.as.txn.logging.TransactionLogger;
import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceRegistry;

/**
 * The transaction management extension.
 *
 * @author David M. Lloyd
 * @author Emanuel Muckenhuber
 * @author Scott Stark (sstark@redhat.com) (C) 2011 Red Hat Inc.
 * @author Mike Musgrove (mmusgrov@redhat.com) (C) 2012 Red Hat Inc.
 */
public class TransactionExtension implements Extension {
    public static final String SUBSYSTEM_NAME = "transactions";
    /**
     * The operation name to resolve the object store path
     */
    public static final String RESOLVE_OBJECT_STORE_PATH = "resolve-object-store-path";

    private static final String RESOURCE_NAME = TransactionExtension.class.getPackage().getName() + ".LocalDescriptions";

    static final ModelVersion CURRENT_MODEL_VERSION = ModelVersion.create(5, 0, 0);

    private static final ServiceName MBEAN_SERVER_SERVICE_NAME = ServiceName.JBOSS.append("mbean", "server");
    static final PathElement LOG_STORE_PATH = PathElement.pathElement(LogStoreConstants.LOG_STORE, LogStoreConstants.LOG_STORE);
    static final PathElement SUBSYSTEM_PATH = PathElement.pathElement(ModelDescriptionConstants.SUBSYSTEM, TransactionExtension.SUBSYSTEM_NAME);
    static final PathElement PARTICIPANT_PATH = PathElement.pathElement(LogStoreConstants.PARTICIPANTS);
    static final PathElement TRANSACTION_PATH = PathElement.pathElement(LogStoreConstants.TRANSACTIONS);

    static StandardResourceDescriptionResolver getResourceDescriptionResolver(final String... keyPrefix) {
        StringBuilder prefix = new StringBuilder(SUBSYSTEM_NAME);
        for (String kp : keyPrefix) {
            prefix.append('.').append(kp);
        }
        return new StandardResourceDescriptionResolver(prefix.toString(), RESOURCE_NAME, TransactionExtension.class.getClassLoader(), true, false);
    }

    static MBeanServer getMBeanServer(OperationContext context) {
        final ServiceRegistry serviceRegistry = context.getServiceRegistry(false);
        final ServiceController<?> serviceController = serviceRegistry.getService(MBEAN_SERVER_SERVICE_NAME);
        if (serviceController == null) {
            throw TransactionLogger.ROOT_LOGGER.jmxSubsystemNotInstalled();
        }
        return (MBeanServer) serviceController.getValue();
    }

    /**
     * {@inheritDoc}
     */
    public void initialize(ExtensionContext context) {
        TransactionLogger.ROOT_LOGGER.debug("Initializing Transactions Extension");
        final LogStoreResource resource = new LogStoreResource();
        final boolean registerRuntimeOnly = context.isRuntimeOnlyRegistrationValid();
        final SubsystemRegistration subsystem = context.registerSubsystem(SUBSYSTEM_NAME, CURRENT_MODEL_VERSION);

        final TransactionSubsystemRootResourceDefinition rootResourceDefinition = new TransactionSubsystemRootResourceDefinition(registerRuntimeOnly);
        final ManagementResourceRegistration registration = subsystem.registerSubsystemModel(rootResourceDefinition);
        registration.registerOperationHandler(GenericSubsystemDescribeHandler.DEFINITION, GenericSubsystemDescribeHandler.INSTANCE);

        // Create the path resolver handlers
        if (context.getProcessType().isServer()) {
            // It's less than ideal to create a separate operation here, but this extension contains two relative-to attributes
            final ResolvePathHandler objectStorePathHandler = ResolvePathHandler.Builder.of(RESOLVE_OBJECT_STORE_PATH, context.getPathManager())
                   .setPathAttribute(TransactionSubsystemRootResourceDefinition.OBJECT_STORE_PATH)
                   .setRelativeToAttribute(TransactionSubsystemRootResourceDefinition.OBJECT_STORE_RELATIVE_TO)
                   .build();
            registration.registerOperationHandler(objectStorePathHandler.getOperationDefinition(), objectStorePathHandler);
        }

        ManagementResourceRegistration logStoreChild = registration.registerSubModel(new LogStoreDefinition(resource, registerRuntimeOnly));
        if (registerRuntimeOnly) {
            ManagementResourceRegistration transactionChild = logStoreChild.registerSubModel(new LogStoreTransactionDefinition(resource));
            transactionChild.registerSubModel(LogStoreTransactionParticipantDefinition.INSTANCE);
        }

        subsystem.registerXMLElementWriter(TransactionSubsystemXMLPersister.INSTANCE);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void initializeParsers(ExtensionParsingContext context) {
        context.setSubsystemXmlMapping(SUBSYSTEM_NAME, Namespace.TRANSACTIONS_1_0.getUriString(), TransactionSubsystem10Parser::new);
        context.setSubsystemXmlMapping(SUBSYSTEM_NAME, Namespace.TRANSACTIONS_1_1.getUriString(), TransactionSubsystem11Parser::new);
        context.setSubsystemXmlMapping(SUBSYSTEM_NAME, Namespace.TRANSACTIONS_1_2.getUriString(), TransactionSubsystem12Parser::new);
        context.setSubsystemXmlMapping(SUBSYSTEM_NAME, Namespace.TRANSACTIONS_1_3.getUriString(), TransactionSubsystem13Parser::new);
        context.setSubsystemXmlMapping(SUBSYSTEM_NAME, Namespace.TRANSACTIONS_1_4.getUriString(), TransactionSubsystem14Parser::new);
        context.setSubsystemXmlMapping(SUBSYSTEM_NAME, Namespace.TRANSACTIONS_1_5.getUriString(), TransactionSubsystem15Parser::new);
        context.setSubsystemXmlMapping(SUBSYSTEM_NAME, Namespace.TRANSACTIONS_2_0.getUriString(), TransactionSubsystem20Parser::new);
        context.setSubsystemXmlMapping(SUBSYSTEM_NAME, Namespace.TRANSACTIONS_3_0.getUriString(), TransactionSubsystem30Parser::new);
        context.setSubsystemXmlMapping(SUBSYSTEM_NAME, Namespace.TRANSACTIONS_4_0.getUriString(), TransactionSubsystem40Parser::new);
        context.setSubsystemXmlMapping(SUBSYSTEM_NAME, Namespace.TRANSACTIONS_5_0.getUriString(), TransactionSubsystem50Parser::new);
    }
}


/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2008, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.wildfly.iiop.openjdk.rmi;

import org.wildfly.iiop.openjdk.logging.IIOPLogger;

/**
 * Analysis class for primitive types.
 *

 * Routines here are conforming to the "Java(TM) Language to IDL Mapping
 * Specification", version 1.1 (01-06-07).
 *
 * @author Ole Husgaard
 */
public class PrimitiveAnalysis extends ClassAnalysis {

    public static final PrimitiveAnalysis voidAnalysis = new PrimitiveAnalysis(Void.TYPE, "void", "void");
    public static final PrimitiveAnalysis booleanAnalysis = new PrimitiveAnalysis(Boolean.TYPE, "boolean", "boolean");
    public static final PrimitiveAnalysis charAnalysis = new PrimitiveAnalysis(Character.TYPE, "wchar", "char");
    public static final PrimitiveAnalysis byteAnalysis = new PrimitiveAnalysis(Byte.TYPE, "octet", "byte");
    public static final PrimitiveAnalysis shortAnalysis = new PrimitiveAnalysis(Short.TYPE, "short", "short");
    public static final PrimitiveAnalysis intAnalysis = new PrimitiveAnalysis(Integer.TYPE, "long", "int");
    public static final PrimitiveAnalysis longAnalysis = new PrimitiveAnalysis(Long.TYPE, "long_long", "long");
    public static final PrimitiveAnalysis floatAnalysis = new PrimitiveAnalysis(Float.TYPE, "float", "float");
    public static final PrimitiveAnalysis doubleAnalysis = new PrimitiveAnalysis(Double.TYPE, "double", "double");

    private PrimitiveAnalysis(final Class cls, final String idlName, final String javaName) {
        super(cls, idlName, javaName);
    }

    /**
     * Get a singleton instance representing one of the primitive types.
     */
    public static PrimitiveAnalysis getPrimitiveAnalysis(final Class cls) {
        if (cls == null)
            throw IIOPLogger.ROOT_LOGGER.cannotAnalyzeNullClass();

        if (cls == Void.TYPE)
            return voidAnalysis;
        if (cls == Boolean.TYPE)
            return booleanAnalysis;
        if (cls == Character.TYPE)
            return charAnalysis;
        if (cls == Byte.TYPE)
            return byteAnalysis;
        if (cls == Short.TYPE)
            return shortAnalysis;
        if (cls == Integer.TYPE)
            return intAnalysis;
        if (cls == Long.TYPE)
            return longAnalysis;
        if (cls == Float.TYPE)
            return floatAnalysis;
        if (cls == Double.TYPE)
            return doubleAnalysis;

        throw IIOPLogger.ROOT_LOGGER.notAPrimitive(cls.getName());
    }

}


/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2014, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 2110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.as.ejb3.component.interceptors;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

import org.jboss.as.ejb3.logging.EjbLogger;
import org.jboss.invocation.Interceptor;
import org.jboss.invocation.InterceptorContext;
import org.jboss.invocation.InterceptorFactory;
import org.jboss.invocation.InterceptorFactoryContext;

/**
 * A per component interceptor that allows the EJB to shutdown gracefully.
 *
 * @author Stuart Douglas
 */
public class ShutDownInterceptorFactory implements InterceptorFactory {

    private static final int SHUTDOWN_FLAG = 1 << 31;
    private static final int INVERSE_SHUTDOWN_FLAG = ~SHUTDOWN_FLAG;

    private static final AtomicIntegerFieldUpdater<ShutDownInterceptorFactory> updater = AtomicIntegerFieldUpdater.newUpdater(ShutDownInterceptorFactory.class, "invocationCount");

    @SuppressWarnings("unused")
    private volatile int invocationCount;

    private final Object lock = new Object();

    private Interceptor interceptor = new Interceptor() {
        @Override
        public Object processInvocation(InterceptorContext context) throws Exception {

            int value;
            int oldValue;
            do {
                oldValue = invocationCount;
                if ((oldValue & SHUTDOWN_FLAG) != 0) {
                    throw EjbLogger.ROOT_LOGGER.componentIsShuttingDown();
                }
                value = oldValue + 1;
            } while (!updater.compareAndSet(ShutDownInterceptorFactory.this, oldValue, value));
            try {
                return context.proceed();
            } finally {
                do {
                    oldValue = invocationCount;
                    boolean shutDown = (oldValue & SHUTDOWN_FLAG) != 0;
                    int oldCount = oldValue & INVERSE_SHUTDOWN_FLAG;
                    value = oldCount - 1;
                    if(shutDown) {
                        value = value | SHUTDOWN_FLAG;
                    }
                } while (!updater.compareAndSet(ShutDownInterceptorFactory.this, oldValue, value));
                //if the count is zero and the component is shutting down
                if (value == SHUTDOWN_FLAG) {
                    synchronized (lock) {
                        lock.notifyAll();
                    }
                }
            }
        }
    };

    @Override
    public Interceptor create(InterceptorFactoryContext context) {
        return interceptor;
    }

    /**
     * Upon calling this method the EJB will be set to a shutdown state, and no further invocations will be allowed.
     * It will then wait for all active invocation to finish and then return.
     */
    public void shutdown() {
        int value;
        int oldValue;
        //set the shutdown bit
        do {
            oldValue = invocationCount;
            value = SHUTDOWN_FLAG | oldValue;
            //the component has already been shutdown
            if (oldValue == value) {
                return;
            }
        } while (!updater.compareAndSet(this, oldValue, value));

        synchronized (lock) {
            value = invocationCount;
            while (value != SHUTDOWN_FLAG) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                value = invocationCount;
                if((value & SHUTDOWN_FLAG) == 0) {
                    return; //component has been restarted
                }
            }
        }
    }

    public void start() {
        int value;
        int oldValue;
        //set the shutdown bit
        do {
            oldValue = invocationCount;
            value = INVERSE_SHUTDOWN_FLAG & oldValue;
            //the component has already been started
            if (oldValue == value) {
                return;
            }
        } while (!updater.compareAndSet(this, oldValue, value));
        synchronized (lock) {
            lock.notifyAll();
        }
    }
}


/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2011, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.as.jpa.service;

import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;

import javax.enterprise.inject.spi.BeanManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceProvider;
import javax.sql.DataSource;
import javax.validation.ValidatorFactory;

import org.jboss.as.jpa.beanmanager.BeanManagerAfterDeploymentValidation;
import org.jboss.as.jpa.beanmanager.ProxyBeanManager;
import org.jboss.as.jpa.classloader.TempClassLoaderFactoryImpl;
import org.jboss.as.jpa.spi.PersistenceUnitService;
import org.jboss.as.jpa.subsystem.PersistenceUnitRegistryImpl;
import org.jboss.as.jpa.util.JPAServiceNames;
import org.jboss.as.naming.WritableServiceBasedNamingStore;
import org.jboss.as.server.deployment.SetupAction;
import org.jboss.msc.inject.Injector;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.StartContext;
import org.jboss.msc.service.StartException;
import org.jboss.msc.service.StopContext;
import org.jboss.msc.value.InjectedValue;
import org.jipijapa.plugin.spi.EntityManagerFactoryBuilder;
import org.jipijapa.plugin.spi.PersistenceProviderAdaptor;
import org.jipijapa.plugin.spi.PersistenceUnitMetadata;
import org.wildfly.security.manager.action.GetAccessControlContextAction;
import org.wildfly.security.manager.WildFlySecurityManager;

import static org.jboss.as.jpa.messages.JpaLogger.ROOT_LOGGER;

/**
 * Persistence Unit service that is created for each deployed persistence unit that will be referenced by the
 * persistence context/unit injector.
 *

 * The persistence unit scoped
 *
 * @author Scott Marlow
 * @author Richard Opalka
 */
public class PersistenceUnitServiceImpl implements Service<PersistenceUnitService>, PersistenceUnitService {
    private final InjectedValue<DataSource> jtaDataSource = new InjectedValue<DataSource>();
    private final InjectedValue<DataSource> nonJtaDataSource = new InjectedValue<DataSource>();
    private final InjectedValue<ExecutorService> executorInjector = new InjectedValue<ExecutorService>();
    private final InjectedValue<BeanManager> beanManagerInjector = new InjectedValue<>();
    private final InjectedValue<PhaseOnePersistenceUnitServiceImpl> phaseOnePersistenceUnitServiceInjectedValue = new InjectedValue<>();

    private static final String CDI_BEAN_MANAGER = "javax.persistence.bean.manager";
    private static final String VALIDATOR_FACTORY = "javax.persistence.validation.factory";

    private final Map properties;
    private final PersistenceProviderAdaptor persistenceProviderAdaptor;
    private final PersistenceProvider persistenceProvider;
    private final PersistenceUnitMetadata pu;
    private final ClassLoader classLoader;
    private final PersistenceUnitRegistryImpl persistenceUnitRegistry;
    private final ServiceName deploymentUnitServiceName;
    private final ValidatorFactory validatorFactory;
    private final BeanManagerAfterDeploymentValidation beanManagerAfterDeploymentValidation;

    private volatile EntityManagerFactory entityManagerFactory;
    private volatile ProxyBeanManager proxyBeanManager;
    private final SetupAction javaNamespaceSetup;

    public PersistenceUnitServiceImpl(
            final Map properties,
            final ClassLoader classLoader,
            final PersistenceUnitMetadata pu,
            final PersistenceProviderAdaptor persistenceProviderAdaptor,
            final PersistenceProvider persistenceProvider,
            final PersistenceUnitRegistryImpl persistenceUnitRegistry,
            final ServiceName deploymentUnitServiceName,
            final ValidatorFactory validatorFactory, SetupAction javaNamespaceSetup,
            BeanManagerAfterDeploymentValidation beanManagerAfterDeploymentValidation) {
        this.properties = properties;
        this.pu = pu;
        this.persistenceProviderAdaptor = persistenceProviderAdaptor;
        this.persistenceProvider = persistenceProvider;
        this.classLoader = classLoader;
        this.persistenceUnitRegistry = persistenceUnitRegistry;
        this.deploymentUnitServiceName = deploymentUnitServiceName;
        this.validatorFactory = validatorFactory;
        this.javaNamespaceSetup = javaNamespaceSetup;
        this.beanManagerAfterDeploymentValidation = beanManagerAfterDeploymentValidation;
    }

    @Override
    public void start(final StartContext context) throws StartException {
        final ExecutorService executor = executorInjector.getValue();
        final AccessControlContext accessControlContext =
                AccessController.doPrivileged(GetAccessControlContextAction.getInstance());

        final Runnable task = new Runnable() {
            // run async in a background thread
            @Override
            public void run() {
                PrivilegedAction<Void> privilegedAction =
                        new PrivilegedAction<Void>() {
                            // run as security privileged action
                            @Override
                            public Void run() {

                                ClassLoader old = Thread.currentThread().getContextClassLoader();
                                Thread.currentThread().setContextClassLoader(classLoader);
                                if(javaNamespaceSetup != null) {
                                    javaNamespaceSetup.setup(Collections.<String, Object>emptyMap());
                                }

                                try {
                                    PhaseOnePersistenceUnitServiceImpl phaseOnePersistenceUnitService = phaseOnePersistenceUnitServiceInjectedValue.getOptionalValue();
                                    WritableServiceBasedNamingStore.pushOwner(deploymentUnitServiceName);
                                    Object wrapperBeanManagerLifeCycle=null;

                                    // as per JPA specification contract, always pass ValidatorFactory in via standard property before
                                    // creating container EntityManagerFactory
                                    if (validatorFactory != null) {
                                        properties.put(VALIDATOR_FACTORY, validatorFactory);
                                    }

                                    // handle phase 2 of 2 of bootstrapping the persistence unit
                                    if (phaseOnePersistenceUnitService != null) {
                                        ROOT_LOGGER.startingPersistenceUnitService(2, pu.getScopedPersistenceUnitName());
                                        // indicate that the second phase of bootstrapping the persistence unit has started
                                        phaseOnePersistenceUnitService.setSecondPhaseStarted(true);
                                        if (beanManagerInjector.getOptionalValue() != null) {
                                            wrapperBeanManagerLifeCycle = phaseOnePersistenceUnitService.getBeanManagerLifeCycle();
                                            // update the bean manager proxy to the actual CDI bean manager
                                            proxyBeanManager = phaseOnePersistenceUnitService.getBeanManager();
                                            proxyBeanManager.setDelegate(beanManagerInjector.getOptionalValue());
                                        }
                                        EntityManagerFactoryBuilder emfBuilder = phaseOnePersistenceUnitService.getEntityManagerFactoryBuilder();

                                        // always pass the ValidatorFactory before starting the second phase of the
                                        // persistence unit bootstrap.
                                        if (validatorFactory != null) {
                                            emfBuilder.withValidatorFactory(validatorFactory);
                                        }

                                        // get the EntityManagerFactory from the second phase of the persistence unit bootstrap
                                        entityManagerFactory = emfBuilder.build();
                                    } else {
                                        ROOT_LOGGER.startingService("Persistence Unit", pu.getScopedPersistenceUnitName());
                                        // start the persistence unit in one pass (1 of 1)
                                        pu.setTempClassLoaderFactory(new TempClassLoaderFactoryImpl(classLoader));
                                        pu.setJtaDataSource(jtaDataSource.getOptionalValue());
                                        pu.setNonJtaDataSource(nonJtaDataSource.getOptionalValue());

                                        if (beanManagerInjector.getOptionalValue() != null) {
                                            proxyBeanManager = new ProxyBeanManager();
                                            proxyBeanManager.setDelegate(beanManagerInjector.getOptionalValue());
                                            wrapperBeanManagerLifeCycle = persistenceProviderAdaptor.beanManagerLifeCycle(proxyBeanManager);
                                            if (wrapperBeanManagerLifeCycle != null) {
                                              // pass the wrapper object representing the bean manager life cycle object
                                              properties.put(CDI_BEAN_MANAGER, wrapperBeanManagerLifeCycle);
                                            }
                                            else {
                                              properties.put(CDI_BEAN_MANAGER, proxyBeanManager);
                                            }
                                        }
                                        entityManagerFactory = createContainerEntityManagerFactory();
                                    }
                                    persistenceUnitRegistry.add(getScopedPersistenceUnitName(), getValue());
                                    if(wrapperBeanManagerLifeCycle != null) {
                                        beanManagerAfterDeploymentValidation.register(persistenceProviderAdaptor, wrapperBeanManagerLifeCycle);
                                    }
                                    context.complete();
                                } catch (Throwable t) {
                                    context.failed(new StartException(t));
                                } finally {
                                    Thread.currentThread().setContextClassLoader(old);
                                    pu.setTempClassLoaderFactory(null);    // release the temp classloader factory (only needed when creating the EMF)
                                    WritableServiceBasedNamingStore.popOwner();

                                    if (javaNamespaceSetup != null) {
                                        javaNamespaceSetup.teardown(Collections.<String, Object>emptyMap());
                                    }
                                }
                                return null;
                            }

                        };
                WildFlySecurityManager.doChecked(privilegedAction, accessControlContext);

            }

        };
        try {
            executor.execute(task);
        } catch (RejectedExecutionException e) {
            task.run();
        } finally {
            context.asynchronous();
        }
    }

    @Override
    public void stop(final StopContext context) {
        final ExecutorService executor = executorInjector.getValue();
        final AccessControlContext accessControlContext =
                AccessController.doPrivileged(GetAccessControlContextAction.getInstance());
        final Runnable task = new Runnable() {
            // run async in a background thread
            @Override
            public void run() {
                PrivilegedAction<Void> privilegedAction =
                        new PrivilegedAction<Void>() {
                            // run as security privileged action
                            @Override
                            public Void run() {

                                if (phaseOnePersistenceUnitServiceInjectedValue.getOptionalValue() != null) {
                                    ROOT_LOGGER.stoppingPersistenceUnitService(2, pu.getScopedPersistenceUnitName());
                                } else {
                                    ROOT_LOGGER.stoppingService("Persistence Unit", pu.getScopedPersistenceUnitName());
                                }
                                ClassLoader old = Thread.currentThread().getContextClassLoader();
                                Thread.currentThread().setContextClassLoader(classLoader);
                                if(javaNamespaceSetup != null) {
                                    javaNamespaceSetup.setup(Collections.<String, Object>emptyMap());
                                }
                                try {
                                    if (entityManagerFactory != null) {
                                        // protect against race condition reported by WFLY-11563
                                        synchronized (this) {
                                            if (entityManagerFactory != null) {
                                                WritableServiceBasedNamingStore.pushOwner(deploymentUnitServiceName);
                                                try {
                                                    if (entityManagerFactory.isOpen()) {
                                                        entityManagerFactory.close();
                                                    }
                                                } catch (Throwable t) {
                                                    ROOT_LOGGER.failedToStopPUService(t, pu.getScopedPersistenceUnitName());
                                                } finally {
                                                    entityManagerFactory = null;
                                                    pu.setTempClassLoaderFactory(null);
                                                    WritableServiceBasedNamingStore.popOwner();
                                                    persistenceUnitRegistry.remove(getScopedPersistenceUnitName());
                                                }
                                            }
                                        }
                                    }
                                } finally {
                                    Thread.currentThread().setContextClassLoader(old);
                                    if (javaNamespaceSetup != null) {
                                        javaNamespaceSetup.teardown(Collections.<String, Object>emptyMap());
                                    }
                                }
                                if (proxyBeanManager != null) {
                                    synchronized (this) {
                                        if (proxyBeanManager != null) {
                                            proxyBeanManager.setDelegate(null);
                                            proxyBeanManager = null;
                                        }
                                    }
                                }
                                context.complete();
                                return null;
                            }
                        };
                WildFlySecurityManager.doChecked(privilegedAction, accessControlContext);
            }

        };
        try {
            executor.execute(task);
        } catch (RejectedExecutionException e) {
            task.run();
        } finally {
            context.asynchronous();
        }
    }

    public InjectedValue<ExecutorService> getExecutorInjector() {
        return executorInjector;
    }

    @Override
    public PersistenceUnitServiceImpl getValue() throws IllegalStateException, IllegalArgumentException {
        return this;
    }

    /**
     * Get the entity manager factory
     *
     * @return the entity manager factory
     */
    @Override
    public EntityManagerFactory getEntityManagerFactory() {
        return entityManagerFactory;
    }

    @Override
    public String getScopedPersistenceUnitName() {
        return pu.getScopedPersistenceUnitName();
    }

    public Injector<DataSource> getJtaDataSourceInjector() {
        return jtaDataSource;
    }

    public Injector<DataSource> getNonJtaDataSourceInjector() {
        return nonJtaDataSource;
    }

    public Injector<BeanManager> getBeanManagerInjector() {
        return beanManagerInjector;
    }

    /**
     * Returns the Persistence Unit service name used for creation or lookup.
     * The service name contains the unique fully scoped persistence unit name
     *
     * @param pu persistence unit definition
     * @return
     */
    public static ServiceName getPUServiceName(PersistenceUnitMetadata pu) {
        return JPAServiceNames.getPUServiceName(pu.getScopedPersistenceUnitName());
    }

    public static ServiceName getPUServiceName(String scopedPersistenceUnitName) {
        return JPAServiceNames.getPUServiceName(scopedPersistenceUnitName);
    }

    /**
     * Create EE container entity manager factory
     *
     * @return EntityManagerFactory
     */
    private EntityManagerFactory createContainerEntityManagerFactory() {
        persistenceProviderAdaptor.beforeCreateContainerEntityManagerFactory(pu);
        try {
            ROOT_LOGGER.tracef("calling createContainerEntityManagerFactory for pu=%s with integration properties=%s, application properties=%s",
                    pu.getScopedPersistenceUnitName(), properties, pu.getProperties());
            return persistenceProvider.createContainerEntityManagerFactory(pu, properties);
        } finally {
            try {
                persistenceProviderAdaptor.afterCreateContainerEntityManagerFactory(pu);
            } finally {
                pu.setAnnotationIndex(null);    // close reference to Annotation Index (only needed during call to createContainerEntityManagerFactory)
                //This is needed if the datasource is restarted
                //pu.setTempClassLoaderFactory(null);    // close reference to temp classloader factory (only needed during call to createEntityManagerFactory)
            }
        }
    }

    public Injector<PhaseOnePersistenceUnitServiceImpl> getPhaseOnePersistenceUnitServiceImplInjector() {
        return phaseOnePersistenceUnitServiceInjectedValue;
    }
}


/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2009, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.as.webservices.util;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.jboss.metadata.javaee.spec.ParamValueMetaData;
import org.jboss.metadata.web.jboss.JBossServletMetaData;
import org.jboss.metadata.web.jboss.JBossServletsMetaData;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
import org.jboss.metadata.web.spec.AuthConstraintMetaData;
import org.jboss.metadata.web.spec.LoginConfigMetaData;
import org.jboss.metadata.web.spec.SecurityConstraintMetaData;
import org.jboss.metadata.web.spec.ServletMappingMetaData;
import org.jboss.metadata.web.spec.ServletMetaData;
import org.jboss.metadata.web.spec.TransportGuaranteeType;
import org.jboss.metadata.web.spec.UserDataConstraintMetaData;
import org.jboss.metadata.web.spec.WebResourceCollectionMetaData;
import org.jboss.metadata.web.spec.WebResourceCollectionsMetaData;

/**
 * Utility class that simplifies work with JBossWebMetaData object structure.
 *
 * @author Richard Opalka
 * @author Thomas Diesler
 */
public final class WebMetaDataHelper {
    /** Star utility string. */
    private static final String STAR_STRING = "*";

    /** GET http method utility string. */
    private static final String GET_STRING = "GET";

    /** POST http method utility string. */
    private static final String POST_STRING = "POST";

    /** GET and POST methods utility list. */
    private static List<String> getAndPostMethods;

    /** POST method utility list. */
    private static List<String> onlyPostMethod;

    /** All roles utility list. */
    private static List<String> allRoles;

    static {
        final List<String> getAndPostList = new LinkedList<String>();
        getAndPostList.add(WebMetaDataHelper.GET_STRING);
        getAndPostList.add(WebMetaDataHelper.POST_STRING);
        WebMetaDataHelper.getAndPostMethods = Collections.unmodifiableList(getAndPostList);

        final List<String> onlyPostList = new LinkedList<String>();
        onlyPostList.add(WebMetaDataHelper.POST_STRING);
        WebMetaDataHelper.onlyPostMethod = Collections.unmodifiableList(onlyPostList);

        final List<String> roleNamesList = new LinkedList<String>();
        roleNamesList.add(WebMetaDataHelper.STAR_STRING);
        WebMetaDataHelper.allRoles = Collections.unmodifiableList(roleNamesList);
    }

    /**
     * Constructor.
     */
    private WebMetaDataHelper() {
        super();
    }

    /**
     * Creates URL pattern list from passed string.
     *
     * @param urlPattern URL pattern
     * @return list wrapping passed parameter
     */
    public static List<String> getUrlPatterns(final String urlPattern) {
        final List<String> linkedList = new LinkedList<String>();

        linkedList.add(urlPattern);

        return linkedList;
    }

    /**
     * If WSDL access is secured, it returns both POST and GET methods, otherwise only POST method.
     *
     * @param secureWsdlAccess whether WSDL is secured
     * @return web access methods
     */
    public static List<String> getHttpMethods(final boolean secureWsdlAccess) {
        return secureWsdlAccess ? WebMetaDataHelper.getAndPostMethods : WebMetaDataHelper.onlyPostMethod;
    }

    /**
     * Returns all role list.
     *
     * @return all role list
     */
    public static List<String> getAllRoles() {
        return WebMetaDataHelper.allRoles;
    }

    /**
     * Gets servlets meta data from jboss web meta data. If not found it creates new servlets meta data and associates them
     * with jboss web meta data.
     *
     * @param jbossWebMD jboss web meta data
     * @return servlets meta data
     */
    public static JBossServletsMetaData getServlets(final JBossWebMetaData jbossWebMD) {
        JBossServletsMetaData servletsMD = jbossWebMD.getServlets();

        if (servletsMD == null) {
            servletsMD = new JBossServletsMetaData();
            jbossWebMD.setServlets(servletsMD);
        }

        return servletsMD;
    }

    /**
     * Gets servlet mappings meta data from jboss web meta data. If not found it creates new servlet mappings meta data and
     * associates them with jboss web meta data.
     *
     * @param jbossWebMD jboss web meta data
     * @return servlet mappings meta data
     */
    public static List<ServletMappingMetaData> getServletMappings(final JBossWebMetaData jbossWebMD) {
        List<ServletMappingMetaData> servletMappingsMD = jbossWebMD.getServletMappings();

        if (servletMappingsMD == null) {
            servletMappingsMD = new LinkedList<ServletMappingMetaData>();
            jbossWebMD.setServletMappings(servletMappingsMD);
        }

        return servletMappingsMD;
    }

    /**
     * Gets security constraints meta data from jboss web meta data. If not found it creates new security constraints meta data
     * and associates them with jboss web meta data.
     *
     * @param jbossWebMD jboss web meta data
     * @return security constraints meta data
     */
    public static List<SecurityConstraintMetaData> getSecurityConstraints(final JBossWebMetaData jbossWebMD) {
        List<SecurityConstraintMetaData> securityConstraintsMD = jbossWebMD.getSecurityConstraints();

        if (securityConstraintsMD == null) {
            securityConstraintsMD = new LinkedList<SecurityConstraintMetaData>();
            jbossWebMD.setSecurityConstraints(securityConstraintsMD);
        }

        return securityConstraintsMD;
    }

    /**
     * Gets login config meta data from jboss web meta data. If not found it creates new login config meta data and associates
     * them with jboss web meta data.
     *
     * @param jbossWebMD jboss web meta data
     * @return login config meta data
     */
    public static LoginConfigMetaData getLoginConfig(final JBossWebMetaData jbossWebMD) {
        LoginConfigMetaData loginConfigMD = jbossWebMD.getLoginConfig();

        if (loginConfigMD == null) {
            loginConfigMD = new LoginConfigMetaData();
            jbossWebMD.setLoginConfig(loginConfigMD);
        }

        return loginConfigMD;
    }

    /**
     * Gets context parameters meta data from jboss web meta data. If not found it creates new context parameters meta data and
     * associates them with jboss web meta data.
     *
     * @param jbossWebMD jboss web meta data
     * @return context parameters meta data
     */
    public static List<ParamValueMetaData> getContextParams(final JBossWebMetaData jbossWebMD) {
        List<ParamValueMetaData> contextParamsMD = jbossWebMD.getContextParams();

        if (contextParamsMD == null) {
            contextParamsMD = new LinkedList<ParamValueMetaData>();
            jbossWebMD.setContextParams(contextParamsMD);
        }

        return contextParamsMD;
    }

    /**
     * Gets web resource collections meta data from security constraint meta data. If not found it creates new web resource
     * collections meta data and associates them with security constraint meta data.
     *
     * @param securityConstraintMD security constraint meta data
     * @return web resource collections meta data
     */
    public static WebResourceCollectionsMetaData getWebResourceCollections(final SecurityConstraintMetaData securityConstraintMD) {
        WebResourceCollectionsMetaData webResourceCollectionsMD = securityConstraintMD.getResourceCollections();

        if (webResourceCollectionsMD == null) {
            webResourceCollectionsMD = new WebResourceCollectionsMetaData();
            securityConstraintMD.setResourceCollections(webResourceCollectionsMD);
        }

        return webResourceCollectionsMD;
    }

    /**
     * Gets init parameters meta data from servlet meta data. If not found it creates new init parameters meta data and
     * associates them with servlet meta data.
     *
     * @param servletMD servlet meta data
     * @return init parameters meta data
     */
    public static List<ParamValueMetaData> getServletInitParams(final ServletMetaData servletMD) {
        List<ParamValueMetaData> initParamsMD = servletMD.getInitParam();

        if (initParamsMD == null) {
            initParamsMD = new LinkedList<ParamValueMetaData>();
            servletMD.setInitParam(initParamsMD);
        }

        return initParamsMD;
    }

    /**
     * Creates new security constraint meta data and associates them with security constraints meta data.
     *
     * @param securityConstraintsMD security constraints meta data
     * @return new security constraing meta data
     */
    public static SecurityConstraintMetaData newSecurityConstraint(final List<SecurityConstraintMetaData> securityConstraintsMD) {
        final SecurityConstraintMetaData securityConstraintMD = new SecurityConstraintMetaData();

        securityConstraintsMD.add(securityConstraintMD);

        return securityConstraintMD;
    }

    /**
     * Creates new web resource collection meta data and associates them with web resource collections meta data.
     *
     * @param servletName servlet name
     * @param urlPattern URL pattern
     * @param securedWsdl whether WSDL access is secured
     * @param webResourceCollectionsMD web resource collections meta data
     * @return new web resource collection meta data
     */
    public static WebResourceCollectionMetaData newWebResourceCollection(final String servletName, final String urlPattern,
            final boolean securedWsdl, final WebResourceCollectionsMetaData webResourceCollectionsMD) {
        final WebResourceCollectionMetaData webResourceCollectionMD = new WebResourceCollectionMetaData();

        webResourceCollectionMD.setWebResourceName(servletName);
        webResourceCollectionMD.setUrlPatterns(WebMetaDataHelper.getUrlPatterns(urlPattern));
        webResourceCollectionMD.setHttpMethods(WebMetaDataHelper.getHttpMethods(securedWsdl));
        webResourceCollectionsMD.add(webResourceCollectionMD);

        return webResourceCollectionMD;
    }

    /**
     * Creates new servlet meta data and associates them with servlets meta data.
     *
     * @param servletName servlet name
     * @param servletClass servlet class name
     * @param servletsMD servlets meta data
     * @return new servlet meta data
     */
    public static JBossServletMetaData newServlet(final String servletName, final String servletClass,
            final JBossServletsMetaData servletsMD) {
        final JBossServletMetaData servletMD = new JBossServletMetaData();

        servletMD.setServletName(servletName);
        servletMD.setServletClass(servletClass);
        servletsMD.add(servletMD);

        return servletMD;
    }

    /**
     * Creates new servlet mapping meta data and associates them with servlet mappings meta data.
     *
     * @param servletName servlet name
     * @param urlPatterns URL patterns
     * @param servletMappingsMD servlet mapping meta data
     * @return new servlet mapping meta data
     */
    public static ServletMappingMetaData newServletMapping(final String servletName, final List<String> urlPatterns,
            final List<ServletMappingMetaData> servletMappingsMD) {
        final ServletMappingMetaData servletMappingMD = new ServletMappingMetaData();

        servletMappingMD.setServletName(servletName);
        servletMappingMD.setUrlPatterns(urlPatterns);
        servletMappingsMD.add(servletMappingMD);

        return servletMappingMD;
    }

    /**
     * Creates new authentication constraint and associates it with security constraint meta data.
     *
     * @param roleNames roles
     * @param securityConstraintMD security constraint meta data
     * @return new authentication constraint meta data
     */
    public static AuthConstraintMetaData newAuthConstraint(final List<String> roleNames,
            final SecurityConstraintMetaData securityConstraintMD) {
        final AuthConstraintMetaData authConstraintMD = new AuthConstraintMetaData();

        authConstraintMD.setRoleNames(roleNames);
        securityConstraintMD.setAuthConstraint(authConstraintMD);

        return authConstraintMD;
    }

    /**
     * Creates new user constraint meta data and associates it with security constraint meta data.
     *
     * @param transportGuarantee transport guarantee value
     * @param securityConstraintMD security constraint meta data
     * @return new user data constraint meta data
     */
    public static UserDataConstraintMetaData newUserDataConstraint(final String transportGuarantee,
            final SecurityConstraintMetaData securityConstraintMD) {
        final UserDataConstraintMetaData userDataConstraintMD = new UserDataConstraintMetaData();
        final TransportGuaranteeType transportGuaranteeValue = TransportGuaranteeType.valueOf(transportGuarantee);

        userDataConstraintMD.setTransportGuarantee(transportGuaranteeValue);
        securityConstraintMD.setUserDataConstraint(userDataConstraintMD);

        return userDataConstraintMD;
    }

    /**
     * Creates new parameter meta data and associates it with parameters meta data.
     *
     * @param key parameter key
     * @param value parameter value
     * @param paramsMD parameters meta data
     * @return new parameter meta data
     */
    public static ParamValueMetaData newParamValue(final String key, final String value, final List<ParamValueMetaData> paramsMD) {
        final ParamValueMetaData paramValueMD = WebMetaDataHelper.newParamValue(key, value);

        paramsMD.add(paramValueMD);

        return paramValueMD;
    }

    /**
     * Creates new parameter with specified key and value.
     *
     * @param key the key
     * @param value the value
     * @return new parameter
     */
    private static ParamValueMetaData newParamValue(final String key, final String value) {
        final ParamValueMetaData paramMD = new ParamValueMetaData();

        paramMD.setParamName(key);
        paramMD.setParamValue(value);

        return paramMD;
    }
}