blob: 6b74b4dbad34bbbfa3371017f22fc6286821a537 [file] [log] [blame]
package aQute.bnd.differ;
import java.util.*;
import aQute.bnd.service.diff.*;
/**
* An element can be compared to another element of the same type. Elements with
* the same name and same place in the hierarchy should have the same type. The
* idea is that for a certain resource type you create an element (Structured or
* Leaf). This process is done for the newer and older resource.
* <p>
* A Leaf type has a value, comparison is rather simple in this case.
* <p>
* A Structured type has named children. The comparison between the newer and
* older child elements is then done on their name. Two elements with the same
* name are then matched.
* <p>
* The classes are prepared for extension but so far it turned out to be
* unnecessary.
*/
class Element implements Tree {
final static Element[] EMPTY = new Element[0];
final Type type;
final String name;
final Delta add;
final Delta remove;
final String comment;
final Element[] children;
Element(Type type, String name) {
this(type, name, null, Delta.MINOR, Delta.MAJOR, null);
}
Element(Type type, String name, Element... children) {
this(type, name, Arrays.asList(children), Delta.MINOR, Delta.MAJOR, null);
}
Element(Type type, String name, Collection< ? extends Element> children, Delta add, Delta remove, String comment) {
this.type = type;
this.name = name;
this.add = add;
this.remove = remove;
this.comment = comment;
if (children != null && children.size() > 0) {
this.children = children.toArray(new Element[children.size()]);
Arrays.sort(this.children);
} else
this.children = EMPTY;
}
public Element(Data data) {
this.name = data.name;
this.type = data.type;
this.comment = data.comment;
this.add = data.add;
this.remove = data.rem;
if (data.children == null)
children = EMPTY;
else {
this.children = new Element[data.children.length];
for (int i = 0; i < children.length; i++)
children[i] = new Element(data.children[i]);
Arrays.sort(this.children);
}
}
public Data serialize() {
Data data = new Data();
data.type = this.type;
data.name = this.name;
data.add = this.add;
data.rem = this.remove;
data.comment = this.comment;
if (children.length != 0) {
data.children = new Data[children.length];
for (int i = 0; i < children.length; i++) {
data.children[i] = children[i].serialize();
}
}
return data;
}
public Type getType() {
return type;
}
public String getName() {
return name;
}
String getComment() {
return comment;
}
public int compareTo(Tree other) {
if (type == other.getType())
return name.compareTo(other.getName());
return type.compareTo(other.getType());
}
@Override
public boolean equals(Object other) {
if (other == null || getClass() != other.getClass())
return false;
return compareTo((Element) other) == 0;
}
@Override
public int hashCode() {
return type.hashCode() ^ name.hashCode();
}
public Tree[] getChildren() {
return children;
}
public Delta ifAdded() {
return add;
}
public Delta ifRemoved() {
return remove;
}
public Diff diff(Tree older) {
return new DiffImpl(this, older);
}
public Element get(String name) {
for (Element e : children) {
if (e.name.equals(name))
return e;
}
return null;
}
@Override
public String toString() {
return type + " " + name + " (" + add + "/" + remove + ")";
}
}