package jadex.tools.starter; import jadex.base.SComponentFactory; import jadex.bridge.IModelInfo; import jadex.commons.SGUI; import jadex.commons.concurrent.DefaultResultListener; import jadex.commons.concurrent.SwingDefaultResultListener; import jadex.commons.gui.CombiIcon; import jadex.tools.common.modeltree.DefaultNodeFunctionality; import jadex.tools.common.modeltree.DirNode; import jadex.tools.common.modeltree.FileNode; import jadex.tools.common.modeltree.IExplorerTreeNode; import jadex.tools.common.modeltree.ModelExplorer; import jadex.tools.common.modeltree.ModelExplorerTreeModel; import jadex.tools.common.modeltree.NodeTask; import java.util.Date; import java.util.List; import javax.swing.Icon; import javax.swing.JLabel; import javax.swing.SwingUtilities; import javax.swing.UIDefaults; /** * Model tree node functionality, specific for the starter plugin. */ public class StarterNodeFunctionality extends DefaultNodeFunctionality { //-------- constants -------- /** The valid property. */ protected static final String VALID = "valid"; /** The last check date of the valid property (Date). */ protected static final String VALID_DATE = "valid_date"; /** * The image for (m/r) elements. */ static UIDefaults icons = new UIDefaults(new Object[] { "overlay_check", SGUI.makeIcon(StarterNodeFunctionality.class, "/jadex/tools/common/images/overlay_check.png"), "checking_on", SGUI.makeIcon(StarterNodeFunctionality.class, "/jadex/tools/common/images/new_agent_check_anim.gif"), }); //-------- attributes -------- /** The starter plugin. */ protected StarterPlugin starter; /** The check indicator for the status bar. */ protected JLabel checkcomp; //-------- constructors -------- /** * Create a starter node functionality. */ public StarterNodeFunctionality(StarterPlugin starter) { super(starter.getJCC()); this.starter = starter; checkcomp = new JLabel(icons.getIcon("checking_on")); checkcomp.setToolTipText("Checking validity of componentomponent models."); } //-------- methods -------- /** * Get the icon. * @return The icon. */ public Icon getIcon(IExplorerTreeNode node) { Icon icon = super.getIcon(node); if(icon!=null && !isValid(node)) { icon = new CombiIcon(new Icon[] { icon, icons.getIcon("overlay_check") }); } return icon; } /** * Check if the valid flag of a node is set to true. */ public boolean isValid(IExplorerTreeNode node) { // System.out.println("isValid: "+node.getToolTipText()); boolean ret = true; // Unknown node types are valid by default if(node instanceof FileNode && starter.getCheckingMenu()!=null && starter.getCheckingMenu().isSelected()) { FileNode fn = (FileNode)node; Date filedate = getLastModified(fn); Date validate = (Date) fn.getProperties().get(VALID_DATE); boolean check = filedate!=null && (validate==null || validate.before(filedate)); if(!check && filedate!=null) { List children = getChildren(fn); if(children!=null) { for(int i=0; !check && i<children.size(); i++) { Date childate = (Date) ((FileNode)children.get(i)).getProperties().get(VALID_DATE); // If child not checked, check child first before continuing. if(childate==null) { startNodeTask(new CheckTask(fn)); break; } else { check = validate==null || validate.before(childate); } } } } if(check) { startNodeTask(new CheckTask(fn)); } Boolean val = (Boolean)fn.getProperties().get(VALID); ret = val==null || val.booleanValue(); // Valid, if not yet checked. } return ret; } /** * Called when the corresponding file of a node has changed. * Empty default implementation to be overridden by subclasses. */ public void nodeChanged(FileNode node) { // System.out.println("nodeChanged("+node.getToolTipText()+")"); isValid(node); } /** * Called when children of a directory node have been added or removed. * Empty default implementation to be overridden by subclasses. */ public void childrenChanged(DirNode node) { // System.out.println("childrenChanged("+node.getToolTipText()+")"); isValid(node); } //-------- helper classes -------- /** * A task to check a file. */ class CheckTask extends NodeTask { //-------- constructors -------- /** * Create a refresh task. */ public CheckTask(IExplorerTreeNode node) { super(StarterNodeFunctionality.this, node, ModelExplorer.PERCENTAGE_USER*0.9, "Checking ", checkcomp); } //-------- IExecutable interface -------- /** * Execute the task. */ public void performTask() { // System.out.println("Check: "+node.getToolTipText()); if(node instanceof FileNode) { final FileNode fn = (FileNode)node; Boolean val = (Boolean)fn.getProperties().get(VALID); final boolean oldvalid = val==null || val.booleanValue(); // final boolean newvalid = false; // Check directory. if(node instanceof DirNode) { boolean newvalid = true; List children = getChildren(fn); for(int i=0; newvalid && children!=null && i<children.size(); i++) { newvalid = isValid((IExplorerTreeNode)children.get(i)); } renew(fn, oldvalid, newvalid); } // Check file. else { final String file = fn.getFile().getAbsolutePath(); SComponentFactory.isLoadable(jcc.getServiceProvider(), file).addResultListener(new DefaultResultListener() { public void resultAvailable(Object source, Object result) { if(((Boolean)result).booleanValue()) { SComponentFactory.loadModel(jcc.getServiceProvider(), file).addResultListener(new SwingDefaultResultListener(checkcomp) { public void customResultAvailable(Object source, Object result) { boolean newvalid = false; IModelInfo model = (IModelInfo)result; if(model!=null) { newvalid = model.getReport()==null; } renew(fn, oldvalid, newvalid); } public void customExceptionOccurred(Object source, Exception exception) { renew(fn, oldvalid, false); } }); } else { renew(fn, oldvalid, false); } } }); } } } /** * * @param fn * @param oldtest * @param newtest */ protected void renew(FileNode fn, boolean oldvalid, boolean newvalid) { fn.getProperties().put(VALID, new Boolean(newvalid)); // Add always, because old value could be null. fn.getProperties().put(VALID_DATE, new Date()); if(oldvalid!=newvalid) { if(node.getParent() instanceof DirNode) childrenChanged((DirNode) node.getParent()); { SwingUtilities.invokeLater(new Runnable() { public void run() { ((ModelExplorerTreeModel)explorer.getModel()).fireNodeChanged(node); } }); } } } } }