You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by xu...@apache.org on 2010/04/06 07:14:12 UTC

svn commit: r931020 [5/6] - in /geronimo/server/trunk: framework/modules/geronimo-deployment/src/main/java/org/apache/geronimo/deployment/ framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/osgi/ plugins/j2ee/geronimo-web-2.5-bu...

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletInitParamMergeHandler.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletInitParamMergeHandler.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletInitParamMergeHandler.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletInitParamMergeHandler.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,101 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.merge.webfragment;
+
+import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.web25.deployment.merge.ElementSource;
+import org.apache.geronimo.web25.deployment.merge.MergeContext;
+import org.apache.geronimo.web25.deployment.merge.MergeItem;
+import org.apache.geronimo.web25.deployment.utils.WebDeploymentMessageUtils;
+import org.apache.geronimo.xbeans.javaee6.ParamValueType;
+import org.apache.geronimo.xbeans.javaee6.ServletType;
+import org.apache.geronimo.xbeans.javaee6.WebAppType;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ServletInitParamMergeHandler implements SubMergeHandler<ServletType, ServletType> {
+
+    @Override
+    public void add(ServletType servlet, MergeContext mergeContext) throws DeploymentException {
+        String servletName = servlet.getServletName().getStringValue();
+        for (ParamValueType paramValue : servlet.getInitParamArray()) {
+            addServletInitParam(servletName, paramValue, ElementSource.WEB_FRAGMENT, mergeContext.getCurrentJarUrl(), mergeContext);
+        }
+    }
+
+    @Override
+    public void merge(ServletType srcServlet, ServletType targetServlet, MergeContext mergeContext) throws DeploymentException {
+        String servletName = srcServlet.getServletName().getStringValue();
+        for (ParamValueType paramValue : srcServlet.getInitParamArray()) {
+            MergeItem existedMergeItem = (MergeItem) mergeContext.getAttribute(createServletInitParamKey(servletName, paramValue.getParamName().getStringValue()));
+            if (existedMergeItem == null) {
+                targetServlet.addNewInitParam().set(paramValue);
+                addServletInitParam(servletName, paramValue, ElementSource.WEB_FRAGMENT, mergeContext.getCurrentJarUrl(), mergeContext);
+            } else {
+                ParamValueType existedParamValue = (ParamValueType) existedMergeItem.getValue();
+                switch (existedMergeItem.getSourceType()) {
+                case WEB_XML:
+                    continue;
+                case WEB_FRAGMENT:
+                    if (!existedParamValue.getParamValue().getStringValue().equals(paramValue.getParamValue().getStringValue())) {
+                        throw new DeploymentException(WebDeploymentMessageUtils.createDuplicateKeyValueMessage("servlet " + servletName, "param-name", paramValue.getParamName().getStringValue(), "param-value",
+                                existedParamValue.getParamValue().getStringValue(), existedMergeItem.getBelongedURL(), paramValue.getParamValue().getStringValue(), mergeContext.getCurrentJarUrl()));
+                    }
+                    break;
+                case ANNOTATION:
+                    //Spec 8.1.n.iii Init params for servlets and filters defined via annotations, will be
+                    //overridden in the descriptor if the name of the init param exactly matches
+                    //the name specified via the annotation. Init params are additive between the
+                    //annotations and descriptors.
+                    //In my understanding, the value of init-param should be overridden even if it is merged from annotation before the current web-fragment.xml file
+                    existedParamValue.getParamValue().set(paramValue.getParamValue());
+                    existedMergeItem.setBelongedURL(mergeContext.getCurrentJarUrl());
+                    existedMergeItem.setSourceType(ElementSource.WEB_FRAGMENT);
+                }
+            }
+        }
+
+    }
+
+    @Override
+    public void postProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException {
+    }
+
+    @Override
+    public void preProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException {
+        for (ServletType servlet : webApp.getServletArray()) {
+            String servletName = servlet.getServletName().getStringValue();
+            for (ParamValueType paramValue : servlet.getInitParamArray()) {
+                addServletInitParam(servletName, paramValue, ElementSource.WEB_XML, null, context);
+            }
+        }
+    }
+
+    public static String createServletInitParamKey(String servletName, String paramName) {
+        return "servlet." + servletName + ".init-param.param-name." + paramName;
+    }
+
+    public static boolean isServletInitParamConfigured(String servletName, String paramName, MergeContext mergeContext) {
+        return mergeContext.containsAttribute(createServletInitParamKey(servletName, paramName));
+    }
+
+    public static void addServletInitParam(String servletName, ParamValueType paramValue, ElementSource source, String relativeUrl, MergeContext mergeContext) {
+        mergeContext.setAttribute(createServletInitParamKey(servletName, paramValue.getParamName().getStringValue()), new MergeItem(paramValue, relativeUrl, source));
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletInitParamMergeHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletInitParamMergeHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletInitParamMergeHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletLoadOnStartupMergeHandler.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletLoadOnStartupMergeHandler.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletLoadOnStartupMergeHandler.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletLoadOnStartupMergeHandler.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,90 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.merge.webfragment;
+
+import java.math.BigInteger;
+
+import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.web25.deployment.merge.ElementSource;
+import org.apache.geronimo.web25.deployment.merge.MergeContext;
+import org.apache.geronimo.web25.deployment.merge.MergeItem;
+import org.apache.geronimo.web25.deployment.utils.WebDeploymentMessageUtils;
+import org.apache.geronimo.xbeans.javaee6.ServletType;
+import org.apache.geronimo.xbeans.javaee6.WebAppType;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ServletLoadOnStartupMergeHandler implements SubMergeHandler<ServletType, ServletType> {
+
+    /**
+     *  This method will be invoked while a new servlet is found in the current webfragment.xml, while it is not found in the web.xml file and those merged web-fragment.xml files
+     */
+    @Override
+    public void add(ServletType servlet, MergeContext mergeContext) throws DeploymentException {
+        if (servlet.getLoadOnStartup() != null) {
+            mergeContext.setAttribute(createServletLoadOnStartupKey(servlet.getServletName().getStringValue()), new MergeItem(servlet.getLoadOnStartup(), mergeContext.getCurrentJarUrl(),
+                    ElementSource.WEB_FRAGMENT));
+        }
+    }
+
+    @Override
+    public void merge(ServletType srcServlet, ServletType targetServlet, MergeContext mergeContext) throws DeploymentException {
+        String servletName = srcServlet.getServletName().getStringValue();
+        //If the same servlet in the initial web.xml has already set the load-on-startup option, then we just ignore the setting in webfragment.xml file
+        if (isServletLoadOnStartupConfiguredInWebXML(servletName, mergeContext)) {
+            return;
+        }
+        if (srcServlet.getLoadOnStartup() != null) {
+            BigInteger srcLoadOnStartupValue = (BigInteger) srcServlet.getLoadOnStartup();
+            MergeItem existedLoadOnStartup = (MergeItem) mergeContext.getAttribute(createServletLoadOnStartupKey(servletName));
+            if (existedLoadOnStartup == null) {
+                targetServlet.setLoadOnStartup(srcLoadOnStartupValue);
+                mergeContext.setAttribute(createServletLoadOnStartupKey(servletName), new MergeItem(srcLoadOnStartupValue, mergeContext.getCurrentJarUrl(), ElementSource.WEB_XML));
+            } else if (!existedLoadOnStartup.getValue().equals(srcLoadOnStartupValue)) {
+                throw new DeploymentException(WebDeploymentMessageUtils.createDuplicateValueMessage("servlet " + servletName, "load-on-startup", existedLoadOnStartup.getValue().toString(),
+                        existedLoadOnStartup.getBelongedURL(), srcLoadOnStartupValue.toString(), mergeContext.getCurrentJarUrl()));
+            }
+        }
+    }
+
+    @Override
+    public void postProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException {
+    }
+
+    @Override
+    public void preProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException {
+        for (ServletType servlet : webApp.getServletArray()) {
+            if (servlet.getLoadOnStartup() != null) {
+                context.setAttribute(createServletLoadOnStartupConfiguredInWebXMLKey(servlet.getServletName().getStringValue()), Boolean.TRUE);
+            }
+        }
+    }
+
+    public static String createServletLoadOnStartupConfiguredInWebXMLKey(String servletName) {
+        return "servlet.servlet-name." + servletName + ".load-on-startup.configured_in_web_xml";
+    }
+
+    public static String createServletLoadOnStartupKey(String servletName) {
+        return "servlet.servlet-name." + servletName + ".load-on-startup";
+    }
+
+    public static boolean isServletLoadOnStartupConfiguredInWebXML(String servletName, MergeContext mergeContext) {
+        return mergeContext.containsAttribute(createServletLoadOnStartupConfiguredInWebXMLKey(servletName));
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletLoadOnStartupMergeHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletLoadOnStartupMergeHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletLoadOnStartupMergeHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingMergeHandler.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingMergeHandler.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingMergeHandler.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingMergeHandler.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,104 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.merge.webfragment;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.web25.deployment.merge.ElementSource;
+import org.apache.geronimo.web25.deployment.merge.MergeContext;
+import org.apache.geronimo.xbeans.javaee6.ServletMappingType;
+import org.apache.geronimo.xbeans.javaee6.UrlPatternType;
+import org.apache.geronimo.xbeans.javaee6.WebAppType;
+import org.apache.geronimo.xbeans.javaee6.WebFragmentType;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ServletMappingMergeHandler implements WebFragmentMergeHandler<WebFragmentType, WebAppType> {
+
+    private List<SubMergeHandler<ServletMappingType, ServletMappingType>> subMergeHandlers;
+
+    public ServletMappingMergeHandler() {
+        subMergeHandlers = new ArrayList<SubMergeHandler<ServletMappingType, ServletMappingType>>();
+        subMergeHandlers.add(new ServletMappingUrlPatternMergeHandler());
+    }
+
+    @Override
+    public void merge(WebFragmentType webFragment, WebAppType webApp, MergeContext mergeContext) throws DeploymentException {
+        for (ServletMappingType srcServletMapping : webFragment.getServletMappingArray()) {
+            String servletName = srcServletMapping.getServletName().getStringValue();
+            ServletMappingType targetServletMapping = (ServletMappingType) mergeContext.getAttribute(createServletMappingKey(servletName));
+            if (targetServletMapping == null) {
+                targetServletMapping = (ServletMappingType) webApp.addNewServletMapping().set(srcServletMapping);
+                mergeContext.setAttribute(createServletMappingKey(servletName), targetServletMapping);
+                for (SubMergeHandler<ServletMappingType, ServletMappingType> subMergeHandler : subMergeHandlers) {
+                    subMergeHandler.add(targetServletMapping, mergeContext);
+                }
+            } else {
+                if (isServletMappingFromAnnotation(servletName, mergeContext) && srcServletMapping.getUrlPatternArray().length > 0) {
+                    //If the current url-patterns configurations are from annotations, so let's drop them
+                    targetServletMapping.setUrlPatternArray(new UrlPatternType[0]);
+                    mergeContext.removeAttribute(createServletMappingSourceKey(servletName));
+                }
+                for (SubMergeHandler<ServletMappingType, ServletMappingType> subMergeHandler : subMergeHandlers) {
+                    subMergeHandler.merge(srcServletMapping, targetServletMapping, mergeContext);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void postProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException {
+        for (SubMergeHandler<ServletMappingType, ServletMappingType> subMergeHandler : subMergeHandlers) {
+            subMergeHandler.postProcessWebXmlElement(webApp, context);
+        }
+    }
+
+    @Override
+    public void preProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException {
+        for (ServletMappingType filterMapping : webApp.getServletMappingArray()) {
+            String filterName = filterMapping.getServletName().getStringValue();
+            context.setAttribute(createServletMappingKey(filterName), filterMapping);
+        }
+        for (SubMergeHandler<ServletMappingType, ServletMappingType> subMergeHandler : subMergeHandlers) {
+            subMergeHandler.preProcessWebXmlElement(webApp, context);
+        }
+    }
+
+    public static String createServletMappingKey(String servletName) {
+        return "servlet-mapping.servlet-name" + servletName;
+    }
+
+    public static String createServletMappingSourceKey(String servletName) {
+        return "servlet-mapping.servlet-name." + servletName + ".sources";
+    }
+
+    public static void addServletMapping(ServletMappingType servletMapping, MergeContext mergeContext) {
+        mergeContext.setAttribute(createServletMappingKey(servletMapping.getServletName().getStringValue()), servletMapping);
+    }
+
+    public static boolean isServletMappingConfigured(String servletName, MergeContext mergeContext) {
+        return mergeContext.containsAttribute(createServletMappingKey(servletName));
+    }
+
+    public static boolean isServletMappingFromAnnotation(String servletName, MergeContext mergeContext) {
+        ElementSource elementSource = (ElementSource) mergeContext.getAttribute(createServletMappingSourceKey(servletName));
+        return elementSource != null && elementSource.equals(ElementSource.ANNOTATION);
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingMergeHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingMergeHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingMergeHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingUrlPatternMergeHandler.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingUrlPatternMergeHandler.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingUrlPatternMergeHandler.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingUrlPatternMergeHandler.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,84 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.merge.webfragment;
+
+import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.web25.deployment.merge.MergeContext;
+import org.apache.geronimo.web25.deployment.utils.WebDeploymentMessageUtils;
+import org.apache.geronimo.web25.deployment.utils.WebDeploymentValidationUtils;
+import org.apache.geronimo.xbeans.javaee6.ServletMappingType;
+import org.apache.geronimo.xbeans.javaee6.UrlPatternType;
+import org.apache.geronimo.xbeans.javaee6.WebAppType;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ServletMappingUrlPatternMergeHandler implements SubMergeHandler<ServletMappingType, ServletMappingType> {
+
+    @Override
+    public void add(ServletMappingType servletMapping, MergeContext mergeContext) throws DeploymentException {
+        String servletName = servletMapping.getServletName().getStringValue();
+        for (UrlPatternType urlPattern : servletMapping.getUrlPatternArray()) {
+            String urlPatternStr = urlPattern.getStringValue();
+            if (!WebDeploymentValidationUtils.isUrlPatternValid(urlPatternStr)) {
+                throw new DeploymentException(WebDeploymentMessageUtils.createInvalidUrlPatternErrorMessage("servlet-mapping", servletName, urlPatternStr, "web-fragment.xml located in "
+                        + mergeContext.getCurrentJarUrl()));
+            }
+            mergeContext.setAttribute(createServletMappingUrlPatternKey(servletName, urlPattern.getStringValue()), urlPattern);
+        }
+    }
+
+    @Override
+    public void merge(ServletMappingType srcServletMapping, ServletMappingType targetServletMapping, MergeContext mergeContext) throws DeploymentException {
+        String servletName = srcServletMapping.getServletName().getStringValue();
+        for (UrlPatternType urlPattern : srcServletMapping.getUrlPatternArray()) {
+            String urlPatternStr = urlPattern.getStringValue();
+            String servletMappingUrlPatternKey = createServletMappingUrlPatternKey(servletName, urlPatternStr);
+            if (!mergeContext.containsAttribute(servletMappingUrlPatternKey)) {
+                UrlPatternType newUrlPattern = (UrlPatternType) targetServletMapping.addNewUrlPattern().set(urlPattern);
+                if (!WebDeploymentValidationUtils.isUrlPatternValid(urlPatternStr)) {
+                    throw new DeploymentException(WebDeploymentMessageUtils.createInvalidUrlPatternErrorMessage("servlet-mapping", servletName, urlPatternStr, "web-fragment.xml located in "
+                            + mergeContext.getCurrentJarUrl()));
+                }
+                mergeContext.setAttribute(servletMappingUrlPatternKey, newUrlPattern);
+            }
+        }
+    }
+
+    @Override
+    public void postProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException {
+    }
+
+    @Override
+    public void preProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException {
+        for (ServletMappingType servletMapping : webApp.getServletMappingArray()) {
+            String servletName = servletMapping.getServletName().getStringValue();
+            for (UrlPatternType urlPattern : servletMapping.getUrlPatternArray()) {
+                String urlPatternStr = urlPattern.getStringValue();
+                if (!WebDeploymentValidationUtils.isUrlPatternValid(urlPatternStr)) {
+                    throw new DeploymentException(WebDeploymentMessageUtils.createInvalidUrlPatternErrorMessage("servlet-mapping", servletName, urlPatternStr, "web.xml"));
+                }
+                context.setAttribute(createServletMappingUrlPatternKey(servletName, urlPatternStr), urlPattern);
+            }
+        }
+    }
+
+    public static String createServletMappingUrlPatternKey(String servletName, String urlPattern) {
+        return "servlet-mapping.servlet-name." + servletName + ".url-pattern." + urlPattern;
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingUrlPatternMergeHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingUrlPatternMergeHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMappingUrlPatternMergeHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMergeHandler.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMergeHandler.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMergeHandler.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMergeHandler.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,92 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.merge.webfragment;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.web25.deployment.merge.MergeContext;
+import org.apache.geronimo.xbeans.javaee6.ServletType;
+import org.apache.geronimo.xbeans.javaee6.WebAppType;
+import org.apache.geronimo.xbeans.javaee6.WebFragmentType;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ServletMergeHandler implements WebFragmentMergeHandler<WebFragmentType, WebAppType> {
+
+    private List<SubMergeHandler<ServletType, ServletType>> subMergeHandlers;
+
+    public ServletMergeHandler() {
+        subMergeHandlers = new ArrayList<SubMergeHandler<ServletType, ServletType>>();
+        subMergeHandlers.add(new ServletInitParamMergeHandler());
+        subMergeHandlers.add(new ServletLoadOnStartupMergeHandler());
+    }
+
+    @Override
+    public void merge(WebFragmentType webFragment, WebAppType webApp, MergeContext mergeContext) throws DeploymentException {
+        for (ServletType srcServlet : webFragment.getServletArray()) {
+            String servletName = srcServlet.getServletName().getStringValue();
+            ServletType targetServlet = (ServletType) mergeContext.getAttribute(createServletKey(servletName));
+            if (targetServlet == null) {
+                targetServlet = (ServletType) webApp.addNewServlet().set(srcServlet);
+                mergeContext.setAttribute(createServletKey(servletName), targetServlet);
+                for (SubMergeHandler<ServletType, ServletType> subMergeHandler : subMergeHandlers) {
+                    subMergeHandler.add(targetServlet, mergeContext);
+                }
+            } else {
+                for (SubMergeHandler<ServletType, ServletType> subMergeHandler : subMergeHandlers) {
+                    subMergeHandler.merge(srcServlet, targetServlet, mergeContext);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void postProcessWebXmlElement(WebAppType webApp, MergeContext mergeContext) throws DeploymentException {
+        for (SubMergeHandler<ServletType, ServletType> subMergeHandler : subMergeHandlers) {
+            subMergeHandler.postProcessWebXmlElement(webApp, mergeContext);
+        }
+    }
+
+    @Override
+    public void preProcessWebXmlElement(WebAppType webApp, MergeContext mergeContext) throws DeploymentException {
+        for (ServletType servlet : webApp.getServletArray()) {
+            mergeContext.setAttribute(createServletKey(servlet.getServletName().getStringValue()), servlet);
+        }
+        for (SubMergeHandler<ServletType, ServletType> subMergeHandler : subMergeHandlers) {
+            subMergeHandler.preProcessWebXmlElement(webApp, mergeContext);
+        }
+    }
+
+    public static String createServletKey(String servletName) {
+        return "servlet.servlet-name." + servletName;
+    }
+
+    public static boolean isServletConfigured(String servletName, MergeContext mergeContext) {
+        return mergeContext.containsAttribute(createServletKey(servletName));
+    }
+
+    public static ServletType getServlet(String servletName, MergeContext mergeContext) {
+        return (ServletType) mergeContext.getAttribute(createServletKey(servletName));
+    }
+
+    public static void addServlet(ServletType servlet, MergeContext mergeContext) {
+        mergeContext.setAttribute(createServletKey(servlet.getServletName().getStringValue()), servlet);
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMergeHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMergeHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/ServletMergeHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SessionConfigMergeHandler.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SessionConfigMergeHandler.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SessionConfigMergeHandler.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SessionConfigMergeHandler.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,46 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.merge.webfragment;
+
+import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.web25.deployment.merge.MergeContext;
+import org.apache.geronimo.web25.deployment.utils.WebDeploymentMessageUtils;
+import org.apache.geronimo.xbeans.javaee6.WebAppType;
+import org.apache.geronimo.xbeans.javaee6.WebFragmentType;
+
+/**
+ * @FIXME For session-config, no rules are mentioned in spec, from my understanding, we should only use the one from web.xml
+ * @version $Rev$ $Date$
+ */
+public class SessionConfigMergeHandler implements WebFragmentMergeHandler<WebFragmentType, WebAppType> {
+
+    @Override
+    public void merge(WebFragmentType srcElement, WebAppType webApp, MergeContext mergeContext) throws DeploymentException {
+    }
+
+    @Override
+    public void postProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException {
+    }
+
+    @Override
+    public void preProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException {
+        if (webApp.getSessionConfigArray().length > 1) {
+            throw new DeploymentException(WebDeploymentMessageUtils.createMultipleConfigurationWebAppErrorMessage("session-config"));
+        }
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SessionConfigMergeHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SessionConfigMergeHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SessionConfigMergeHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SubMergeHandler.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SubMergeHandler.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SubMergeHandler.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SubMergeHandler.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,29 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.merge.webfragment;
+
+import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.web25.deployment.merge.MergeContext;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface SubMergeHandler<S, T> extends WebFragmentMergeHandler<S, T> {
+
+    public void add(T element, MergeContext mergeContext) throws DeploymentException;
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SubMergeHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SubMergeHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/SubMergeHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentEntry.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentEntry.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentEntry.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentEntry.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,75 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.merge.webfragment;
+
+import org.apache.geronimo.xbeans.javaee6.WebFragmentType;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WebFragmentEntry {
+
+    private String jarURL;
+
+    //If the name element is defined in the web-fragment.xml, its value is the same with the webfragment's name. If not, a temporary unique name is assigned
+    private String name;
+
+    private WebFragmentType webFragment;
+
+    private String webFragmentName;
+
+    public WebFragmentEntry(String name, String webFragmentName, WebFragmentType webFragment, String jarURL) {
+        this.name = name;
+        this.jarURL = jarURL;
+        this.webFragment = webFragment;
+        this.webFragmentName = webFragmentName;
+    }
+
+    public String getJarURL() {
+        return jarURL;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public WebFragmentType getWebFragment() {
+        return webFragment;
+    }
+
+    public String getWebFragmentName() {
+        return webFragmentName;
+    }
+
+    public void setJarURL(String jarURL) {
+        this.jarURL = jarURL;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setWebFragment(WebFragmentType webFragment) {
+        this.webFragment = webFragment;
+    }
+
+    public void setWebFragmentName(String webFragmentName) {
+        this.webFragmentName = webFragmentName;
+    }
+
+}
\ No newline at end of file

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentEntry.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentEntry.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentMergeHandler.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentMergeHandler.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentMergeHandler.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentMergeHandler.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,34 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.merge.webfragment;
+
+import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.web25.deployment.merge.MergeContext;
+import org.apache.geronimo.xbeans.javaee6.WebAppType;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface WebFragmentMergeHandler<S, T> {
+
+    public void merge(S srcElement, T targetElement, MergeContext mergeContext) throws DeploymentException;
+
+    public void postProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException;
+
+    public void preProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException;
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentMergeHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentMergeHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WebFragmentMergeHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WelcomeFileListMergeHandler.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WelcomeFileListMergeHandler.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WelcomeFileListMergeHandler.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WelcomeFileListMergeHandler.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,85 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.merge.webfragment;
+
+import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.web25.deployment.merge.MergeContext;
+import org.apache.geronimo.xbeans.javaee6.WebAppType;
+import org.apache.geronimo.xbeans.javaee6.WebFragmentType;
+import org.apache.geronimo.xbeans.javaee6.WelcomeFileListType;
+
+/**
+ * TODO 8.1.6 By default all applications will have index.htm(l) and index.jsp in the list of  welcome-file-list.
+ * The descriptor may to be used to override these default settings. So do we need to add them if none is found
+ * @version $Rev$ $Date$
+ */
+public class WelcomeFileListMergeHandler implements WebFragmentMergeHandler<WebFragmentType, WebAppType> {
+
+    @Override
+    public void merge(WebFragmentType webFragment, WebAppType webApp, MergeContext mergeContext) throws DeploymentException {
+        WelcomeFileListType targetWelcomeFileList = null;
+        for (WelcomeFileListType welcomeFileList : webFragment.getWelcomeFileListArray()) {
+            for (String welcomeFile : welcomeFileList.getWelcomeFileArray()) {
+                String welcomeFileKey = createWelcomeFileKey(welcomeFile);
+                if (mergeContext.containsAttribute(welcomeFileKey)) {
+                    continue;
+                }
+                if (targetWelcomeFileList == null) {
+                    targetWelcomeFileList = webApp.getWelcomeFileListArray().length > 0 ? webApp.getWelcomeFileListArray(0) : webApp.addNewWelcomeFileList();
+                }
+                targetWelcomeFileList.addNewWelcomeFile().setStringValue(welcomeFile);
+            }
+        }
+    }
+
+    @Override
+    public void postProcessWebXmlElement(WebAppType parentElement, MergeContext context) throws DeploymentException {
+    }
+
+    @Override
+    public void preProcessWebXmlElement(WebAppType webApp, MergeContext context) throws DeploymentException {
+        WelcomeFileListType[] welcomeFileLists = webApp.getWelcomeFileListArray();
+        if (welcomeFileLists.length == 0) {
+            return;
+        }
+        //Spec 14.2 While multiple welcome file lists are found, we need to concatenate the items
+        if (welcomeFileLists.length > 1) {
+            WelcomeFileListType targetWelcomeFileList = welcomeFileLists[0];
+            for (int i = 1; i < welcomeFileLists.length; i++) {
+                WelcomeFileListType welcomeFileList = welcomeFileLists[i];
+                for (String welcomeFile : welcomeFileList.getWelcomeFileArray()) {
+                    targetWelcomeFileList.addNewWelcomeFile().setStringValue(welcomeFile);
+                }
+            }
+            for (int i = 1, iLength = welcomeFileLists.length; i < iLength; i++) {
+                webApp.removeWelcomeFileList(1);
+            }
+        }
+        for (String welcomeFile : welcomeFileLists[0].getWelcomeFileArray()) {
+            context.setAttribute(createWelcomeFileKey(welcomeFile), Boolean.TRUE);
+        }
+    }
+
+    public static String createWelcomeFileKey(String welcomeFile) {
+        return "welcome-file-list.welcome-file." + welcomeFile;
+    }
+
+    public static boolean isWelcomeFileConfigured(String welcomeFile, MergeContext mergeContext) {
+        return mergeContext.containsAttribute(createWelcomeFileKey(welcomeFile));
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WelcomeFileListMergeHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WelcomeFileListMergeHandler.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/webfragment/WelcomeFileListMergeHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentMessageUtils.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentMessageUtils.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentMessageUtils.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentMessageUtils.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,67 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.utils;
+
+import java.text.MessageFormat;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WebDeploymentMessageUtils {
+
+    private static MessageFormat DUPLICATE_JNDIREF_MESSAGE_FORMAT = new MessageFormat(
+            "It is not allowed that the same {0} with value {1} are configured in more than two web-fragment file or annotations while it is not present in web.xml file : ( 1 ) {2}  ( 2 ) {3}");
+
+    private static MessageFormat DUPLICATE_KEY_VALUE_MESSAGE_FORMAT = new MessageFormat(
+            "Conflict of configuration {1} named {2} of different values in {0} are found below : \n( 1 ) {3} {4} in jar {5} \n( 2 ) {3} {6} in jar {7} \n You might add an entry in the web.xml to take precedence all of them.");
+
+    private static MessageFormat DUPLICATE_VALUE_MESSAGE_FORMAT = new MessageFormat(
+            "Conflict of configuration {1}  of different values in {0} are found below : \n( 1 ) {2}  in jar {3} \n( 2 ) {4} in jar {5} \n You might add an entry in the web.xml to take precedence all of them.");
+
+    private static MessageFormat MULTIPLE_CONFIGURATION_WEB_FRAGMENT_WARNING_MESSAGE_FORMAT = new MessageFormat(
+            "Only one element of {0} could be configured in web-fragment.xml  {1}  only the first one will be considered");
+
+    private static MessageFormat MULTIPLE_CONFIGURATION_WEB_APP_ERROR_MESSAGE_FORMAT = new MessageFormat("Only one element of {0} could be configured in web.xml");
+
+    private static MessageFormat INVALID_URL_PATTERN_ERROR_MESSAGE = new MessageFormat("Invalid character CR(#xD) or LF(#xA) is found in <url-pattern> {2} of {0} {1} from {3}");
+
+    public static String createDuplicateJNDIRefMessage(String elementName, String refName, String jarUrlA, String jarUrlB) {
+        return DUPLICATE_JNDIREF_MESSAGE_FORMAT.format(new Object[] { elementName, refName, jarUrlA, jarUrlB });
+    }
+
+    public static String createDuplicateKeyValueMessage(String parentElement, String keyElementName, String keyName, String valueElementName, String valueA, String jarUrlA, String valueB,
+            String jarUrlB) {
+        return DUPLICATE_KEY_VALUE_MESSAGE_FORMAT.format(new Object[] { parentElement, keyElementName, keyName, valueElementName, valueA, jarUrlA, valueB, jarUrlB });
+    }
+
+    public static String createDuplicateValueMessage(String parentElement, String elementName, String valueA, String jarUrlA, String valueB, String jarUrlB) {
+        return DUPLICATE_VALUE_MESSAGE_FORMAT.format(new Object[] { parentElement, elementName, valueA, jarUrlA, valueB, jarUrlB });
+    }
+
+    public static String createMultipleConfigurationWarningMessage(String elementName, String jarUrl) {
+        return MULTIPLE_CONFIGURATION_WEB_FRAGMENT_WARNING_MESSAGE_FORMAT.format(new Object[] { elementName, jarUrl });
+    }
+
+    public static String createMultipleConfigurationWebAppErrorMessage(String elementName) {
+        return MULTIPLE_CONFIGURATION_WEB_APP_ERROR_MESSAGE_FORMAT.format(new Object[] { elementName });
+    }
+
+    public static String createInvalidUrlPatternErrorMessage(String parentElementName, String parentElement, String urlPattern, String location) {
+        return INVALID_URL_PATTERN_ERROR_MESSAGE.format(new Object[] { parentElementName, parentElement, urlPattern, location });
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentMessageUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentMessageUtils.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentMessageUtils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentValidationUtils.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentValidationUtils.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentValidationUtils.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentValidationUtils.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,88 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment.utils;
+
+import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.xbeans.javaee6.FilterMappingType;
+import org.apache.geronimo.xbeans.javaee6.SecurityConstraintType;
+import org.apache.geronimo.xbeans.javaee6.ServletMappingType;
+import org.apache.geronimo.xbeans.javaee6.UrlPatternType;
+import org.apache.geronimo.xbeans.javaee6.WebAppType;
+import org.apache.geronimo.xbeans.javaee6.WebResourceCollectionType;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WebDeploymentValidationUtils {
+
+    public static boolean isUrlPatternValid(String urlPattern) {
+        //j2ee_1_4.xsd explicitly requires preserving all whitespace. Do not trim.
+        return urlPattern.indexOf(0x0D) < 0 && urlPattern.indexOf(0x0A) < 0;
+    }
+
+    public static void validateWebApp(WebAppType webApp) throws DeploymentException {
+        checkURLPattern(webApp);
+        checkMultiplicities(webApp);
+    }
+
+    private static void checkURLPattern(WebAppType webApp) throws DeploymentException {
+        FilterMappingType[] filterMappings = webApp.getFilterMappingArray();
+        for (FilterMappingType filterMapping : filterMappings) {
+            for (UrlPatternType urlPattern : filterMapping.getUrlPatternArray()) {
+                if (!isUrlPatternValid(urlPattern.getStringValue().trim())) {
+                    throw new DeploymentException(WebDeploymentMessageUtils.createInvalidUrlPatternErrorMessage("filter-mapping", filterMapping.getFilterName().getStringValue(), urlPattern
+                            .getStringValue(), "web.xml"));
+                }
+            }
+        }
+        ServletMappingType[] servletMappings = webApp.getServletMappingArray();
+        for (ServletMappingType servletMapping : servletMappings) {
+            for (UrlPatternType urlPattern : servletMapping.getUrlPatternArray()) {
+                if (!isUrlPatternValid(urlPattern.getStringValue().trim())) {
+                    throw new DeploymentException(WebDeploymentMessageUtils.createInvalidUrlPatternErrorMessage("servlet-mapping", servletMapping.getServletName().getStringValue(), urlPattern
+                            .getStringValue(), "web.xml"));
+                }
+            }
+        }
+        SecurityConstraintType[] constraints = webApp.getSecurityConstraintArray();
+        for (SecurityConstraintType constraint : constraints) {
+            WebResourceCollectionType[] collections = constraint.getWebResourceCollectionArray();
+            for (WebResourceCollectionType collection : collections) {
+                UrlPatternType[] patterns = collection.getUrlPatternArray();
+                for (UrlPatternType pattern : patterns) {
+                    if (!isUrlPatternValid(pattern.getStringValue().trim())) {
+                        throw new DeploymentException(WebDeploymentMessageUtils.createInvalidUrlPatternErrorMessage("security-constraint", collection.getWebResourceName().getStringValue(), pattern
+                                .getStringValue(), "web.xml"));
+                    }
+                }
+            }
+        }
+    }
+
+    private static void checkMultiplicities(WebAppType webApp) throws DeploymentException {
+        if (webApp.getSessionConfigArray().length > 1) {
+            throw new DeploymentException(WebDeploymentMessageUtils.createMultipleConfigurationWebAppErrorMessage("session-config"));
+        }
+        if (webApp.getJspConfigArray().length > 1) {
+            throw new DeploymentException(WebDeploymentMessageUtils.createMultipleConfigurationWebAppErrorMessage("jsp-config"));
+        }
+        if (webApp.getLoginConfigArray().length > 1) {
+            throw new DeploymentException(WebDeploymentMessageUtils.createMultipleConfigurationWebAppErrorMessage("login-config"));
+        }
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentValidationUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentValidationUtils.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/utils/WebDeploymentValidationUtils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/SchemaConversionTest.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/SchemaConversionTest.java?rev=931020&r1=931019&r2=931020&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/SchemaConversionTest.java (original)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/SchemaConversionTest.java Tue Apr  6 05:14:09 2010
@@ -167,6 +167,15 @@ public class SchemaConversionTest extend
             return null;
         }
 
+        @Override
+        protected void postInitContext(EARContext earContext, Module module, Bundle bundle) throws DeploymentException {
+            // TODO Auto-generated method stub
+        }
+
+        @Override
+        protected void preInitContext(EARContext earContext, Module module, Bundle bundle) throws DeploymentException {
+            // TODO Auto-generated method stub
+        }
     }
 
 

Added: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/WebFragmentTest.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/WebFragmentTest.java?rev=931020&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/WebFragmentTest.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/WebFragmentTest.java Tue Apr  6 05:14:09 2010
@@ -0,0 +1,436 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.geronimo.web25.deployment;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
+import org.apache.geronimo.gbean.AbstractName;
+import org.apache.geronimo.j2ee.deployment.EARContext;
+import org.apache.geronimo.kernel.config.Configuration;
+import org.apache.geronimo.kernel.config.ConfigurationData;
+import org.apache.geronimo.kernel.config.ConfigurationManager;
+import org.apache.geronimo.kernel.config.ConfigurationModuleType;
+import org.apache.geronimo.kernel.config.ConfigurationResolver;
+import org.apache.geronimo.kernel.config.ConfigurationStore;
+import org.apache.geronimo.kernel.config.InvalidConfigException;
+import org.apache.geronimo.kernel.config.LifecycleException;
+import org.apache.geronimo.kernel.config.LifecycleMonitor;
+import org.apache.geronimo.kernel.config.LifecycleResults;
+import org.apache.geronimo.kernel.config.NoSuchConfigException;
+import org.apache.geronimo.kernel.config.NoSuchStoreException;
+import org.apache.geronimo.kernel.osgi.MockBundle;
+import org.apache.geronimo.kernel.osgi.MockBundleContext;
+import org.apache.geronimo.kernel.repository.Artifact;
+import org.apache.geronimo.kernel.repository.ArtifactResolver;
+import org.apache.geronimo.kernel.repository.Environment;
+import org.apache.geronimo.kernel.repository.MissingDependencyException;
+import org.apache.geronimo.kernel.repository.Repository;
+import org.apache.geronimo.kernel.repository.Version;
+import org.apache.geronimo.kernel.util.FileUtils;
+import org.apache.geronimo.testsupport.XmlBeansTestSupport;
+import org.apache.geronimo.web25.deployment.merge.MergeHelper;
+import org.apache.geronimo.web25.deployment.merge.webfragment.WebFragmentEntry;
+import org.apache.geronimo.xbeans.javaee6.WebAppDocument;
+import org.apache.geronimo.xbeans.javaee6.WebAppType;
+import org.apache.geronimo.xbeans.javaee6.WebFragmentDocument;
+import org.apache.xmlbeans.XmlObject;
+import org.osgi.framework.Bundle;
+
+/**
+ *
+ *
+ * @version $Rev$ $Date$
+ */
+public class WebFragmentTest extends XmlBeansTestSupport {
+
+    private ClassLoader classLoader = WebFragmentTest.class.getClassLoader();
+
+    /**
+     * Test points :
+     * a. All the ordering configuration in the web-fragments should be ignored
+     * b. The name in the absolute ordering configuration might be not present in founded web-fragment.xml
+     * c. If others is configured, all the web-fragment should be included,
+     * @throws Exception
+     */
+    public void testAbsoluteSortWithOthers() throws Exception {
+        Map<String, WebFragmentDocument> jarURLWebFragmentDocumentMap = new LinkedHashMap<String, WebFragmentDocument>();
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testA.jar", (WebFragmentDocument) loadXmlObject("webfragments/absolute/webfragmentA.xml"));
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testB.jar", (WebFragmentDocument) loadXmlObject("webfragments/absolute/webfragmentB.xml"));
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testC.jar", (WebFragmentDocument) loadXmlObject("webfragments/absolute/webfragmentC.xml"));
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testD.jar", (WebFragmentDocument) loadXmlObject("webfragments/absolute/webfragmentD.xml"));
+        WebAppType webApp = ((WebAppDocument) loadXmlObject("webfragments/absolute/web-withothers.xml")).getWebApp();
+        WebFragmentEntry[] webFragmentEntries = MergeHelper.sortWebFragments(new DummyEARContext(), null, null, webApp, jarURLWebFragmentDocumentMap);
+        Assert.assertEquals(4, webFragmentEntries.length);
+        Assert.assertEquals("webfragmentD", webFragmentEntries[0].getName());
+        Assert.assertEquals("webfragmentB", webFragmentEntries[1].getName());
+        Assert.assertEquals("webfragmentC", webFragmentEntries[2].getName());
+        Assert.assertEquals("webfragmentA", webFragmentEntries[3].getName());
+    }
+
+    /**
+     * Test points :
+     * a. All the ordering configuration in the web-fragments should be ignored
+     * b. The name in the absolute ordering configuration might be not present in founded web-fragment.xml
+     * c. If others element is not configured, only those explicitly configured web fragments are included
+     * @throws Exception
+     */
+    public void testAbsoluteSortWithoutOthers() throws Exception {
+        Map<String, WebFragmentDocument> jarURLWebFragmentDocumentMap = new LinkedHashMap<String, WebFragmentDocument>();
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testA.jar", (WebFragmentDocument) loadXmlObject("webfragments/absolute/webfragmentA.xml"));
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testB.jar", (WebFragmentDocument) loadXmlObject("webfragments/absolute/webfragmentB.xml"));
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testC.jar", (WebFragmentDocument) loadXmlObject("webfragments/absolute/webfragmentC.xml"));
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testD.jar", (WebFragmentDocument) loadXmlObject("webfragments/absolute/webfragmentD.xml"));
+        WebAppType webApp = ((WebAppDocument) loadXmlObject("webfragments/absolute/web-withoutothers.xml")).getWebApp();
+        WebFragmentEntry[] webFragmentEntries = MergeHelper.sortWebFragments(new DummyEARContext(), null, null, webApp, jarURLWebFragmentDocumentMap);
+        Assert.assertEquals(2, webFragmentEntries.length);
+        Assert.assertEquals("webfragmentD", webFragmentEntries[0].getName());
+        Assert.assertEquals("webfragmentA", webFragmentEntries[1].getName());
+    }
+
+    public void testRelativeSort() throws Exception {
+        Map<String, WebFragmentDocument> jarURLWebFragmentDocumentMap = new LinkedHashMap<String, WebFragmentDocument>();
+        //A  -(after)-> B
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testA.jar", (WebFragmentDocument) loadXmlObject("webfragments/relative/webfragmentA.xml"));
+        //B
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testB.jar", (WebFragmentDocument) loadXmlObject("webfragments/relative/webfragmentB.xml"));
+        //C -(before) -> others
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testC.jar", (WebFragmentDocument) loadXmlObject("webfragments/relative/webfragmentC.xml"));
+        //D -(after) -> others
+        jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testD.jar", (WebFragmentDocument) loadXmlObject("webfragments/relative/webfragmentD.xml"));
+        WebAppType webApp = ((WebAppDocument) loadXmlObject("webfragments/relative/web.xml")).getWebApp();
+        WebFragmentEntry[] webFragmentEntries = MergeHelper.sortWebFragments(new DummyEARContext(), null, null, webApp, jarURLWebFragmentDocumentMap);
+        Assert.assertEquals("webfragmentC", webFragmentEntries[0].getName());
+        Assert.assertEquals("webfragmentB", webFragmentEntries[1].getName());
+        Assert.assertEquals("webfragmentA", webFragmentEntries[2].getName());
+        Assert.assertEquals("webfragmentD", webFragmentEntries[3].getName());
+    }
+
+    /**
+     * Test Points :
+     * a. A -> A
+     * @throws Exception
+     */
+    public void testCircusDependencyA() throws Exception {
+        try {
+            Map<String, WebFragmentDocument> jarURLWebFragmentDocumentMap = new LinkedHashMap<String, WebFragmentDocument>();
+            //A  -(before)-> A
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testA.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusA/webfragmentA.xml"));
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testB.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusA/webfragmentB.xml"));
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testC.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusA/webfragmentC.xml"));
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testD.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusA/webfragmentD.xml"));
+            WebAppType webApp = ((WebAppDocument) loadXmlObject("webfragments/circus/circusA/web.xml")).getWebApp();
+            MergeHelper.sortWebFragments(new DummyEARContext(), null, null, webApp, jarURLWebFragmentDocumentMap);
+            fail("Circus Dependency should be found");
+        } catch (DeploymentException e) {
+            Assert.assertTrue(e.getMessage().indexOf("WEB-INF/lib/testA.jar") != -1);
+        }
+    }
+
+    /**
+     * Test Points :
+     * a. A -> B -> A
+     * @throws Exception
+     */
+    public void testCircusDependencyB() throws Exception {
+        try {
+            Map<String, WebFragmentDocument> jarURLWebFragmentDocumentMap = new LinkedHashMap<String, WebFragmentDocument>();
+            //A  -(before)-> B
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testA.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusB/webfragmentA.xml"));
+            //B -(before) -> A
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testB.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusB/webfragmentB.xml"));
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testC.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusB/webfragmentC.xml"));
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testD.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusB/webfragmentD.xml"));
+            WebAppType webApp = ((WebAppDocument) loadXmlObject("webfragments/circus/circusB/web.xml")).getWebApp();
+            MergeHelper.sortWebFragments(new DummyEARContext(), null, null, webApp, jarURLWebFragmentDocumentMap);
+            fail("Circus Dependency should be found");
+        } catch (DeploymentException e) {
+            Assert.assertTrue(e.getMessage().indexOf("WEB-INF/lib/testA.jar") != -1 || e.getMessage().indexOf("WEB-INF/lib/testB.jar") != -1);
+        }
+    }
+
+    /**
+     * Test Points :
+     * a. A -> B -> C -> A
+     * @throws Exception
+     */
+    public void testCircusDependencyC() throws Exception {
+        try {
+            Map<String, WebFragmentDocument> jarURLWebFragmentDocumentMap = new LinkedHashMap<String, WebFragmentDocument>();
+            //A  -(after)-> B
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testA.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusC/webfragmentA.xml"));
+            //B - (after) -> D
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testB.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusC/webfragmentB.xml"));
+            //C -(before) -> others
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testC.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusC/webfragmentC.xml"));
+            //D -(after) -> A
+            jarURLWebFragmentDocumentMap.put("WEB-INF/lib/testD.jar", (WebFragmentDocument) loadXmlObject("webfragments/circus/circusC/webfragmentD.xml"));
+            WebAppType webApp = ((WebAppDocument) loadXmlObject("webfragments/circus/circusC/web.xml")).getWebApp();
+            MergeHelper.sortWebFragments(new DummyEARContext(), null, null, webApp, jarURLWebFragmentDocumentMap);
+            fail("Circus Dependency should be found");
+        } catch (DeploymentException e) {
+            Assert.assertTrue(e.getMessage().indexOf("WEB-INF/lib/testA.jar") != -1 || e.getMessage().indexOf("WEB-INF/lib/testB.jar") != -1 || e.getMessage().indexOf("WEB-INF/lib/testD.jar") != -1);
+        }
+    }
+
+    private XmlObject loadXmlObject(String url) throws Exception {
+        URL srcXml = classLoader.getResource(url);
+        return XmlBeansUtil.parse(srcXml, classLoader);
+    }
+
+    public static class DummyConfigurationManager implements ConfigurationManager {
+
+        @Override
+        public ArtifactResolver getArtifactResolver() {
+            return null;
+        }
+
+        @Override
+        public Bundle getBundle(Artifact id) {
+            return null;
+        }
+
+        @Override
+        public Configuration getConfiguration(Artifact configurationId) {
+            return null;
+        }
+
+        @Override
+        public Artifact[] getInstalled(Artifact query) {
+            return null;
+        }
+
+        @Override
+        public Artifact[] getLoaded(Artifact query) {
+            return null;
+        }
+
+        @Override
+        public Collection<? extends Repository> getRepositories() {
+            return null;
+        }
+
+        @Override
+        public Artifact[] getRunning(Artifact query) {
+            return null;
+        }
+
+        @Override
+        public ConfigurationStore getStoreForConfiguration(Artifact configuration) {
+            return null;
+        }
+
+        @Override
+        public ConfigurationStore[] getStores() {
+            return null;
+        }
+
+        @Override
+        public boolean isConfiguration(Artifact artifact) {
+            return false;
+        }
+
+        @Override
+        public boolean isInstalled(Artifact configurationId) {
+            return false;
+        }
+
+        @Override
+        public boolean isLoaded(Artifact configurationId) {
+            return false;
+        }
+
+        @Override
+        public boolean isOnline() {
+            return false;
+        }
+
+        @Override
+        public boolean isRunning(Artifact configurationId) {
+            return false;
+        }
+
+        @Override
+        public List listConfigurations() {
+            return null;
+        }
+
+        @Override
+        public List listConfigurations(AbstractName store) throws NoSuchStoreException {
+            return null;
+        }
+
+        @Override
+        public List<AbstractName> listStores() {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults loadConfiguration(Artifact configurationId) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults loadConfiguration(Artifact configurationId, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults loadConfiguration(ConfigurationData configurationData) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults loadConfiguration(ConfigurationData configurationData, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public ConfigurationResolver newConfigurationResolver(ConfigurationData configurationData) {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults reloadConfiguration(Artifact configurationId) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults reloadConfiguration(Artifact configurationId, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults reloadConfiguration(Artifact configurationId, Version version) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults reloadConfiguration(Artifact configurationId, Version version, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults reloadConfiguration(ConfigurationData configurationData) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults reloadConfiguration(ConfigurationData configurationData, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LinkedHashSet<Artifact> resolveParentIds(ConfigurationData configurationData) throws MissingDependencyException, InvalidConfigException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults restartConfiguration(Artifact configurationId) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults restartConfiguration(Artifact configurationId, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public void setOnline(boolean online) {
+        }
+
+        @Override
+        public LinkedHashSet<Artifact> sort(List<Artifact> ids, LifecycleMonitor monitor) throws InvalidConfigException, IOException, NoSuchConfigException, MissingDependencyException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults startConfiguration(Artifact configurationId) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults startConfiguration(Artifact configurationId, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults stopConfiguration(Artifact configurationId) throws NoSuchConfigException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults stopConfiguration(Artifact configurationId, LifecycleMonitor monitor) throws NoSuchConfigException {
+            return null;
+        }
+
+        @Override
+        public void uninstallConfiguration(Artifact configurationId) throws IOException, NoSuchConfigException {
+        }
+
+        @Override
+        public LifecycleResults unloadConfiguration(Artifact configurationId) throws NoSuchConfigException {
+            return null;
+        }
+
+        @Override
+        public LifecycleResults unloadConfiguration(Artifact configurationId, LifecycleMonitor monitor) throws NoSuchConfigException {
+            return null;
+        }
+    }
+
+    private static class DummyEARContext extends EARContext {
+
+        /**
+         *  public EARContext(File baseDir,
+                      File inPlaceConfigurationDir,
+                      Environment environment,
+                      ConfigurationModuleType moduleType,
+                      Naming naming,
+                      ConfigurationManager configurationManager,
+                      BundleContext bundleContext,
+                      AbstractNameQuery serverName,
+                      AbstractName baseName,
+                      AbstractNameQuery transactionManagerObjectName,
+                      AbstractNameQuery connectionTrackerObjectName,
+                      AbstractNameQuery corbaGBeanObjectName,
+                      Map messageDestinations) throws DeploymentException {
+        super(baseDir, inPlaceConfigurationDir, environment, baseName, moduleType, naming, configurationManager, bundleContext);
+
+        this.serverName = serverName;
+        this.transactionManagerObjectName = transactionManagerObjectName;
+        this.connectionTrackerObjectName = connectionTrackerObjectName;
+        this.corbaGBeanObjectName = corbaGBeanObjectName;
+        this.messageDestinations = messageDestinations;
+        }
+         */
+        public DummyEARContext() throws Exception {
+            super(FileUtils.createTempDir(), null, new Environment(), ConfigurationModuleType.WAR, null, new DummyConfigurationManager(), new MockBundleContext(new MockBundle(WebFragmentTest.class
+                    .getClassLoader(), "", 1L)), null, null, null, null, null, null);
+        }
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/WebFragmentTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/WebFragmentTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/test/java/org/apache/geronimo/web25/deployment/WebFragmentTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain