BUG-2218: Keep existing link augmentations during discovery process
[controller.git] / opendaylight / sal / api / src / main / java / org / opendaylight / controller / sal / core / Path.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 /**
11  * @file   Path.java
12  *
13  * @brief  Describe a path as a sequence of Edge such that from
14  * each of its Head Node there is an link to the next Tail Node in the sequence
15  *
16  */
17 package org.opendaylight.controller.sal.core;
18
19 import java.io.Serializable;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.Collections;
23 import java.util.LinkedList;
24 import java.util.List;
25
26 import javax.xml.bind.annotation.XmlAccessType;
27 import javax.xml.bind.annotation.XmlAccessorType;
28 import javax.xml.bind.annotation.XmlElement;
29 import javax.xml.bind.annotation.XmlRootElement;
30
31 /**
32  * Describe a path as a sequence of Edge such that from
33  * each of its Head Node there is an link to the next Tail Node in the
34  * sequence
35  *
36  */
37 @XmlRootElement
38 @XmlAccessorType(XmlAccessType.NONE)
39 public class Path implements Serializable {
40     private static final long serialVersionUID = 1L;
41     @XmlElement
42     private List<Edge> edges;
43
44     /**
45      * Private constructor used for JAXB mapping
46      */
47     @SuppressWarnings("unused")
48     private Path() {
49         this.edges = null;
50     }
51
52     /**
53      * Construct an object representing a path, the constructor will
54      * check if the passed list of edges is such that for every
55      * consecutive edges the head node of the first edge coincide with
56      * the tail node of the subsequent in order for connectivity to be there.
57      *
58      * @param edges Edges of the path
59      *
60      */
61     public Path(List<Edge> edges) throws ConstructionException {
62         // Lets check if the list of edges is such that the head node
63         // of an edge is also the tail node of the subsequent one
64         boolean sequential = true;
65         if (edges.size() >= 2) {
66             for (int i = 0; i < edges.size() - 1; i++) {
67                 Edge current = edges.get(i);
68                 Edge next = edges.get(i + 1);
69                 if (!current.getHeadNodeConnector().getNode().equals(next.getTailNodeConnector().getNode())) {
70                     sequential = false;
71                     break;
72                 }
73             }
74         } else if (edges.size() == 0) {
75             throw new ConstructionException("Path is empty");
76         }
77
78         if (!sequential) {
79             throw new ConstructionException("Path is not sequential");
80         }
81
82         this.edges = edges;
83     }
84
85     /**
86      * Create the reversed path
87      * @return The reversed path
88      */
89     public Path reverse() {
90         int j = edges.size(); // size always > 0
91         Edge[]  aEdges = new Edge[j];
92         for (Edge e : edges) {
93             j--;
94             aEdges[j] = e.reverse();
95         }
96         Path rp;
97         try {
98          rp = new Path(Arrays.asList(aEdges));
99         } catch (ConstructionException ce) {
100             rp = null;
101         }
102         return rp;
103     }
104
105     /**
106      * Return the list of nodes of this path, the first node is the start node
107      * @return the list of nodes
108      */
109     public List<Node> getNodes() {
110         List<Node> nl = new ArrayList<Node>();
111         nl.add(this.getStartNode());
112         for (Edge e : edges) {
113             nl.add(e.getHeadNodeConnector().getNode());
114         }
115         return nl;
116     }
117
118     /**
119      * Copy Construct for a path
120      *
121      * @param src Path to copy from
122      *
123      */
124     public Path(Path src) throws ConstructionException {
125         if (src != null) {
126             this.edges = new LinkedList<Edge>(src.getEdges());
127         } else {
128             throw new ConstructionException("src supplied was null");
129         }
130     }
131
132     /**
133      * get the First Node of the path
134      *
135      *
136      * @return The start Node of the Path
137      */
138     public Node getStartNode() {
139         return this.edges.get(0).getTailNodeConnector().getNode();
140     }
141
142     /**
143      * get the Last Node of the path
144      *
145      *
146      * @return The last Node of the Path
147      */
148     public Node getEndNode() {
149         return this.edges.get(this.edges.size() - 1).getHeadNodeConnector()
150                 .getNode();
151     }
152
153     /**
154      * getter method for the Path
155      *
156      *
157      * @return Return the list of edges that constitute the Path
158      */
159     public List<Edge> getEdges() {
160         return (edges == null) ? Collections.<Edge>emptyList() : new ArrayList<Edge>(edges);
161     }
162
163     @Override
164     public int hashCode() {
165         final int prime = 31;
166         int result = 1;
167         result = prime * result + ((edges == null) ? 0 : edges.hashCode());
168         return result;
169     }
170
171     @Override
172     public boolean equals(Object obj) {
173         if (this == obj) {
174             return true;
175         }
176         if (obj == null) {
177             return false;
178         }
179         if (getClass() != obj.getClass()) {
180             return false;
181         }
182         Path other = (Path) obj;
183         if (edges == null) {
184             if (other.edges != null) {
185                 return false;
186             }
187         } else if (!edges.equals(other.edges)) {
188             return false;
189         }
190         return true;
191     }
192
193     @Override
194     public String toString() {
195         StringBuilder sb = new StringBuilder();
196         sb.append("[");
197         for (int i = 0; i < this.edges.size(); i++) {
198             if (i != 0) {
199                 // add the comma to the previous element
200                 sb.append(",");
201             }
202             sb.append(this.edges.get(i).toString());
203         }
204         sb.append("]");
205         return sb.toString();
206     }
207 }