Merge "Updated Concepts descriptions"
[yangtools.git] / yang / yang-binding / src / main / java / org / opendaylight / yangtools / yang / binding / InstanceIdentifier.java
1 /*\r
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 package org.opendaylight.yangtools.yang.binding;\r
9 \r
10 import java.util.ArrayList;\r
11 import java.util.Collections;\r
12 import java.util.List;\r
13 \r
14 import org.opendaylight.yangtools.concepts.Builder;\r
15 import org.opendaylight.yangtools.concepts.Immutable;\r
16 import org.opendaylight.yangtools.concepts.Mutable;\r
17 \r
18 /**\r
19  * Uniquely identifies instance of data tree.\r
20  * \r
21  */\r
22 public class InstanceIdentifier implements Immutable {\r
23 \r
24     private final List<PathArgument> path;\r
25     private final Class<? extends DataObject> targetType;\r
26 \r
27     public InstanceIdentifier(Class<? extends DataObject> type) {\r
28         path = Collections.emptyList();\r
29         this.targetType = type;\r
30     }\r
31 \r
32     public InstanceIdentifier(List<PathArgument> path, Class<? extends DataObject> type) {\r
33         this.path = Collections.<PathArgument> unmodifiableList(new ArrayList<>(path));\r
34         this.targetType = type;\r
35     }\r
36 \r
37     /**\r
38      * \r
39      * @return path\r
40      */\r
41     public List<PathArgument> getPath() {\r
42         return this.path;\r
43     }\r
44 \r
45     public Class<?> getTargetType() {\r
46         return this.targetType;\r
47     }\r
48 \r
49     @Override\r
50     public String toString() {\r
51         return "InstanceIdentifier [path=" + path + "]";\r
52     }\r
53 \r
54     /**\r
55      * Path argument of instance identifier.\r
56      * \r
57      * Interface which implementations are used as path components of the\r
58      * instance path.\r
59      * \r
60      * @author ttkacik\r
61      * \r
62      */\r
63     public interface PathArgument {\r
64 \r
65         Class<? extends DataObject> getType();\r
66 \r
67     }\r
68 \r
69     public static class Item<T extends DataObject> implements PathArgument {\r
70         private final Class<T> type;\r
71 \r
72         public Item(Class<T> type) {\r
73             this.type = type;\r
74         }\r
75 \r
76         public Class<T> getType() {\r
77             return type;\r
78         }\r
79 \r
80         @Override\r
81         public int hashCode() {\r
82             final int prime = 31;\r
83             int result = 1;\r
84             result = prime * result + ((type == null) ? 0 : type.hashCode());\r
85             return result;\r
86         }\r
87 \r
88         @Override\r
89         public boolean equals(Object obj) {\r
90             if (this == obj)\r
91                 return true;\r
92             if (obj == null)\r
93                 return false;\r
94             if (getClass() != obj.getClass())\r
95                 return false;\r
96             Item<?> other = (Item<?>) obj;\r
97             if (type == null) {\r
98                 if (other.type != null)\r
99                     return false;\r
100             } else if (!type.equals(other.type))\r
101                 return false;\r
102             return true;\r
103         }\r
104     }\r
105 \r
106     public static class IdentifiableItem<I extends Identifiable<T> & DataObject, T extends Identifier<I>> implements\r
107             PathArgument {\r
108 \r
109         private final T key;\r
110         private final Class<I> type;\r
111 \r
112         public IdentifiableItem(Class<I> type, T key) {\r
113             this.type = type;\r
114             this.key = key;\r
115         }\r
116 \r
117         T getKey() {\r
118             return this.key;\r
119         }\r
120 \r
121         @Override\r
122         public Class<I> getType() {\r
123             return this.type;\r
124         }\r
125 \r
126         @Override\r
127         public boolean equals(Object obj) {\r
128             if (obj == null) {\r
129                 return false;\r
130             }\r
131             if (obj.hashCode() != hashCode()) {\r
132                 return false;\r
133             }\r
134             if (!(obj instanceof IdentifiableItem<?, ?>)) {\r
135                 return false;\r
136             }\r
137             IdentifiableItem<?, ?> foreign = (IdentifiableItem<?, ?>) obj;\r
138             return key.equals(foreign.getKey());\r
139         }\r
140 \r
141         @Override\r
142         public int hashCode() {\r
143             return key.hashCode();\r
144         }\r
145 \r
146         @Override\r
147         public String toString() {\r
148             return type.getName()+"[key=" + key + "]";\r
149         }\r
150     }\r
151 \r
152     public interface InstanceIdentifierBuilder extends Builder<InstanceIdentifier> {\r
153 \r
154         <T extends DataObject> InstanceIdentifierBuilder node(Class<T> container);\r
155 \r
156         <I extends Identifiable<T> & DataObject, T extends Identifier<I>> InstanceIdentifierBuilder node(\r
157                 Class<I> listItem, T listKey);\r
158 \r
159     }\r
160 \r
161     public static InstanceIdentifierBuilder builder() {\r
162         return new BuilderImpl();\r
163     }\r
164 \r
165     private static class BuilderImpl implements InstanceIdentifierBuilder {\r
166 \r
167         private List<PathArgument> path;\r
168         private Class<? extends DataObject> target = null;\r
169 \r
170         @Override\r
171         public InstanceIdentifier toInstance() {\r
172             List<PathArgument> immutablePath = Collections.unmodifiableList(new ArrayList<PathArgument>(path));\r
173             return new InstanceIdentifier(immutablePath, target);\r
174         }\r
175 \r
176         @Override\r
177         public <T extends DataObject> InstanceIdentifierBuilder node(Class<T> container) {\r
178             target = container;\r
179             path.add(new Item<T>(container));\r
180             return this;\r
181         }\r
182 \r
183         @Override\r
184         public <I extends Identifiable<T> & DataObject, T extends Identifier<I>> InstanceIdentifierBuilder node(\r
185                 Class<I> listItem, T listKey) {\r
186             target = listItem;\r
187             path.add(new IdentifiableItem<I, T>(listItem, listKey));\r
188             return this;\r
189         }\r
190 \r
191     }\r
192 }\r