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/08/09 03:45:43 UTC

svn commit: r983497 - in /geronimo/server/trunk: framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/util/ plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/ plugins/j2ee/geronimo-j2ee-buil...

Author: xuhaihong
Date: Mon Aug  9 01:45:43 2010
New Revision: 983497

URL: http://svn.apache.org/viewvc?rev=983497&view=rev
Log:
GERONIMO-5496 Move the sort algorithm from the geronimo-web-builder to geronimo-j2ee-builder

Added:
    geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/util/JoinUtils.java   (with props)
    geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/
    geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/CircularReferencesException.java   (with props)
    geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtils.java   (with props)
    geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/IllegalConfigurationException.java   (with props)
    geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/test/java/org/apache/geronimo/j2ee/deployment/util/
    geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/test/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtilsTest.java   (with props)
Modified:
    geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/MergeHelper.java

Added: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/util/JoinUtils.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/util/JoinUtils.java?rev=983497&view=auto
==============================================================================
--- geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/util/JoinUtils.java (added)
+++ geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/util/JoinUtils.java Mon Aug  9 01:45:43 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.kernel.util;
+
+import java.util.Collection;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class JoinUtils {
+
+    public static String join(String delimiter, Collection collection) {
+        if (collection.size() == 0) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        for (Object obj : collection) {
+            sb.append(obj).append(delimiter);
+        }
+        return sb.substring(0, sb.length() - delimiter.length());
+    }
+
+    public static String join(String delimiter, Object... collection) {
+        if (collection.length == 0) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        for (Object obj : collection) {
+            sb.append(obj).append(delimiter);
+        }
+        return sb.substring(0, sb.length() - delimiter.length());
+    }
+
+    public static <T> String join(String delimiter, NameCallback<T> nameCallback, T... collection) {
+        if (collection.length == 0) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        for (T obj : collection) {
+            sb.append(nameCallback.getName(obj)).append(delimiter);
+        }
+        return sb.substring(0, sb.length() - delimiter.length());
+    }
+
+    public static <T> String join(String delimiter, NameCallback<T> nameCallback, Collection<T> collection) {
+        if (collection.size() == 0) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        for (T obj : collection) {
+            sb.append(nameCallback.getName(obj)).append(delimiter);
+        }
+        return sb.substring(0, sb.length() - delimiter.length());
+    }
+
+    public static interface NameCallback<T> {
+
+        public String getName(T object);
+    }
+}

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/util/JoinUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/util/JoinUtils.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/framework/modules/geronimo-kernel/src/main/java/org/apache/geronimo/kernel/util/JoinUtils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/CircularReferencesException.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/CircularReferencesException.java?rev=983497&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/CircularReferencesException.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/CircularReferencesException.java Mon Aug  9 01:45:43 2010
@@ -0,0 +1,36 @@
+/**
+ *  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.j2ee.deployment.util;
+
+import java.util.List;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CircularReferencesException extends Exception {
+
+    private final List<List> circuits;
+
+    public CircularReferencesException(List<List> circuits) {
+        this.circuits = circuits;
+    }
+
+    public List<List> getCircuits() {
+        return circuits;
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/CircularReferencesException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/CircularReferencesException.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/CircularReferencesException.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtils.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtils.java?rev=983497&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtils.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtils.java Mon Aug  9 01:45:43 2010
@@ -0,0 +1,358 @@
+/**
+ *  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.j2ee.deployment.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.geronimo.kernel.util.JoinUtils;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class FragmentSortUtils {
+
+    public static interface Visitor<T> {
+
+        String getName(T t);
+
+        List<String> getAfterNames(T t);
+
+        List<String> getBeforeNames(T t);
+
+        boolean afterOthers(T t);
+
+        boolean beforeOthers(T t);
+    }
+
+    public static <T> List<T> sort(Collection<T> objects, Visitor<T> visitor) throws IllegalConfigurationException, CircularReferencesException {
+
+        if (objects.size() == 0) {
+            return Collections.emptyList();
+        }
+
+        final Map<String, Node<T>> nodes = new LinkedHashMap<String, Node<T>>();
+
+        // Create nodes
+        for (T obj : objects) {
+            String name = visitor.getName(obj);
+            Node<T> node = new Node<T>(name, obj, visitor.afterOthers(obj), visitor.beforeOthers(obj), visitor.getAfterNames(obj), visitor.getBeforeNames(obj));
+            if (node.beforeOthers && node.afterOthers) {
+                throw new IllegalConfigurationException(name, "Before others and after others could not be configured at the sametime ");
+            }
+            nodes.put(name, node);
+        }
+
+        // Link nodes
+        for (Node<T> node : nodes.values()) {
+            //Convert all the before and after configurations to dependOns
+            if (node.after.contains(node.name)) {
+                throw new IllegalConfigurationException(node.name, "The fragment could not be configured to after itself");
+            }
+            for (String afterNodeName : node.after) {
+                Node<T> afterNode = nodes.get(afterNodeName);
+                if (afterNode != null) {
+                    node.dependOns.add(afterNode);
+                }
+            }
+            if (node.before.contains(node.name)) {
+                throw new IllegalConfigurationException(node.name, "The fragment could not be configured to before itself");
+            }
+            for (String beforeNodeName : node.before) {
+                Node<T> beforeNode = nodes.get(beforeNodeName);
+                if (beforeNode != null) {
+                    beforeNode.dependOns.add(node);
+                }
+            }
+        }
+
+        boolean circuitFounded = false;
+        for (Node<T> node : nodes.values()) {
+            Set<Node<T>> visitedNodes = new HashSet<Node<T>>();
+            if (!normalizeNodeReferences(node, node, visitedNodes)) {
+                circuitFounded = true;
+                break;
+            }
+            node.dependOns.addAll(visitedNodes);
+        }
+
+        //detect circus
+        if (circuitFounded) {
+            Set<Circuit<T>> circuits = new LinkedHashSet<Circuit<T>>();
+
+            for (Node<T> node : nodes.values()) {
+                findCircuits(circuits, node, new java.util.Stack<Node<T>>());
+            }
+
+            ArrayList<Circuit<T>> list = new ArrayList<Circuit<T>>(circuits);
+            Collections.sort(list);
+
+            List<List> all = new ArrayList<List>();
+            for (Circuit circuit : list) {
+                all.add(unwrap(circuit.nodes));
+            }
+
+            throw new CircularReferencesException(all);
+        }
+
+        //Build Double Link Node List
+        Node<T> rootNode = new Node<T>();
+        rootNode.previous = rootNode;
+        rootNode.next = nodes.values().iterator().next();
+
+        for (Node<T> node : nodes.values()) {
+            node.previous = rootNode.previous;
+            rootNode.previous.next = node;
+            node.next = rootNode;
+            rootNode.previous = node;
+        }
+
+        //Sort by  Before/After
+        Node<T> lastBeforeNode = rootNode;
+        for (Node<T> node : nodes.values()) {
+            if (node.beforeOthers) {
+                moveAfter(node, lastBeforeNode);
+                lastBeforeNode = node;
+            } else if (node.afterOthers) {
+                moveBefore(node, rootNode);
+            }
+        }
+
+        //Sort by dependOns
+        for (Node<T> node : nodes.values()) {
+            for (Node<T> reference : node.dependOns) {
+                swap(node, reference, rootNode);
+            }
+        }
+
+        List<T> sortedList = new ArrayList<T>(nodes.size());
+        Node<T> currentNode = rootNode.next;
+        while (currentNode != rootNode) {
+            sortedList.add(currentNode.object);
+            currentNode = currentNode.next;
+        }
+        return sortedList;
+    }
+
+    private static <T> boolean normalizeNodeReferences(Node<T> rootNode, Node<T> node, Set<Node<T>> dependOns) {
+        if (node.dependOns.contains(rootNode)) {
+            return false;
+        }
+        for (Node<T> reference : node.dependOns) {
+            if (!dependOns.add(reference)) {
+                //this reference node has been visited in the past
+                continue;
+            }
+            if (!normalizeNodeReferences(rootNode, reference, dependOns)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static <T> void moveAfter(Node<T> insertNode, Node<T> targetNode) {
+        //Remove the insertNode
+        insertNode.previous.next = insertNode.next;
+        insertNode.next.previous = insertNode.previous;
+        //Insert the node after the targetNode
+        targetNode.next.previous = insertNode;
+        insertNode.next = targetNode.next;
+        targetNode.next = insertNode;
+        insertNode.previous = targetNode;
+    }
+
+    private static <T> void moveBefore(Node<T> insertNode, Node<T> targetNode) {
+        //Remove the insertNode
+        insertNode.previous.next = insertNode.next;
+        insertNode.next.previous = insertNode.previous;
+        //Insert the node before the targetNode
+        targetNode.previous.next = insertNode;
+        insertNode.previous = targetNode.previous;
+        insertNode.next = targetNode;
+        targetNode.previous = insertNode;
+    }
+
+    private static <T> void swap(Node<T> shouldAfterNode, Node<T> shouldBeforeNode, Node<T> rootNode) {
+        Node<T> currentNode = shouldBeforeNode;
+        while (currentNode.next != rootNode) {
+            if (currentNode.next == shouldAfterNode) {
+                return;
+            }
+            currentNode = currentNode.next;
+        }
+        //Remove the shouldAfterNode from list
+        shouldAfterNode.previous.next = shouldAfterNode.next;
+        shouldAfterNode.next.previous = shouldAfterNode.previous;
+        //Insert the node immediately after the shouldBeforeNode
+        shouldAfterNode.previous = shouldBeforeNode;
+        shouldAfterNode.next = shouldBeforeNode.next;
+        shouldBeforeNode.next = shouldAfterNode;
+        shouldAfterNode.next.previous = shouldAfterNode;
+    }
+
+    private static <T> List<T> unwrap(List<Node<T>> nodes) {
+        List<T> referees = new ArrayList<T>(nodes.size());
+        for (Node<T> node : nodes) {
+            referees.add(node.object);
+        }
+        return referees;
+    }
+
+    private static <T> void findCircuits(Set<Circuit<T>> circuits, Node<T> node, java.util.Stack<Node<T>> stack) {
+        if (stack.contains(node)) {
+            int fromIndex = stack.indexOf(node);
+            int toIndex = stack.size();
+            ArrayList<Node<T>> circularity = new ArrayList<Node<T>>(stack.subList(fromIndex, toIndex));
+            // add ending node to list so a full circuit is shown
+            circularity.add(node);
+            Circuit circuit = new Circuit(circularity);
+            circuits.add(circuit);
+            return;
+        }
+
+        stack.push(node);
+
+        for (Node<T> reference : node.dependOns) {
+            findCircuits(circuits, reference, stack);
+        }
+
+        stack.pop();
+    }
+
+    private static class Node<T> implements Comparable<Node<T>> {
+
+        public String name;
+
+        public T object;
+
+        public List<String> after = new ArrayList<String>();
+
+        public List<String> before = new ArrayList<String>();
+
+        public boolean afterOthers;
+
+        public boolean beforeOthers;
+
+        public final Set<Node<T>> dependOns = new HashSet<Node<T>>();
+
+        public Node<T> next;
+
+        public Node<T> previous;
+
+        public Node() {
+        }
+
+        public Node(String name, T object, boolean afterOthers, boolean beforeOthers, List<String> after, List<String> before) {
+            this.name = name;
+            this.object = object;
+            this.afterOthers = afterOthers;
+            this.beforeOthers = beforeOthers;
+            this.before = before;
+            this.after = after;
+        }
+
+        public boolean equals(Object o) {
+            if (this == o)
+                return true;
+            if (o == null || getClass() != o.getClass())
+                return false;
+
+            final Node<T> node = (Node<T>) o;
+
+            return name.equals(node.name);
+        }
+
+        public int hashCode() {
+            return name.hashCode();
+        }
+
+        public int compareTo(Node<T> o) {
+            return this.name.compareTo(o.name);
+        }
+
+        public String toString() {
+            return name;
+        }
+    }
+
+    private static class Circuit<T> implements Comparable<Circuit<T>> {
+
+        private final List<Node<T>> nodes;
+
+        private final List<Node<T>> atomic;
+
+        public Circuit(List<Node<T>> nodes) {
+            this.nodes = nodes;
+            atomic = new ArrayList<Node<T>>(nodes);
+            atomic.remove(atomic.size() - 1);
+            Collections.sort(atomic);
+        }
+
+        public List<Node<T>> getNodes() {
+            return nodes;
+        }
+
+        public boolean equals(Object o) {
+            if (this == o)
+                return true;
+            if (o == null || getClass() != o.getClass())
+                return false;
+
+            final Circuit<T> circuit = (Circuit<T>) o;
+
+            if (!atomic.equals(circuit.atomic))
+                return false;
+
+            return true;
+        }
+
+        public int hashCode() {
+            return atomic.hashCode();
+        }
+
+        public int compareTo(Circuit<T> o) {
+            int i = atomic.size() - o.atomic.size();
+            if (i != 0)
+                return i;
+
+            Iterator<Node<T>> iterA = atomic.listIterator();
+            Iterator<Node<T>> iterB = o.atomic.listIterator();
+            while (iterA.hasNext() && iterB.hasNext()) {
+                Node<T> a = iterA.next();
+                Node<T> b = iterB.next();
+                i = a.compareTo(b);
+                if (i != 0)
+                    return i;
+            }
+
+            return 0;
+        }
+
+        public String toString() {
+            return "Circuit(" + JoinUtils.join(",", unwrap(nodes)) + ")";
+        }
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtils.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/IllegalConfigurationException.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/IllegalConfigurationException.java?rev=983497&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/IllegalConfigurationException.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/IllegalConfigurationException.java Mon Aug  9 01:45:43 2010
@@ -0,0 +1,41 @@
+/**
+ *  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.j2ee.deployment.util;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class IllegalConfigurationException extends Exception {
+
+    private static final long serialVersionUID = -6131258240075237969L;
+
+    private String nodeName;
+
+    public IllegalConfigurationException(String nodeName, String message) {
+        super(message);
+        this.nodeName = nodeName;
+    }
+
+    public IllegalConfigurationException(String message) {
+        super(message);
+    }
+
+    public String getNodeName() {
+        return nodeName;
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/IllegalConfigurationException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/IllegalConfigurationException.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/main/java/org/apache/geronimo/j2ee/deployment/util/IllegalConfigurationException.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/test/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtilsTest.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/test/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtilsTest.java?rev=983497&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/test/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtilsTest.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/test/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtilsTest.java Mon Aug  9 01:45:43 2010
@@ -0,0 +1,362 @@
+/**
+ *  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.j2ee.deployment.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.apache.geronimo.j2ee.deployment.util.FragmentSortUtils.Visitor;
+import org.junit.Test;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class FragmentSortUtilsTest {
+
+    @Test
+    public void testFragmentSortA() throws Exception {
+        List<String> fragmentList = new ArrayList<String>();
+        for (int i = 0; i < 6; i++) {
+            fragmentList.add(String.valueOf((char) ('A' + i)));
+        }
+        List<String> sortedList = FragmentSortUtils.sort(fragmentList, new Visitor<String>() {
+
+            @Override
+            public boolean afterOthers(String t) {
+                if (t.equals("A") || t.equals("C")) {
+                    return true;
+                }
+                return false;
+            }
+
+            @Override
+            public boolean beforeOthers(String t) {
+                if (t.equals("B") || t.equals("F")) {
+                    return true;
+                }
+                return false;
+            }
+
+            @Override
+            public List<String> getAfterNames(String t) {
+                if (t.equals("A")) {
+                    return Arrays.asList("C");
+                }
+                return Collections.emptyList();
+            }
+
+            @Override
+            public List<String> getBeforeNames(String t) {
+                if (t.equals("F")) {
+                    return Arrays.asList("B");
+                }
+                return Collections.emptyList();
+            }
+
+            @Override
+            public String getName(String t) {
+                return t;
+            }
+
+        });
+        Assert.assertEquals(Arrays.asList("F", "B", "D", "E", "C", "A"), sortedList);
+    }
+
+    @Test
+    public void testFragmentSortB() throws Exception {
+        List<String> fragmentList = new ArrayList<String>();
+        for (int i = 0; i < 6; i++) {
+            fragmentList.add(String.valueOf((char) ('A' + i)));
+        }
+        List<String> sortedList = FragmentSortUtils.sort(fragmentList, new Visitor<String>() {
+
+            @Override
+            public boolean afterOthers(String t) {
+                if (t.equals("A") || t.equals("D")) {
+                    return true;
+                }
+                return false;
+            }
+
+            @Override
+            public boolean beforeOthers(String t) {
+                if (t.equals("B") || t.equals("E")) {
+                    return true;
+                }
+                return false;
+            }
+
+            @Override
+            public List<String> getAfterNames(String t) {
+                return Collections.emptyList();
+            }
+
+            @Override
+            public List<String> getBeforeNames(String t) {
+                if (t.equals("A")) {
+                    return Arrays.asList("C");
+                }
+                return Collections.emptyList();
+            }
+
+            @Override
+            public String getName(String t) {
+                return t;
+            }
+
+        });
+        Assert.assertEquals(Arrays.asList("B", "E", "F", "A", "C", "D"), sortedList);
+    }
+
+    @Test
+    public void testFragmentSortC() throws Exception {
+        List<String> fragmentList = new ArrayList<String>();
+        for (int i = 0; i < 4; i++) {
+            fragmentList.add(String.valueOf((char) ('A' + i)));
+        }
+        List<String> sortedList = FragmentSortUtils.sort(fragmentList, new Visitor<String>() {
+
+            @Override
+            public boolean afterOthers(String t) {
+                return t.equals("A");
+            }
+
+            @Override
+            public boolean beforeOthers(String t) {
+                return t.equals("C");
+            }
+
+            @Override
+            public List<String> getAfterNames(String t) {
+                return Collections.emptyList();
+            }
+
+            @Override
+            public List<String> getBeforeNames(String t) {
+                return Collections.emptyList();
+            }
+
+            @Override
+            public String getName(String t) {
+                return t;
+            }
+
+        });
+        Assert.assertEquals(Arrays.asList("C", "B", "D", "A"), sortedList);
+    }
+
+    @Test
+    public void testBothAfterAndBeforeOthers() {
+        List<String> fragmentList = new ArrayList<String>();
+        for (int i = 0; i < 2; i++) {
+            fragmentList.add(String.valueOf((char) ('A' + i)));
+        }
+        Exception actualException = null;
+        try {
+            FragmentSortUtils.sort(fragmentList, new Visitor<String>() {
+
+                @Override
+                public boolean afterOthers(String t) {
+                    return t.equals("A");
+                }
+
+                @Override
+                public boolean beforeOthers(String t) {
+                    return t.equals("A");
+                }
+
+                @Override
+                public List<String> getAfterNames(String t) {
+                    return Collections.emptyList();
+                }
+
+                @Override
+                public List<String> getBeforeNames(String t) {
+                    return Collections.emptyList();
+                }
+
+                @Override
+                public String getName(String t) {
+                    return t;
+                }
+
+            });
+        } catch (IllegalConfigurationException e) {
+            actualException = e;
+        } catch (CircularReferencesException e) {
+            Assert.fail("Should not get CircularReference Exception here");
+        }
+        Assert.assertNotNull("Should get an IllegalConfigurationException", actualException);
+    }
+
+    @Test
+    public void testBeforeOrAfterItselfException() {
+        List<String> fragmentList = new ArrayList<String>();
+        for (int i = 0; i < 2; i++) {
+            fragmentList.add(String.valueOf((char) ('A' + i)));
+        }
+        IllegalConfigurationException actualException = null;
+        try {
+            FragmentSortUtils.sort(fragmentList, new Visitor<String>() {
+
+                @Override
+                public boolean afterOthers(String t) {
+                    return false;
+                }
+
+                @Override
+                public boolean beforeOthers(String t) {
+                    return false;
+                }
+
+                @Override
+                public List<String> getAfterNames(String t) {
+                    if (t.equals("A")) {
+                        return Arrays.asList("A");
+                    } else {
+                        return Collections.emptyList();
+                    }
+                }
+
+                @Override
+                public List<String> getBeforeNames(String t) {
+                    return Collections.emptyList();
+                }
+
+                @Override
+                public String getName(String t) {
+                    return t;
+                }
+
+            });
+        } catch (IllegalConfigurationException e) {
+            actualException = e;
+
+        } catch (CircularReferencesException e) {
+            Assert.fail("Should not get CircularReferencesException here");
+        }
+        Assert.assertNotNull("Should get an IllegalConfigurationException", actualException);
+    }
+
+    @Test
+    public void testCircularReferenceExceptionA() {
+        List<String> fragmentList = new ArrayList<String>();
+        for (int i = 0; i < 2; i++) {
+            fragmentList.add(String.valueOf((char) ('A' + i)));
+        }
+        CircularReferencesException actualException = null;
+        try {
+            FragmentSortUtils.sort(fragmentList, new Visitor<String>() {
+
+                @Override
+                public boolean afterOthers(String t) {
+                    return false;
+                }
+
+                @Override
+                public boolean beforeOthers(String t) {
+                    return false;
+                }
+
+                @Override
+                public List<String> getAfterNames(String t) {
+                    if (t.equals("A")) {
+                        return Arrays.asList("B");
+                    } else {
+                        return Collections.emptyList();
+                    }
+                }
+
+                @Override
+                public List<String> getBeforeNames(String t) {
+                    if (t.equals("A")) {
+                        return Arrays.asList("B");
+                    } else {
+                        return Collections.emptyList();
+                    }
+                }
+
+                @Override
+                public String getName(String t) {
+                    return t;
+                }
+
+            });
+        } catch (IllegalConfigurationException e) {
+            Assert.fail("Should not get IllegalConfigurationException here");
+        } catch (CircularReferencesException e) {
+            actualException = e;
+        }
+        Assert.assertNotNull("Should get an CircularReferencesException", actualException);
+    }
+
+    @Test
+    public void testCircularReferenceExceptionB() {
+        List<String> fragmentList = new ArrayList<String>();
+        for (int i = 0; i < 3; i++) {
+            fragmentList.add(String.valueOf((char) ('A' + i)));
+        }
+        Exception actualException = null;
+        try {
+            FragmentSortUtils.sort(fragmentList, new Visitor<String>() {
+
+                @Override
+                public boolean afterOthers(String t) {
+                    return false;
+                }
+
+                @Override
+                public boolean beforeOthers(String t) {
+                    return false;
+                }
+
+                @Override
+                public List<String> getAfterNames(String t) {
+                    if (t.equals("A")) {
+                        return Arrays.asList("B");
+                    } else if (t.equals("B")) {
+                        return Arrays.asList("C");
+                    } else if (t.equals("C")) {
+                        return Arrays.asList("A");
+                    }
+                    return Collections.emptyList();
+                }
+
+                @Override
+                public List<String> getBeforeNames(String t) {
+                    return Collections.emptyList();
+                }
+
+                @Override
+                public String getName(String t) {
+                    return t;
+                }
+
+            });
+        } catch (IllegalConfigurationException e) {
+            Assert.fail("Should not get IllegalConfigurationException here");
+        } catch (CircularReferencesException e) {
+            actualException = e;
+        }
+        Assert.assertNotNull("Should get an CircularReferencesException", actualException);
+    }
+}

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/test/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtilsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/test/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtilsTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/plugins/j2ee/geronimo-j2ee-builder/src/test/java/org/apache/geronimo/j2ee/deployment/util/FragmentSortUtilsTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/MergeHelper.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/MergeHelper.java?rev=983497&r1=983496&r2=983497&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/MergeHelper.java (original)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web-2.5-builder/src/main/java/org/apache/geronimo/web25/deployment/merge/MergeHelper.java Mon Aug  9 01:45:43 2010
@@ -23,6 +23,7 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -42,10 +43,17 @@ import javax.servlet.annotation.WebListe
 import javax.servlet.annotation.WebServlet;
 import javax.xml.bind.JAXBException;
 import javax.xml.parsers.ParserConfigurationException;
+
 import org.apache.geronimo.common.DeploymentException;
 import org.apache.geronimo.j2ee.deployment.EARContext;
 import org.apache.geronimo.j2ee.deployment.Module;
+import org.apache.geronimo.j2ee.deployment.util.CircularReferencesException;
+import org.apache.geronimo.j2ee.deployment.util.FragmentSortUtils;
+import org.apache.geronimo.j2ee.deployment.util.IllegalConfigurationException;
+import org.apache.geronimo.j2ee.deployment.util.FragmentSortUtils.Visitor;
 import org.apache.geronimo.kernel.util.IOUtils;
+import org.apache.geronimo.kernel.util.JoinUtils;
+import org.apache.geronimo.kernel.util.JoinUtils.NameCallback;
 import org.apache.geronimo.web25.deployment.AbstractWebModuleBuilder;
 import org.apache.geronimo.web25.deployment.merge.annotation.AnnotationMergeHandler;
 import org.apache.geronimo.web25.deployment.merge.annotation.ServletSecurityAnnotationMergeHandler;
@@ -92,10 +100,10 @@ import org.apache.xbean.finder.BundleAnn
 import org.apache.xbean.finder.BundleAssignableClassFinder;
 import org.apache.xbean.osgi.bundle.util.BundleClassFinder;
 import org.apache.xbean.osgi.bundle.util.BundleResourceFinder;
-import org.apache.xbean.osgi.bundle.util.BundleResourceFinder.ResourceFinderCallback;
 import org.apache.xbean.osgi.bundle.util.ClassDiscoveryFilter;
 import org.apache.xbean.osgi.bundle.util.DiscoveryRange;
 import org.apache.xbean.osgi.bundle.util.ResourceDiscoveryFilter;
+import org.apache.xbean.osgi.bundle.util.BundleResourceFinder.ResourceFinderCallback;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.packageadmin.PackageAdmin;
@@ -140,22 +148,22 @@ public class MergeHelper {
         List<WebFragmentEntry> orderedWebFragments = new LinkedList<WebFragmentEntry>();
 
         Map<String, WebFragmentEntry> unusedWebFragmentEntryMap = new LinkedHashMap<String, WebFragmentEntry>(webFragmentEntryMap);
-        for (Object o: absoluteOrdering.getNameOrOthers()) {
+        for (Object o : absoluteOrdering.getNameOrOthers()) {
             if (o instanceof String) {
                 //web fragment name
                 String webFragmentName = (String) o;
                 unusedWebFragmentEntryMap.remove(webFragmentName);
             }
         }
-        for (Object o: absoluteOrdering.getNameOrOthers()) {
+        for (Object o : absoluteOrdering.getNameOrOthers()) {
             if (o instanceof String) {
                 //web fragment name
                 String webFragmentName = (String) o;
-                 // Only process the web-fragment.xml when it is present and it is not processed before
-                 if (webFragmentEntryMap.containsKey(webFragmentName) && !expliciteConfiguredWebFragmentNames.contains(webFragmentName)) {
-                     expliciteConfiguredWebFragmentNames.add(webFragmentName);
-                     orderedWebFragments.add(webFragmentEntryMap.get(webFragmentName));
-                 }
+                // Only process the web-fragment.xml when it is present and it is not processed before
+                if (webFragmentEntryMap.containsKey(webFragmentName) && !expliciteConfiguredWebFragmentNames.contains(webFragmentName)) {
+                    expliciteConfiguredWebFragmentNames.add(webFragmentName);
+                    orderedWebFragments.add(webFragmentEntryMap.get(webFragmentName));
+                }
             } else {
                 //"other""
                 expliciteConfiguredWebFragmentNames.addAll(unusedWebFragmentEntryMap.keySet());
@@ -169,7 +177,7 @@ public class MergeHelper {
         Set<String> excludedURLs = AbstractWebModuleBuilder.EXCLUDED_JAR_URLS.get(earContext.getGeneralData());
         //Add left named web-fragment.xml file URLs to the EXCLUDED_JAR_URLS List
         for (WebFragmentEntry excludedFragment : unusedWebFragmentEntryMap.values()) {
-                excludedURLs.add(excludedFragment.getJarURL());
+            excludedURLs.add(excludedFragment.getJarURL());
         }
 
         WebFragmentEntry[] webFragmentEntries = orderedWebFragments.toArray(new WebFragmentEntry[orderedWebFragments.size()]);
@@ -260,7 +268,7 @@ public class MergeHelper {
                             bufferedReader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
                             String line = null;
                             while ((line = bufferedReader.readLine()) != null) {
-                                line = line.trim();                                
+                                line = line.trim();
                                 if (!line.isEmpty() && !line.startsWith("#")) {
                                     servletContainerInitializers.add(line);
                                 }
@@ -411,71 +419,86 @@ public class MergeHelper {
 
     public static WebFragmentEntry[] relativeOrderWebFragments(EARContext earContext, Module module, Bundle bundle, WebApp webApp, Map<String, WebFragmentEntry> webFragmentEntryMap)
             throws DeploymentException {
-        Map<String, WebFragmentOrderEntry> webFragmentOrderEntryMap = new LinkedHashMap<String, WebFragmentOrderEntry>();
-        //Step 1 : Create WebFragmentOrderEntry for sorting web fragments easily
-        boolean relativeSortRequired = false;
-        for (String webFragmentName : webFragmentEntryMap.keySet()) {
-            WebFragmentEntry webFragmentEntry = webFragmentEntryMap.get(webFragmentName);
-            if (!relativeSortRequired) {
-                relativeSortRequired = webFragmentEntry.getWebFragment().getOrdering() != null;
-            }
-            webFragmentOrderEntryMap.put(webFragmentName, WebFragmentOrderEntry.create(webFragmentEntry));
-        }
-        //If none of the web-fragment.xml defines the order element, the order of jar files are unknown
-        if (!relativeSortRequired) {
-            WebFragmentEntry[] WebFragments = new WebFragmentEntry[webFragmentOrderEntryMap.size()];
-            int iIndex = 0;
-            for (WebFragmentOrderEntry webFragmentOrderEntry : webFragmentOrderEntryMap.values()) {
-                WebFragments[iIndex++] = webFragmentOrderEntry.webFragmentEntry;
-            }
-            //TODO really not save?
-            //            saveOrderedLibAttribute(earContext, WebFragments);
-            return WebFragments;
-        }
-        LinkedList<WebFragmentOrderEntry> webFragmentOrderEntryList = null;
-        if (relativeSortRequired) {
-            //Step 2 : Initialize the list by before/after others configurations, also, convert the before configurations to corresponding after configurations
-            //TODO Is the reference like A before others and B before A allowed ?
-            webFragmentOrderEntryList = new LinkedList<WebFragmentOrderEntry>();
-            for (WebFragmentOrderEntry webFragmentOrderEntry : webFragmentOrderEntryMap.values()) {
-                for (String beforeEntryName : webFragmentOrderEntry.beforeEntryNames) {
-                    webFragmentOrderEntryMap.get(beforeEntryName).afterEntryNames.add(webFragmentOrderEntry.name);
+        try {
+            WebFragmentEntry[] webFragments = FragmentSortUtils.sort(webFragmentEntryMap.values(), new Visitor<WebFragmentEntry>() {
+
+                @Override
+                public boolean afterOthers(WebFragmentEntry entry) {
+                    WebFragment webFragment = entry.getWebFragment();
+                    if (webFragment.getOrdering() != null) {
+                        OrderingOrdering after = webFragment.getOrdering().getAfter();
+                        if (after != null) {
+                            return after.getOthers() != null;
+                        }
+                    }
+                    return false;
                 }
-                if (webFragmentOrderEntry.afterDefined && webFragmentOrderEntry.afterOthers) {
-                    webFragmentOrderEntryList.addLast(webFragmentOrderEntry);
-                } else {
-                    webFragmentOrderEntryList.addFirst(webFragmentOrderEntry);
+
+                @Override
+                public boolean beforeOthers(WebFragmentEntry entry) {
+                    WebFragment webFragment = entry.getWebFragment();
+                    if (webFragment.getOrdering() != null) {
+                        OrderingOrdering before = webFragment.getOrdering().getBefore();
+                        if (before != null) {
+                            return before.getOthers() != null;
+                        }
+                    }
+                    return false;
                 }
-            }
-            //Step 3: Detect Circus references
-            // a. A -> A
-            // b. A -> B -> A
-            // c. A -> B ->  C -> A
-            for (WebFragmentOrderEntry webFragmentOrderEntry : webFragmentOrderEntryList) {
-                Set<String> allAfterEntryNames = new HashSet<String>();
-                detectCircusAfterDependency(webFragmentOrderEntry, webFragmentOrderEntry, webFragmentOrderEntryMap, allAfterEntryNames);
-                webFragmentOrderEntry.afterEntryNames.addAll(allAfterEntryNames);
-            }
-            //Step 4: Sort the webFragment depending on the after configurations
-            //TODO The Sort algorithm might need to improve.
-            for (WebFragmentOrderEntry webFragmentOrderEntry : webFragmentOrderEntryMap.values()) {
-                for (String afterEntryName : webFragmentOrderEntry.afterEntryNames) {
-                    swap(webFragmentOrderEntry.name, afterEntryName, webFragmentOrderEntryList);
+
+                @Override
+                public List<String> getAfterNames(WebFragmentEntry entry) {
+                    WebFragment webFragment = entry.getWebFragment();
+                    if (webFragment.getOrdering() != null) {
+                        OrderingOrdering after = webFragment.getOrdering().getAfter();
+                        if (after != null) {
+                            return after.getName() == null ? Collections.<String> emptyList() : after.getName();
+                        }
+                    }
+                    return Collections.emptyList();
+                }
+
+                @Override
+                public List<String> getBeforeNames(WebFragmentEntry entry) {
+                    WebFragment webFragment = entry.getWebFragment();
+                    if (webFragment.getOrdering() != null) {
+                        OrderingOrdering before = webFragment.getOrdering().getBefore();
+                        if (before != null) {
+                            return before.getName() == null ? Collections.<String> emptyList() : before.getName();
+                        }
+                    }
+                    return Collections.emptyList();
+                }
+
+                @Override
+                public String getName(WebFragmentEntry entry) {
+                    return entry.getName();
+                }
+
+            }).toArray(new WebFragmentEntry[webFragmentEntryMap.values().size()]);
+            saveOrderedLibAttribute(earContext, webFragments);
+            return webFragments;
+        } catch (IllegalConfigurationException e) {
+            throw new DeploymentException("Jar file " + webFragmentEntryMap.get(e.getNodeName()).getJarURL() + " is not configured correctly for " + e.getMessage(), e);
+        } catch (CircularReferencesException e) {
+            StringBuilder circularReferenceInfo = new StringBuilder();
+            int index = 1;
+            NameCallback<WebFragmentEntry> nameCallback = new NameCallback<WebFragmentEntry>() {
+
+                @Override
+                public String getName(WebFragmentEntry object) {
+                    return object.getJarURL();
                 }
+            };
+            for (List list : e.getCircuits()) {
+                circularReferenceInfo.append(index++ + ". [" + JoinUtils.join(" -> ", nameCallback, list) + "]");
             }
+            throw new DeploymentException("Circular reference is dectected, " + circularReferenceInfo, e);
         }
-        WebFragmentEntry[] WebFragments = new WebFragmentEntry[webFragmentOrderEntryList.size()];
-        int iIndex = 0;
-        for (WebFragmentOrderEntry webFragmentOrderEntry : webFragmentOrderEntryList) {
-            WebFragments[iIndex++] = webFragmentOrderEntry.webFragmentEntry;
-        }
-        saveOrderedLibAttribute(earContext, WebFragments);
-        return WebFragments;
     }
 
-    public static WebFragmentEntry[] sortWebFragments(EARContext earContext, Module module, Bundle bundle, WebApp webApp, Map<String, WebFragment> jarURLDocumentMap)
-            throws DeploymentException {
-        Map<String, WebFragmentEntry> webFragmentEntryMap = new HashMap<String, WebFragmentEntry>(jarURLDocumentMap.size());
+    public static WebFragmentEntry[] sortWebFragments(EARContext earContext, Module module, Bundle bundle, WebApp webApp, Map<String, WebFragment> jarURLDocumentMap) throws DeploymentException {
+        Map<String, WebFragmentEntry> webFragmentEntryMap = new LinkedHashMap<String, WebFragmentEntry>(jarURLDocumentMap.size());
         boolean absoluteOrderingConfigured = webApp.getAbsoluteOrdering() != null;
         Set<String> usedWebFragmentNames = new HashSet<String>();
         Map<String, WebFragment> unnamedWebFragmentMap = new HashMap<String, WebFragment>();
@@ -533,44 +556,6 @@ public class MergeHelper {
         }
     }
 
-    private static void detectCircusAfterDependency(WebFragmentOrderEntry rootWebFragmentOrderEntry, WebFragmentOrderEntry dependentWebFragmentOrderEntry,
-            Map<String, WebFragmentOrderEntry> webFragmentOrderEntryMap, Set<String> visitedWebFragmentNames) throws DeploymentException {
-        if (dependentWebFragmentOrderEntry.afterEntryNames.contains(rootWebFragmentOrderEntry.name)) {
-            throw new DeploymentException("Circus references are founded for " + rootWebFragmentOrderEntry.webFragmentEntry.getWebFragmentName() + " in the jar "
-                    + rootWebFragmentOrderEntry.webFragmentEntry.getJarURL() + ", it must be corrected or change to use absolute-ordering in web.xml file");
-        }
-        for (String subDependentWebFragmentName : dependentWebFragmentOrderEntry.afterEntryNames) {
-            if (visitedWebFragmentNames.contains(subDependentWebFragmentName)) {
-                continue;
-            }
-            visitedWebFragmentNames.add(subDependentWebFragmentName);
-            detectCircusAfterDependency(rootWebFragmentOrderEntry, webFragmentOrderEntryMap.get(subDependentWebFragmentName), webFragmentOrderEntryMap, visitedWebFragmentNames);
-        }
-    }
-
-    private static void swap(String shouldAfter, String shouldBefore, List<WebFragmentOrderEntry> webFragmentOrderEntries) {
-        int iShouldAfterIndex = -1;
-        int iShouldBeforeIndex = -1;
-        int iIndex = 0;
-        for (WebFragmentOrderEntry webFragmentOrderEntry : webFragmentOrderEntries) {
-            if (iShouldAfterIndex == -1 || iShouldBeforeIndex == -1) {
-                String currentWebFragmentName = webFragmentOrderEntry.name;
-                if (shouldAfter.equals(currentWebFragmentName)) {
-                    iShouldAfterIndex = iIndex;
-                } else if (shouldBefore.equals(currentWebFragmentName)) {
-                    iShouldBeforeIndex = iIndex;
-                }
-                iIndex++;
-            } else {
-                break;
-            }
-        }
-        if (iShouldAfterIndex < iShouldBeforeIndex) {
-            WebFragmentOrderEntry webFragmentOrderEntry = webFragmentOrderEntries.remove(iShouldAfterIndex);
-            webFragmentOrderEntries.add(iShouldBeforeIndex, webFragmentOrderEntry);
-        }
-    }
-
     private static void saveOrderedLibAttribute(EARContext earContext, WebFragmentEntry[] webFragmentEntries) {
         //Save ORDERED_LIBS Attribute
         List<String> orderedLibs = new ArrayList<String>();
@@ -583,54 +568,4 @@ public class MergeHelper {
         }
         earContext.getGeneralData().put(AbstractWebModuleBuilder.ORDERED_LIBS, orderedLibs);
     }
-
-    private static class WebFragmentOrderEntry {
-
-        public boolean afterDefined;
-
-        public Set<String> afterEntryNames = new HashSet<String>();
-
-        public boolean afterOthers;
-
-        public boolean beforeDefined;
-
-        public Set<String> beforeEntryNames = new HashSet<String>();
-
-        public boolean beforeOthers;
-
-        //Duplicate name variable is just for easily access
-        public String name;
-
-        public WebFragmentEntry webFragmentEntry;
-
-        public static WebFragmentOrderEntry create(WebFragmentEntry webFragmentEntry) throws DeploymentException {
-            WebFragmentOrderEntry webFragmentOrderEntry = new WebFragmentOrderEntry();
-            WebFragment webFragment = webFragmentEntry.getWebFragment();
-            if (webFragment.getOrdering() != null) {
-                Ordering ordering = webFragment.getOrdering();
-                OrderingOrdering after = ordering.getAfter();
-                if (after == null) {
-                    webFragmentOrderEntry.afterDefined = false;
-                } else {
-                    webFragmentOrderEntry.afterDefined = true;
-                    webFragmentOrderEntry.afterOthers = (after.getOthers() != null);
-                    webFragmentOrderEntry.afterEntryNames.addAll(after.getName());
-                }
-                OrderingOrdering before = ordering.getBefore();
-                if (before == null) {
-                    webFragmentOrderEntry.beforeDefined = false;
-                } else {
-                    webFragmentOrderEntry.beforeDefined = true;
-                    webFragmentOrderEntry.beforeOthers = (before.getOthers() != null);
-                    webFragmentOrderEntry.beforeEntryNames.addAll(before.getName());
-                }
-            }
-            if (webFragmentOrderEntry.beforeOthers && webFragmentOrderEntry.afterOthers) {
-                throw new DeploymentException("It is not allowed to define before and after others at the same time in jar " + webFragmentEntry.getJarURL());
-            }
-            webFragmentOrderEntry.webFragmentEntry = webFragmentEntry;
-            webFragmentOrderEntry.name = webFragmentEntry.getName();
-            return webFragmentOrderEntry;
-        }
-    }
 }