/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */
package com.cburch.logisim.tools;
import java.util.Arrays;
import java.util.List;
import javax.swing.Icon;
import com.cburch.logisim.comp.ComponentFactory;
import com.cburch.logisim.util.Icons;
import com.cburch.logisim.util.StringGetter;
/** This class allows an object to be created holding all the information
* essential to showing a ComponentFactory in the explorer window, but without
* actually loading the ComponentFactory unless a program genuinely gets around
* to needing to use it. Note that for this to work, the relevant
* ComponentFactory class must be in the same package as its Library class,
* the ComponentFactory class must be public, and it must include a public
* no-arguments constructor.
*/
public class FactoryDescription {
public static List<Tool> getTools(Class<? extends Library> base,
FactoryDescription[] descriptions) {
Tool[] tools = new Tool[descriptions.length];
for (int i = 0; i < tools.length; i++) {
tools[i] = new AddTool(base, descriptions[i]);
}
return Arrays.asList(tools);
}
private String name;
private StringGetter displayName;
private String iconName;
private boolean iconLoadAttempted;
private Icon icon;
private String factoryClassName;
private boolean factoryLoadAttempted;
private ComponentFactory factory;
private StringGetter toolTip;
public FactoryDescription(String name, StringGetter displayName,
String iconName, String factoryClassName) {
this(name, displayName, factoryClassName);
this.iconName = iconName;
this.iconLoadAttempted = false;
this.icon = null;
}
public FactoryDescription(String name, StringGetter displayName,
Icon icon, String factoryClassName) {
this(name, displayName, factoryClassName);
this.iconName = "???";
this.iconLoadAttempted = true;
this.icon = icon;
}
public FactoryDescription(String name, StringGetter displayName,
String factoryClassName) {
this.name = name;
this.displayName = displayName;
this.iconName = "???";
this.iconLoadAttempted = true;
this.icon = null;
this.factoryClassName = factoryClassName;
this.factoryLoadAttempted = false;
this.factory = null;
this.toolTip = null;
}
public String getName() {
return name;
}
public String getDisplayName() {
return displayName.get();
}
public boolean isFactoryLoaded() {
return factoryLoadAttempted;
}
public Icon getIcon() {
Icon ret = icon;
if (ret != null || iconLoadAttempted) {
return ret;
} else {
ret = Icons.getIcon(iconName);
icon = ret;
iconLoadAttempted = true;
return ret;
}
}
public ComponentFactory getFactory(Class<? extends Library> libraryClass) {
ComponentFactory ret = factory;
if (factory != null || factoryLoadAttempted) {
return ret;
} else {
String msg = "";
try {
msg = "getting class loader";
ClassLoader loader = libraryClass.getClassLoader();
msg = "getting package name";
String name;
Package pack = libraryClass.getPackage();
if (pack == null) {
name = factoryClassName;
} else {
name = pack.getName() + "." + factoryClassName;
}
msg = "loading class";
Class<?> factoryClass = loader.loadClass(name);
msg = "creating instance";
Object factoryValue = factoryClass.newInstance();
msg = "converting to factory";
if (factoryValue instanceof ComponentFactory) {
ret = (ComponentFactory) factoryValue;
factory = ret;
factoryLoadAttempted = true;
return ret;
}
} catch (Throwable t) {
String name = t.getClass().getName();
String m = t.getMessage();
if (m != null) msg = msg + ": " + name + ": " + m;
else msg = msg + ": " + name;
}
System.err.println("error while " + msg); //OK
factory = null;
factoryLoadAttempted = true;
return null;
}
}
public FactoryDescription setToolTip(StringGetter getter) {
toolTip = getter;
return this;
}
public String getToolTip() {
StringGetter getter = toolTip;
return getter == null ? null : getter.get();
}
}