Implement support for v10 model entities.
[aai/model-loader.git] / src / main / java / org / openecomp / modelloader / entity / model / ModelSorter.java
index 4dcda71..79f1c29 100644 (file)
-/*-
- * ============LICENSE_START=======================================================
- * MODEL LOADER SERVICE
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * Licensed 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.openecomp.modelloader.entity.model;
-
-import jline.internal.Log;
-
-import org.openecomp.modelloader.entity.Artifact;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Utility class to sort the given Models according to their dependencies.
- * Example: Given a list of Models [A, B, C] where B depends on A, and A depends
- * on C, the sorted result will be [C, A, B]
- */
-public class ModelSorter {
-
-  /**
-   * Wraps a Model object to form dependencies other Models using Edges.
-   */
-  static class Node {
-    private final ModelArtifact model;
-    private final HashSet<Edge> inEdges;
-    private final HashSet<Edge> outEdges;
-
-    public Node(ModelArtifact model) {
-      this.model = model;
-      inEdges = new HashSet<Edge>();
-      outEdges = new HashSet<Edge>();
-    }
-
-    public Node addEdge(Node node) {
-      Edge edge = new Edge(this, node);
-      outEdges.add(edge);
-      node.inEdges.add(edge);
-      return this;
-    }
-
-    @Override
-    public String toString() {
-      return model.getNameVersionId();
-    }
-
-    @Override
-    public boolean equals(Object other) {
-      ModelArtifact otherModel = ((Node) other).model;
-      return this.model.getNameVersionId().equals(otherModel.getNameVersionId());
-    }
-
-    @Override
-    public int hashCode() {
-      return this.model.getNameVersionId().hashCode();
-
-    }
-  }
-
-  /**
-   * Represents a dependency between two Nodes.
-   */
-  static class Edge {
-    public final Node from;
-    public final Node to;
-
-    public Edge(Node from, Node to) {
-      this.from = from;
-      this.to = to;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      Edge edge = (Edge) obj;
-      return edge.from == from && edge.to == to;
-    }
-  }
-
-  /**
-   * Returns the list of models sorted by order of dependency.
-   * 
-   * @param originalList
-   *          the list that needs to be sorted
-   * @return a list of sorted models
-   */
-  public List<Artifact> sort(List<Artifact> originalList) {
-
-    if (originalList.size() <= 1) {
-      return originalList;
-    }
-
-    Collection<Node> nodes = createNodes(originalList);
-    Collection<Node> sortedNodes = sortNodes(nodes);
-
-    List<Artifact> sortedModelsList = new ArrayList<Artifact>(sortedNodes.size());
-    for (Node node : sortedNodes) {
-      sortedModelsList.add(node.model);
-    }
-
-    return sortedModelsList;
-  }
-
-  /**
-   * Create nodes from the list of models and their dependencies.
-   * 
-   * @param models
-   *          what the nodes creation is based upon
-   * @return Collection of Node objects
-   */
-  private Collection<Node> createNodes(Collection<Artifact> models) {
-
-    // load list of models into a map, so we can later replace referenceIds with
-    // real Models
-    HashMap<String, ModelArtifact> versionIdToModelMap = new HashMap<String, ModelArtifact>();
-    for (Artifact art : models) {
-      ModelArtifact ma = (ModelArtifact) art;
-      versionIdToModelMap.put(ma.getNameVersionId(), ma);
-    }
-
-    HashMap<String, Node> nodes = new HashMap<String, Node>();
-    // create a node for each model and its referenced models
-    for (Artifact art : models) {
-      ModelArtifact model = (ModelArtifact) art;
-
-      // node might have been created by another model referencing it
-      Node node = nodes.get(model.getNameVersionId());
-
-      if (null == node) {
-        node = new Node(model);
-        nodes.put(model.getNameVersionId(), node);
-      }
-
-      for (String referencedModelId : model.getDependentModelIds()) {
-        // node might have been created by another model referencing it
-        Node referencedNode = nodes.get(referencedModelId);
-
-        if (null == referencedNode) {
-          // create node
-          ModelArtifact referencedModel = versionIdToModelMap.get(referencedModelId);
-          if (referencedModel == null) {
-            Log.debug("ignoring " + referencedModelId);
-            continue; // referenced model not supplied, no need to sort it
-          }
-          referencedNode = new Node(referencedModel);
-          nodes.put(referencedModelId, referencedNode);
-        }
-        referencedNode.addEdge(node);
-      }
-    }
-
-    return nodes.values();
-  }
-
-  /**
-   * Sorts the given Nodes by order of dependency.
-   * 
-   * @param originalList
-   *          the collection of nodes to be sorted
-   * @return a sorted collection of the given nodes
-   */
-  private Collection<Node> sortNodes(Collection<Node> unsortedNodes) {
-
-    // L <- Empty list that will contain the sorted elements
-    ArrayList<Node> nodeList = new ArrayList<Node>();
-
-    // S <- Set of all nodes with no incoming edges
-    HashSet<Node> nodeSet = new HashSet<Node>();
-    for (Node unsortedNode : unsortedNodes) {
-      if (unsortedNode.inEdges.size() == 0) {
-        nodeSet.add(unsortedNode);
-      }
-    }
-
-    // while S is non-empty do
-    while (!nodeSet.isEmpty()) {
-      // remove a node n from S
-      Node node = nodeSet.iterator().next();
-      nodeSet.remove(node);
-
-      // insert n into L
-      nodeList.add(node);
-
-      // for each node m with an edge e from n to m do
-      for (Iterator<Edge> it = node.outEdges.iterator(); it.hasNext();) {
-        // remove edge e from the graph
-        Edge edge = it.next();
-        Node to = edge.to;
-        it.remove();// Remove edge from n
-        to.inEdges.remove(edge);// Remove edge from m
-
-        // if m has no other incoming edges then insert m into S
-        if (to.inEdges.isEmpty()) {
-          nodeSet.add(to);
-        }
-      }
-    }
-    // Check to see if all edges are removed
-    boolean cycle = false;
-    for (Node node : unsortedNodes) {
-      if (!node.inEdges.isEmpty()) {
-        cycle = true;
-        break;
-      }
-    }
-    if (cycle) {
-      throw new RuntimeException(
-          "Circular dependency present between models, topological sort not possible");
-    }
-
-    return nodeList;
-  }
-
-}
+/**\r
+ * ============LICENSE_START=======================================================\r
+ * Model Loader\r
+ * ================================================================================\r
+ * Copyright © 2017 AT&T Intellectual Property.\r
+ * Copyright © 2017 Amdocs\r
+ * All rights reserved.\r
+ * ================================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ============LICENSE_END=========================================================\r
+ *\r
+ * ECOMP and OpenECOMP are trademarks\r
+ * and service marks of AT&T Intellectual Property.\r
+ */\r
+package org.openecomp.modelloader.entity.model;\r
+\r
+import jline.internal.Log;\r
+\r
+import org.openecomp.modelloader.entity.Artifact;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+/**\r
+ * Utility class to sort the given Models according to their dependencies.\r
+ * Example: Given a list of Models [A, B, C] where B depends on A, and A depends\r
+ * on C, the sorted result will be [C, A, B]\r
+ */\r
+public class ModelSorter {\r
+\r
+  /**\r
+   * Wraps a Model object to form dependencies other Models using Edges.\r
+   */\r
+  static class Node {\r
+    private final ModelArtifact model;\r
+    private final HashSet<Edge> inEdges;\r
+    private final HashSet<Edge> outEdges;\r
+\r
+    public Node(ModelArtifact model) {\r
+      this.model = model;\r
+      inEdges = new HashSet<Edge>();\r
+      outEdges = new HashSet<Edge>();\r
+    }\r
+\r
+    public Node addEdge(Node node) {\r
+      Edge edge = new Edge(this, node);\r
+      outEdges.add(edge);\r
+      node.inEdges.add(edge);\r
+      return this;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+      return model.getModelInvariantId();\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object other) {\r
+      ModelArtifact otherModel = ((Node) other).model;\r
+      return this.model.getModelInvariantId().equals(otherModel.getModelInvariantId());\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+      return this.model.getModelInvariantId().hashCode();\r
+\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Represents a dependency between two Nodes.\r
+   */\r
+  static class Edge {\r
+    public final Node from;\r
+    public final Node to;\r
+\r
+    public Edge(Node from, Node to) {\r
+      this.from = from;\r
+      this.to = to;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+      Edge edge = (Edge) obj;\r
+      return edge.from == from && edge.to == to;\r
+    }\r
+  }\r
+\r
+  /**\r
+   * Returns the list of models sorted by order of dependency.\r
+   * \r
+   * @param originalList\r
+   *          the list that needs to be sorted\r
+   * @return a list of sorted models\r
+   */\r
+  public List<Artifact> sort(List<Artifact> originalList) {\r
+\r
+    if (originalList.size() <= 1) {\r
+      return originalList;\r
+    }\r
+\r
+    Collection<Node> nodes = createNodes(originalList);\r
+    Collection<Node> sortedNodes = sortNodes(nodes);\r
+\r
+    List<Artifact> sortedModelsList = new ArrayList<Artifact>(sortedNodes.size());\r
+    for (Node node : sortedNodes) {\r
+      sortedModelsList.add(node.model);\r
+    }\r
+\r
+    return sortedModelsList;\r
+  }\r
+\r
+  /**\r
+   * Create nodes from the list of models and their dependencies.\r
+   * \r
+   * @param models\r
+   *          what the nodes creation is based upon\r
+   * @return Collection of Node objects\r
+   */\r
+  private Collection<Node> createNodes(Collection<Artifact> models) {\r
+\r
+    // load list of models into a map, so we can later replace referenceIds with\r
+    // real Models\r
+    HashMap<String, ModelArtifact> versionIdToModelMap = new HashMap<String, ModelArtifact>();\r
+    for (Artifact art : models) {\r
+      ModelArtifact ma = (ModelArtifact) art;\r
+      versionIdToModelMap.put(ma.getModelModelVerCombinedKey(), ma);\r
+    }\r
+\r
+    HashMap<String, Node> nodes = new HashMap<String, Node>();\r
+    // create a node for each model and its referenced models\r
+    for (Artifact art : models) {\r
+      ModelArtifact model = (ModelArtifact) art;\r
+\r
+      // node might have been created by another model referencing it\r
+      Node node = nodes.get(model.getModelModelVerCombinedKey());\r
+\r
+      if (null == node) {\r
+        node = new Node(model);\r
+        nodes.put(model.getModelModelVerCombinedKey(), node);\r
+      }\r
+\r
+      for (String referencedModelId : model.getDependentModelIds()) {\r
+        // node might have been created by another model referencing it\r
+        Node referencedNode = nodes.get(referencedModelId);\r
+\r
+        if (null == referencedNode) {\r
+          // create node\r
+          ModelArtifact referencedModel = versionIdToModelMap.get(referencedModelId);\r
+          if (referencedModel == null) {\r
+            Log.debug("ignoring " + referencedModelId);\r
+            continue; // referenced model not supplied, no need to sort it\r
+          }\r
+          referencedNode = new Node(referencedModel);\r
+          nodes.put(referencedModelId, referencedNode);\r
+        }\r
+        referencedNode.addEdge(node);\r
+      }\r
+    }\r
+\r
+    return nodes.values();\r
+  }\r
+\r
+  /**\r
+   * Sorts the given Nodes by order of dependency.\r
+   * \r
+   * @param originalList\r
+   *          the collection of nodes to be sorted\r
+   * @return a sorted collection of the given nodes\r
+   */\r
+  private Collection<Node> sortNodes(Collection<Node> unsortedNodes) {\r
+\r
+    // L <- Empty list that will contain the sorted elements\r
+    ArrayList<Node> nodeList = new ArrayList<Node>();\r
+\r
+    // S <- Set of all nodes with no incoming edges\r
+    HashSet<Node> nodeSet = new HashSet<Node>();\r
+    for (Node unsortedNode : unsortedNodes) {\r
+      if (unsortedNode.inEdges.size() == 0) {\r
+        nodeSet.add(unsortedNode);\r
+      }\r
+    }\r
+\r
+    // while S is non-empty do\r
+    while (!nodeSet.isEmpty()) {\r
+      // remove a node n from S\r
+      Node node = nodeSet.iterator().next();\r
+      nodeSet.remove(node);\r
+\r
+      // insert n into L\r
+      nodeList.add(node);\r
+\r
+      // for each node m with an edge e from n to m do\r
+      for (Iterator<Edge> it = node.outEdges.iterator(); it.hasNext();) {\r
+        // remove edge e from the graph\r
+        Edge edge = it.next();\r
+        Node to = edge.to;\r
+        it.remove();// Remove edge from n\r
+        to.inEdges.remove(edge);// Remove edge from m\r
+\r
+        // if m has no other incoming edges then insert m into S\r
+        if (to.inEdges.isEmpty()) {\r
+          nodeSet.add(to);\r
+        }\r
+      }\r
+    }\r
+    // Check to see if all edges are removed\r
+    boolean cycle = false;\r
+    for (Node node : unsortedNodes) {\r
+      if (!node.inEdges.isEmpty()) {\r
+        cycle = true;\r
+        break;\r
+      }\r
+    }\r
+    if (cycle) {\r
+      throw new RuntimeException(\r
+          "Circular dependency present between models, topological sort not possible");\r
+    }\r
+\r
+    return nodeList;\r
+  }\r
+\r
+}\r