blob: 19a6bd92a515e84a03309f22c2d9f56d022c3fae [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
tome3489412014-08-29 02:30:38 -070019package org.onlab.graph;
20
21import com.google.common.collect.ImmutableList;
22
23import java.util.ArrayList;
24import java.util.List;
25import java.util.Objects;
26
tomeadbb462014-09-07 16:10:19 -070027import static com.google.common.base.MoreObjects.toStringHelper;
tome3489412014-08-29 02:30:38 -070028import static com.google.common.base.Preconditions.checkArgument;
29import static com.google.common.base.Preconditions.checkNotNull;
30
31/**
32 * Simple concrete implementation of a directed graph path.
33 */
34public class DefaultMutablePath<V extends Vertex, E extends Edge<V>> implements MutablePath<V, E> {
35
tome3489412014-08-29 02:30:38 -070036 private final List<E> edges = new ArrayList<>();
37 private double cost = 0.0;
38
39 /**
40 * Creates a new empty path.
41 */
42 public DefaultMutablePath() {
43 }
44
45 /**
46 * Creates a new path as a copy of another path.
47 *
48 * @param path path to be copied
49 */
50 public DefaultMutablePath(Path<V, E> path) {
51 checkNotNull(path, "Path cannot be null");
tome3489412014-08-29 02:30:38 -070052 this.cost = path.cost();
53 edges.addAll(path.edges());
54 }
55
56 @Override
57 public V src() {
tom144de692014-08-29 11:38:44 -070058 return edges.isEmpty() ? null : edges.get(0).src();
tome3489412014-08-29 02:30:38 -070059 }
60
61 @Override
62 public V dst() {
tom144de692014-08-29 11:38:44 -070063 return edges.isEmpty() ? null : edges.get(edges.size() - 1).dst();
tome3489412014-08-29 02:30:38 -070064 }
65
66 @Override
67 public double cost() {
68 return cost;
69 }
70
71 @Override
72 public List<E> edges() {
73 return ImmutableList.copyOf(edges);
74 }
75
76 @Override
77 public void setCost(double cost) {
78 this.cost = cost;
79 }
80
81 @Override
82 public Path<V, E> toImmutable() {
83 return new DefaultPath<>(edges, cost);
84 }
85
86 @Override
tom144de692014-08-29 11:38:44 -070087 public void insertEdge(E edge) {
88 checkNotNull(edge, "Edge cannot be null");
89 checkArgument(edges.isEmpty() || src().equals(edge.dst()),
90 "Edge destination must be the same as the current path source");
91 edges.add(0, edge);
92 }
93
94 @Override
tome3489412014-08-29 02:30:38 -070095 public void appendEdge(E edge) {
96 checkNotNull(edge, "Edge cannot be null");
tom144de692014-08-29 11:38:44 -070097 checkArgument(edges.isEmpty() || dst().equals(edge.src()),
tome3489412014-08-29 02:30:38 -070098 "Edge source must be the same as the current path destination");
tome3489412014-08-29 02:30:38 -070099 edges.add(edge);
100 }
101
102 @Override
tom144de692014-08-29 11:38:44 -0700103 public void removeEdge(E edge) {
104 checkArgument(edge.src().equals(edge.dst()) ||
105 edges.indexOf(edge) == 0 ||
106 edges.lastIndexOf(edge) == edges.size() - 1,
107 "Edge must be at start or end of path, or it must be a cyclic edge");
108 edges.remove(edge);
tome3489412014-08-29 02:30:38 -0700109 }
110
111 @Override
112 public String toString() {
tomeadbb462014-09-07 16:10:19 -0700113 return toStringHelper(this)
tom144de692014-08-29 11:38:44 -0700114 .add("src", src())
115 .add("dst", dst())
tome3489412014-08-29 02:30:38 -0700116 .add("cost", cost)
117 .add("edges", edges)
118 .toString();
119 }
120
121 @Override
122 public int hashCode() {
tom144de692014-08-29 11:38:44 -0700123 return Objects.hash(edges, cost);
tome3489412014-08-29 02:30:38 -0700124 }
125
126 @Override
127 public boolean equals(Object obj) {
tomfc9a4ff2014-09-22 18:22:47 -0700128 if (this == obj) {
129 return true;
130 }
tome3489412014-08-29 02:30:38 -0700131 if (obj instanceof DefaultMutablePath) {
132 final DefaultMutablePath other = (DefaultMutablePath) obj;
tom144de692014-08-29 11:38:44 -0700133 return Objects.equals(this.cost, other.cost) &&
tome3489412014-08-29 02:30:38 -0700134 Objects.equals(this.edges, other.edges);
135 }
136 return false;
137 }
tom144de692014-08-29 11:38:44 -0700138
tome3489412014-08-29 02:30:38 -0700139}