blob: 602f95c776731b118823be08f8dcc8566bdd5ce6 [file] [log] [blame]
Stuart McCullochbb014372012-06-07 21:57:32 +00001package aQute.bnd.differ;
2
3import java.util.*;
4
5import aQute.bnd.service.diff.*;
6
7/**
8 * An element can be compared to another element of the same type. Elements with
9 * the same name and same place in the hierarchy should have the same type. The
10 * idea is that for a certain resource type you create an element (Structured or
11 * Leaf). This process is done for the newer and older resource.
12 * <p>
13 * A Leaf type has a value, comparison is rather simple in this case.
14 * <p>
15 * A Structured type has named children. The comparison between the newer and
16 * older child elements is then done on their name. Two elements with the same
17 * name are then matched.
18 * <p>
19 * The classes are prepared for extension but so far it turned out to be
20 * unnecessary.
21 */
22
23class Element implements Comparable<Element>, Tree {
24 final static Element[] EMPTY = new Element[0];
25 final Type type;
26 final String name;
27 final Delta add;
28 final Delta remove;
29 final String comment;
30 final Element[] children;
31
32 Element(Type type, String name) {
33 this(type, name, null, Delta.MINOR, Delta.MAJOR, null);
34 }
35
36 Element(Type type, String name, Element... children) {
37 this(type, name, Arrays.asList(children), Delta.MINOR, Delta.MAJOR, null);
38 }
39
40 Element(Type type, String name, Collection<? extends Element> children, Delta add,
41 Delta remove, String comment) {
42 this.type = type;
43 this.name = name;
44 this.add = add;
45 this.remove = remove;
46 this.comment = comment;
47 if (children != null && children.size() > 0) {
48 this.children = children.toArray(new Element[children.size()]);
49 Arrays.sort(this.children);
50 } else
51 this.children = EMPTY;
52 }
53
54 public Element(Data data) {
55 this.name = data.name;
56 this.type = data.type;
57 this.comment = data.comment;
58 this.add = data.add;
59 this.remove = data.rem;
60 if (data.children == null)
61 children = EMPTY;
62 else {
63 this.children = new Element[data.children.length];
64 for (int i = 0; i < children.length; i++)
65 children[i] = new Element(data.children[i]);
66 Arrays.sort(this.children);
67 }
68 }
69 public Data serialize() {
70 Data data = new Data();
71 data.type = this.type;
72 data.name = this.name;
73 data.add = this.add;
74 data.rem = this.remove;
75 data.comment = this.comment;
76 if (children.length != 0) {
77 data.children = new Data[children.length];
78 for (int i = 0; i < children.length; i++) {
79 data.children[i] = children[i].serialize();
80 }
81 }
82 return data;
83 }
84
85 public Type getType() {
86 return type;
87 }
88
89 public String getName() {
90 return name;
91 }
92
93 String getComment() {
94 return comment;
95 }
96
97 public int compareTo(Element other) {
98 if (type == other.type)
99 return name.compareTo(other.name);
100 else
101 return type.compareTo(other.type);
102 }
103
104 public boolean equals(Object other) {
105 if (other == null || getClass() != other.getClass())
106 return false;
107
108 return compareTo((Element) other) == 0;
109 }
110
111 public int hashCode() {
112 return type.hashCode() ^ name.hashCode();
113 }
114
115 public Tree[] getChildren() {
116 return children;
117 }
118
119 public Delta ifAdded() {
120 return add;
121 }
122
123 public Delta ifRemoved() {
124 return remove;
125 }
126
127 public Diff diff(Tree older) {
128 return new DiffImpl(this, (Element) older);
129 }
130
131 public Element get(String name) {
132 for (Element e : children) {
133 if (e.name.equals(name))
134 return e;
135 }
136 return null;
137 }
138
139 public String toString() {
140 return type + " " + name + " (" + add + "/" + remove + ")";
141 }
142
143
144}