package bibliothek.help.javadoc;
import java.util.HashSet;
import java.util.Set;
import bibliothek.help.model.Entry;
import com.sun.javadoc.ClassDoc;
/**
* An {@link Entryable} that creates a tree showing the type-hierarchy
* of a class or interface. The tree contains all classes and interfaces
* which are extended or implemented by the starting class or interface.<br>
* Some interfaces might occur more than once in the tree, because they
* might be implemented by different classes and interfaces.
* @author Benjamin Sigg
*
*/
@Content(type="hierarchy-class", encoding=Content.Encoding.TREE)
public class EntryableHierarchyClass extends AbstractEntryable{
/** the root of the tree */
private ClassDoc doc;
/**
* Creates a new type-hierarchy.
* @param doc the root of the tree
*/
public EntryableHierarchyClass( ClassDoc doc ){
this.doc = doc;
putClass( doc, null );
}
/**
* Writes the name of the class <code>doc</code> and collects all
* children of the node <code>doc</code>.
* @param doc a class
* @param collecting a set that will be filled with each interface
* that was found by this method.
*/
private void putClass( ClassDoc doc, Set<String> collecting ){
Set<String> done = new HashSet<String>();
if( doc.superclass() != null )
putClass( doc.superclass(), done );
mode( "class", type( doc ), doc.name(), doc.qualifiedName() );
for( ClassDoc inter : doc.interfaces() )
putInterface( inter, done, collecting );
}
/**
* Writes the name of the interface <code>doc</code> and collects all
* children of the node <code>doc</code>.
* @param doc an interface
* @param done the names of interfaces that should not be recorded, if
* <code>doc</code> is contained in <code>done</code>, nothing will happen.
* <code>null</code> is read as empty set.
* @param collecting a set into which each interface is written, that is
* collected by this method. That means <code>doc</code> and the whole
* subtree that has <code>doc</code> as root.
*/
private void putInterface( ClassDoc doc, Set<String> done, Set<String> collecting ){
if( done == null || !done.contains( doc.qualifiedName() )){
if( collecting != null )
collecting.add( doc.qualifiedName() );
mode( "interface", doc.name(), doc.qualifiedTypeName() );
ClassDoc[] subs = doc.interfaces();
if( subs.length > 0 ){
mode( "tree", "+" );
for( ClassDoc sub : subs )
putInterface( sub, null, collecting );
mode( "tree", "-" );
}
}
}
/**
* Gets a character identifying the type of <code>doc</code>.
* @param doc a class, interface, enum or an unknown type
* @return a letter identifying the type of <code>doc</code>
*/
private String type( ClassDoc doc ){
if( doc.isInterface() )
return "i";
if( doc.isEnum() )
return "e";
if( doc.isClass() )
return "c";
return "?";
}
public Entry toEntry() {
return new Entry( "hierarchy-class", doc.qualifiedName(), "Hierarchy of " + doc.qualifiedName(), content(),
"class:" + doc.qualifiedName() );
}
}