/*
* Created on Jul 15, 2004
*/
package edu.sc.seis.sod.validator.tour;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import edu.sc.seis.sod.validator.model.Attribute;
import edu.sc.seis.sod.validator.model.Choice;
import edu.sc.seis.sod.validator.model.Data;
import edu.sc.seis.sod.validator.model.Form;
import edu.sc.seis.sod.validator.model.Group;
import edu.sc.seis.sod.validator.model.Interleave;
import edu.sc.seis.sod.validator.model.MultigenitorForm;
import edu.sc.seis.sod.validator.model.NamedElement;
import edu.sc.seis.sod.validator.model.Text;
import edu.sc.seis.sod.validator.model.Value;
/**
* @author Charlie Groves
*/
public class DepthAwareGuide implements TourGuide {
public DepthAwareGuide(Form root) {
this.root = root;
if(root instanceof MultigenitorForm) {
allowableDepth = 1;
}
}
public void lead(Tourist visitor) {
internalLead(visitor, root);
}
public void internalLead(Tourist visitor, Form curForm) {
if(calcDistance(curForm) > allowableDepth
&& curForm.getParent().isFromDef()
&& (!(curForm instanceof Value))) { return; }
if(curForm instanceof NamedElement) {
NamedElement cur = (NamedElement)curForm;
visitor.visit(cur);
internalLead(visitor, cur.getChild());
visitor.leave(cur);
} else if(curForm instanceof Choice) {
Choice c = (Choice)curForm;
visitor.visit(c);
handleKids(visitor, c, true);
visitor.leave(c);
} else if(curForm instanceof Group) {
Group g = (Group)curForm;
visitor.visit(g);
handleKids(visitor, g, false);
visitor.leave(g);
} else if(curForm instanceof Interleave) {
Interleave g = (Interleave)curForm;
visitor.visit(g);
handleKids(visitor, g, true);
visitor.leave(g);
} else if(curForm instanceof Value) {
visitor.visit((Value)curForm);
} else if(curForm instanceof Data) {
visitor.visit((Data)curForm);
} else if(curForm instanceof Text) {
visitor.visit((Text)curForm);
} else if(curForm instanceof Attribute) {
Attribute attr = (Attribute)curForm;
visitor.visit(attr);
internalLead(visitor, attr.getChild());
visitor.leave(attr);
}
}
private void handleKids(Tourist visitor, MultigenitorForm f, boolean sort) {
Form[] children = f.getChildren();
List<Form> tosort = Arrays.asList(children);
if (sort) {
Collections.sort(tosort, new Comparator<Form>() {
@Override
public int compare(Form o1, Form o2) {
if (o1.isFromDef() && o2.isFromDef()) {
return o1.getDef().getName().toLowerCase().compareTo(o2.getDef().getName().toLowerCase());
} else {
return 0;
}
}
});
}
for (Form form : tosort) {
internalLead(visitor, form);
}
}
public int calcDistance(Form f) {
if(f.equals(root)) { return 0; }
return calcDistance(f.getParent()) + 1;
}
int allowableDepth = 2;
private Form root;
}