| 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 + ")"; |
| } |
| |
| } |