001package org.clafer.instance;
002
003import java.io.IOException;
004import java.util.ArrayList;
005import java.util.List;
006import org.clafer.ast.AstClafer;
007import org.clafer.ast.AstConcreteClafer;
008import org.clafer.common.Check;
009
010/**
011 *
012 * @author jimmy
013 */
014public class InstanceClafer {
015
016    private final AstClafer type;
017    private final int id;
018    private final InstanceRef ref;
019    private final InstanceClafer[] children;
020
021    public InstanceClafer(AstClafer type, int id, InstanceRef ref, InstanceClafer... children) {
022        this.type = Check.notNull(type);
023        this.id = id;
024        this.ref = ref;
025        this.children = Check.noNulls(children);
026    }
027
028    public AstClafer getType() {
029        return type;
030    }
031
032    public int getId() {
033        return id;
034    }
035
036    public boolean hasRef() {
037        return ref != null;
038    }
039
040    public InstanceRef getRef() {
041        return ref;
042    }
043
044    public boolean hasChildren() {
045        return children.length != 0;
046    }
047
048    public InstanceClafer[] getChildren() {
049        return children;
050    }
051    
052    public InstanceClafer[] getChildren(AstConcreteClafer type) {
053        List<InstanceClafer> typedChildren = new ArrayList<>();
054        for(InstanceClafer child : children) {
055            if(type.equals(child.getType())) {
056                typedChildren.add(child);
057            }
058        }
059        return typedChildren.toArray(new InstanceClafer[typedChildren.size()]);
060    }
061
062    /**
063     * Print solution to stdout.
064     *
065     * @throws IOException an IO error occurred
066     */
067    public void print() throws IOException {
068        print(System.out);
069    }
070
071    /**
072     * Print solution.
073     *
074     * @param out the stream to print to
075     * @throws IOException an IO error occurred
076     */
077    public void print(Appendable out) throws IOException {
078        print("", out);
079    }
080
081    private void print(String indent, Appendable out) throws IOException {
082        out.append(indent).append(type.getName()).append("#").append(Integer.toString(id));
083        if(hasRef()) {
084            out.append(" = ").append(ref.toString());
085        }
086        out.append('\n');
087        for (InstanceClafer child : getChildren()) {
088            child.print(indent + "    ", out);
089        }
090    }
091
092    @Override
093    public String toString() {
094        StringBuilder result = new StringBuilder();
095        try {
096            print(result);
097        } catch (IOException e) {
098            // StringBuilder should not throw an IOException.
099            throw new Error(e);
100        }
101        return result.toString();
102    }
103}