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