package tutorial.support.sets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Set;
import javax.imageio.ImageIO;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import tutorial.TutorialExtension;
import tutorial.support.Tutorial;
public class TutorialTreeModel implements TreeModel{
private Node root;
private Set<TutorialExtension> extensions;
public TutorialTreeModel( Class<?> root, Set<TutorialExtension> extensions ) throws InstantiationException, IllegalAccessException{
this.extensions = extensions;
this.root = new Node( root );
}
public void addTreeModelListener( TreeModelListener l ){
// ignore
}
public void removeTreeModelListener( TreeModelListener l ){
// ignore
}
public void valueForPathChanged( TreePath path, Object newValue ){
// ignore
}
public Object getChild( Object parent, int index ){
return ((Node)parent).children[ index ];
}
public int getChildCount( Object parent ){
TutorialTreeModel.Node[] children = ((Node)parent).children;
if( children == null ){
return 0;
}
return children.length;
}
public int getIndexOfChild( Object parent, Object child ){
int index = 0;
for( Node check : ((Node)parent).children ){
if( check == child ){
return index;
}
index++;
}
return -1;
}
public Object getRoot(){
return root;
}
public boolean isLeaf( Object node ){
return ((Node)node).isLeaf();
}
public class Node{
private Class<?> clazz;
private Node[] children;
private String title;
private boolean titleSet = false;
private String description;
private boolean descriptionSet = false;
private BufferedImage image;
private boolean imageSet = false;
public Node( Class<?> clazz ) throws InstantiationException, IllegalAccessException{
this.clazz = clazz;
if( TutorialSet.class.isAssignableFrom( clazz )){
TutorialSet set = (TutorialSet) clazz.newInstance();
for( TutorialExtension extension : extensions ){
set.append( extension );
}
children = new Node[ set.getChildren().length ];
for( int i = 0; i < children.length; i++ ){
children[i] = new Node( set.getChildren()[ i ]);
}
}
}
public boolean isLeaf(){
return !TutorialSet.class.isAssignableFrom( clazz );
}
public String getTitle(){
if( !titleSet ){
titleSet = true;
Tutorial tutorial = (Tutorial)clazz.getAnnotation( Tutorial.class );
if( tutorial == null ){
title = clazz.getSimpleName();
}
else{
title = tutorial.title();
}
}
return title;
}
@Override
public String toString(){
return getTitle();
}
public Class<?> getMainClass(){
try {
if( clazz.getMethod( "main", String[].class ) != null ){
return clazz;
}
else{
return null;
}
}
catch( SecurityException e ) {
e.printStackTrace();
return null;
}
catch( NoSuchMethodException e ) {
return null;
}
}
public String getDescription(){
if( !descriptionSet ){
Tutorial tutorial = (Tutorial) clazz.getAnnotation( Tutorial.class );
String id = tutorial == null ? null : tutorial.id();
if( id != null ){
descriptionSet = true;
try{
InputStream in = clazz.getResourceAsStream( "/data/tutorial/" + id + ".html");
InputStreamReader reader = new InputStreamReader( in, "UTF-8" );
StringBuilder builder = new StringBuilder();
int next;
while( (next = reader.read()) != -1 ){
builder.append( (char)next );
}
reader.close();
description = builder.toString();
}
catch( IOException e ){
e.printStackTrace();
description = "<html><body>" + e.getMessage() + "</body></html>";
}
}
}
return description;
}
public BufferedImage getImage(){
if( !imageSet ){
imageSet = true;
Tutorial tutorial = (Tutorial) clazz.getAnnotation( Tutorial.class );
String id = tutorial == null ? null : tutorial.id();
if( id != null ){
try{
InputStream in = clazz.getResourceAsStream( "/data/tutorial/" + id + ".png" );
if( in == null ){
return null;
}
image = ImageIO.read( in );
in.close();
}
catch( IOException e ){
e.printStackTrace();
}
}
}
return image;
}
public String getCode() throws IOException{
String name = clazz.getName();
name = "/" + name.replace('.', '/') + ".java";
InputStream in = clazz.getResourceAsStream( name );
if( in == null ){
File file = new File( "src" + name );
if( file.canRead() ){
in = new FileInputStream( file );
}
}
if( in != null ){
StringBuilder builder = new StringBuilder();
InputStreamReader reader = new InputStreamReader( in, "UTF-8" );
int next;
while( (next = reader.read()) != -1 ){
if( next == '\t' ){
builder.append( " " );
}
else{
builder.append( (char)next );
}
}
reader.close();
return builder.toString();
}
return "n/a";
}
}
}