Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved.
   *
   * The contents of this file are subject to the terms of either the GNU
   * General Public License Version 2 only ("GPL") or the Common Development
   * and Distribution License("CDDL") (collectively, the "License").  You
   * may not use this file except in compliance with the License.  You can
  * obtain a copy of the License at
  * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
  * or packager/legal/LICENSE.txt.  See the License for the specific
  * language governing permissions and limitations under the License.
  *
  * When distributing the software, include this License Header Notice in each
  * file and include the License file at packager/legal/LICENSE.txt.
  *
  * GPL Classpath Exception:
  * Oracle designates this particular file as subject to the "Classpath"
  * exception as provided by Oracle in the GPL Version 2 section of the License
  * file that accompanied this code.
  *
  * Modifications:
  * If applicable, add the following below the License Header, with the fields
  * enclosed by brackets [] replaced by your own identifying information:
  * "Portions Copyright [year] [name of copyright owner]"
  *
  * Contributor(s):
  * If you wish your version of this file to be governed by only the CDDL or
  * only the GPL Version 2, indicate your decision by adding "[Contributor]
  * elects to include this software in this distribution under the [CDDL or GPL
  * Version 2] license."  If you don't indicate a single choice of license, a
  * recipient has the option to distribute your version of this file under
  * either the CDDL, the GPL Version 2 or to extend the choice of license to
  * its licensees as provided above.  However, if you add GPL Version 2 code
  * and therefore, elected the GPL Version 2 license, then the option applies
  * only if the new code is made subject to such option by the copyright
  * holder.
  */
 
 package org.glassfish.web.deployment.descriptor;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
This represents the ordering resided in web-fragment.xml.

Author(s):
Shing Wai Chan
 
 
 public class OrderingDescriptor extends Descriptor {
     private static LocalStringManagerImpl localStrings =
             new LocalStringManagerImpl(OrderingDescriptor.class);
 
     OrderingOrderingDescriptor after = null;
     
 
     public OrderingOrderingDescriptor getAfter() {
         return ;
     }
 
     public void setAfter(OrderingOrderingDescriptor after) {
         this. = after;
         validate();
     }
 
     public OrderingOrderingDescriptor getBefore() {
         return ;
     }
 
     public void setBefore(OrderingOrderingDescriptor before) {
         this. = before;
         validate();
     }
 
     public void validate() {
         boolean valid = true;
         if ( != null &&  != null) {
             if (.containsOthers() && .containsOthers()) {
                 valid = false;
             }
             if (valid) {
                 for (String name : .getNames()) {
                     if (.containsName(name)) {
                         valid = false;
                         break;
                     }
                 }
            }
        }
        if (!valid) {
            throw new IllegalStateException(.getLocalString(
                    "enterprise.deployment.exceptioninvalidordering",
                    "The ordering is not valid as it contains the same name and/or others in both before and after."));
        }
    }
    public String toString() {
        StringBuilder builder = new StringBuilder();
        if ( != null) {
            builder.append("after: " +  + ", ");
        }
        if ( != null) {
            builder.append("before: " + );
        }
        return builder.toString();
    }
    // ----- sorting logic
    public static void sort(List<WebFragmentDescriptorwfs) {
        if (wfs == null || wfs.size() <= 1) {
            return;
        }
        // build the graph
        List<Nodegraph = new ArrayList<Node>();
        Map<StringNodename2NodeMap = new HashMap<StringNode>();
        // build the nodes
        Node othersNode = new Node(null);
        for (WebFragmentDescriptor wf : wfs) {
            Node wfNode = new Node(wf);
            String wfName = wf.getName();
            if (wfName != null && wfName.length() > 0) {
                name2NodeMap.put(wfNamewfNode);
            }
            graph.add(wfNode);
        }
        List<Noderemaining = new ArrayList<Node>(graph);
        // build the edges
        // othersNode is not in the loop
        Map<NodeMap<NodeEdge>> map = new HashMap<NodeMap<NodeEdge>>();
        for (int i = 0; i < graph.size(); i++) {
            Node wfNode = graph.get(i);
            WebFragmentDescriptor wf = wfNode.getWebFragmentDescriptor();
            String wfName = wf.getName();
            OrderingDescriptor od = wf.getOrderingDescriptor();
            if (od != null) {
                OrderingOrderingDescriptor after = od.getAfter();
                if (after != null) {
                    if (after.containsOthers()) {
                        // othersNode --> wfNode
                        wfNode.getInEdges().add(getEdge(othersNodewfNodemap));
                        othersNode.getOutEdges().add(getEdge(othersNodewfNodemap));
                        remaining.remove(othersNode);
                    }
                    for (String name : after.getNames()) {
                        // nameNode --> wfNode
                        Node nameNode = name2NodeMap.get(name);
                        if (nameNode != null) {
                            wfNode.getInEdges().add(
                                    getEdge(nameNodewfNodemap));
                            nameNode.getOutEdges().add(
                                    getEdge(nameNodewfNodemap));
                            remaining.remove(nameNode);
                        }
                    }
                }
                OrderingOrderingDescriptor before = od.getBefore();
                if (before != null) {
                    if (before.containsOthers()) {
                        // wfNode --> othersNode
                        wfNode.getOutEdges().add(getEdge(wfNodeothersNodemap));
                        othersNode.getInEdges().add(getEdge(wfNodeothersNodemap));
                        remaining.remove(othersNode);
                    }
                    for (String name : before.getNames()) {
                        // wfNode --> nameNode
                        Node nameNode = name2NodeMap.get(name);
                        if (nameNode != null) {
                            wfNode.getOutEdges().add(
                                    getEdge(wfNodenameNodemap));
                            nameNode.getInEdges().add(
                                    getEdge(wfNodenameNodemap));
                            remaining.remove(nameNode);
                        }
                    }
                }
                boolean hasAfterOrdering = (after != null &&
                        (after.containsOthers() || after.getNames().size() > 0));
                boolean hasBeforeOrdering = (before != null &&
                        (before.containsOthers() || before.getNames().size() > 0));
                if (hasAfterOrdering || hasBeforeOrdering) {
                    remaining.remove(wfNode);
                }
            }
        }
        // if others should be in the graph
        if (othersNode.getOutEdges().size() > 0 || othersNode.getInEdges().size() > 0) {
            // add others to the end
            graph.add(othersNode);
            // populate others info into nodes
            Stack<NodeafterOthersStack = new Stack<Node>();
            for (Edge edge : othersNode.getOutEdges()) {
                edge.setVisited(true);
                afterOthersStack.push(edge.getToNode());
            }
            while (!afterOthersStack.isEmpty()) {
                Node aNode = afterOthersStack.pop();
                aNode.setAfterOthers(true);
                for (Edge edge : aNode.getOutEdges()) {
                    if (!edge.isVisited()) {
                        afterOthersStack.push(edge.getToNode());
                        edge.setVisited(true);
                    }
                }
            }
            Stack<NodebeforeOthersStack = new Stack<Node>();
            for (Edge edge : othersNode.getInEdges()) {
                edge.setVisited(true);
                beforeOthersStack.push(edge.getFromNode());
            }
            while (!beforeOthersStack.isEmpty()) {
                Node aNode = beforeOthersStack.pop();
                aNode.setBeforeOthers(true);
                for (Edge edge : aNode.getInEdges()) {
                    if (!edge.isVisited()) {
                        beforeOthersStack.push(edge.getFromNode());
                        edge.setVisited(true);
                    }
                }
            }
        }
        List<Nodesubgraph = new ArrayList<Node>(graph);
        subgraph.removeAll(remaining);
        boolean hasRemaining = (remaining.size() > 0);
        List<NodesortedNodes = topologicalSort(subgraphhasRemaining);
        wfs.clear();
        boolean othersProcessed = false;
        for (Node nodesortedNodes) {
            if (node.isOthers()) {
                // others
                othersProcessed = true;
                for (Node rnoderemaining) {
                    wfs.add(rnode.getWebFragmentDescriptor());
                }
            } else {
                wfs.add(node.getWebFragmentDescriptor());
            }
        }
        if (!othersProcessed) {
            for (Node rnoderemaining) {
                wfs.add(rnode.getWebFragmentDescriptor());
            }
        }
    }
    private static Edge getEdge(Node fromNode toMap<NodeMap<NodeEdge>> map) {
        Edge edge = null;
        Map<NodeEdgenode2Edge = map.get(from);
        if (node2Edge == null) {
            node2Edge = new HashMap<NodeEdge>();
            map.put(fromnode2Edge);
        } else {
            edge = node2Edge.get(to);
        }
        if (edge == null) {
            edge = new Edge(fromto);
            node2Edge.put(toedge);
        }
        return edge;
    }

    
Note that this processing will modify the graph. It is not intended for public.

Parameters:
graph
hasRemaining
Returns:
a sorted list of Node
    private static List<NodetopologicalSort(List<Nodegraphboolean hasRemaining) {
        List<NodesortedNodes = new ArrayList<Node>();
        if (graph.size() == 0) {
            return sortedNodes;
        }
        Stack<Noderoots = new Stack<Node>();
        Stack<NoderootsBefore = new Stack<Node>();
        Stack<NoderootsAfter = new Stack<Node>(); // including others if any
        // find nodes without incoming edges
        for (Node nodegraph) {
            if (node.getInEdges().size() == 0) {
                if (node.isBeforeOthers()) {
                    rootsBefore.add(node);
                } else if (node.isAfterOthers() || node.isOthers()) {
                    rootsAfter.add(node);
                } else {
                    roots.add(node);
                }
            }
        }
        
        if (roots.empty() && rootsBefore.empty() && rootsAfter.empty()) {
            // check if it is a circle with others and empty remaining
            if (isCircleWithOthersAndNoRemaining(graphhasRemainingsortedNodes)) {
                return sortedNodes;
            } else {
                throw new IllegalStateException(.getLocalString(
                        "enterprise.deployment.exceptioninvalidwebfragmentordering",
                        "The web fragment ordering is not valid and possibly has cycling conflicts."));
            }
        }
        while (!(roots.empty() && rootsBefore.empty() && rootsAfter.empty())) {
            Node node = null;
            if (!rootsBefore.empty()) {
                node = rootsBefore.pop();
            } else if (!roots.empty()) {
                node = roots.pop();
            } else { // !rootsAfter.empty()
                node = rootsAfter.pop();
            } 
            sortedNodes.add(node);
            // for each outcoming edges
            Iterator<EdgeoutEdgesIter = node.getOutEdges().iterator();
            while (outEdgesIter.hasNext()) {
                Edge outEdge = outEdgesIter.next();
                Node outNode = outEdge.getToNode();
                // remove the outcoming edge
                outEdgesIter.remove();
                // remove corresponding incoming edge from the outNode
                outNode.getInEdges().remove(outEdge);
                // if no incoming edge
                if (outNode.getInEdges().size() == 0) {
                    // the others node
                    if (node.isBeforeOthers()) {
                        rootsBefore.add(outNode);
                    } else if (node.isAfterOthers() || node.isOthers()) {
                        rootsAfter.add(outNode);
                    } else {
                        roots.add(outNode);
                    }
                }
            }
        }
        boolean hasEdges = false;
        for (Node nodegraph) {
            if (node.getInEdges().size() > 0 || node.getOutEdges().size() > 0) {
                hasEdges = true;
                break;
            }
        }
        if (hasEdges) {
            throw new IllegalStateException(.getLocalString(
                    "enterprise.deployment.exceptioninvalidwebfragmentordering",
                    "The web fragment ordering is not valid and possibly has cycling conflicts."));
        }
        return sortedNodes;
    }

    
This method will check whether the graph does not have remaining vertices and is a circle with others. It return the sorted result in sortedNodes.

Parameters:
graph the input graph
hasRemaining
sortedNodes output sorted result if it is a circle with empty others
Returns:
boolean indicating whether it is a circle with an empty others
    private static boolean isCircleWithOthersAndNoRemaining(List<Nodegraph,
            boolean hasRemainingList<Node>sortedNodes) {
        boolean circleWithOthersAndNoRemaining = false;
        int size = graph.size();
        if (size == 0 || hasRemaining) {
            return circleWithOthersAndNoRemaining;
        }
        Node nextNode = graph.get(size - 1);
        if (nextNode.isOthers()) {
            Set<Nodeset = new LinkedHashSet<Node>();
            int count = 0;
            while ((count < size) &&
                    nextNode.getOutEdges().size() == 1 &&
                    nextNode.getInEdges().size() == 1) {
                if (!set.add(nextNode)) {
                    break;
                }
                nextNode = nextNode.getOutEdges().iterator().next().getToNode();
                count++;
            }
            if (set.size() == size) {
                circleWithOthersAndNoRemaining = true;
                Iterator<Nodeiter = set.iterator();
                // exclude others
                if (iter.hasNext()) {
                    iter.next();
                }
                while (iter.hasNext()) {
                   sortedNodes.add(iter.next());
                }
            }
        }
        return circleWithOthersAndNoRemaining;
    }
    // for debug
    private static void print(WebFragmentDescriptor wf,
            String nullWfStringStringBuilder sb) {
        String wfName = null;
        if (wf != null) {
            wfName = wf.getName();
        } else {
            wfName = nullWfString;
        }
        sb.append(wfName);
    }
    private static class Node {
        private WebFragmentDescriptor webFragmentDescriptor = null;
        private Set<EdgeinEdges = new LinkedHashSet<Edge>();
        private Set<EdgeoutEdges = new LinkedHashSet<Edge>();
        // for sorting
        private boolean afterOthers = false;
        private boolean beforeOthers = false;
        private Node(WebFragmentDescriptor wf) {
             = wf;
        }
        private WebFragmentDescriptor getWebFragmentDescriptor() {
            return ;
        }
        private Set<EdgegetInEdges() {
            return ;
        }
        private Set<EdgegetOutEdges() {
            return ;
        }
        private boolean isOthers() {
            return ( == null);
        }
        private boolean isAfterOthers() {
            return ;
        }
        private void setAfterOthers(boolean afterOthers) {
            this. = afterOthers;
        }
        private boolean isBeforeOthers() {
            return ;
        }
        private void setBeforeOthers(boolean beforeOthers) {
            this. = beforeOthers;
        }
        // for debug
        public String toString() {
            StringBuilder sb = new StringBuilder("{name=");
            print("@others"sb);
            sb.append(", inNodes=[");
            boolean first = true;
            for (Edge e) {
                if (!first) {
                    sb.append(", ");
                }
                first = false;
                print(e.getFromNode().getWebFragmentDescriptor(), "@others"sb);
            }
            sb.append("]");
            sb.append(", outNodes=[");
            first = true;
            for (Edge e) {
                if (!first) {
                    sb.append(", ");
                }
                first = false;
                print(e.getToNode().getWebFragmentDescriptor(), "@others"sb);
            }
            sb.append("]}");
            return sb.toString();
        }
    }
    // an edge with data
    private static final class Edge {
        private Node fromNode = null;
        private Node toNode = null;
        private boolean visited = false;
        private Edge(Node fromNode to) {
             = from;
             = to;
        }
        private Node getFromNode() {
            return ;
        }
        private Node getToNode() {
            return ;
        }
        private boolean isVisited() {
            return ;
        }
        private void setVisited(boolean vt) {
             = vt;
        }
    }
New to GrepCode? Check out our FAQ X