--- /dev/null
+// ResourceTreeBrowser.java\r
+// $Id: ResourceTreeBrowser.java,v 1.1 2010/06/15 12:25:55 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1998.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigadmin.editors;\r
+\r
+import javax.swing.JTree;\r
+import javax.swing.JOptionPane;\r
+import javax.swing.KeyStroke;\r
+import javax.swing.JDialog;\r
+import javax.swing.JFrame;\r
+import javax.swing.JPopupMenu;\r
+import javax.swing.JMenuItem;\r
+import javax.swing.tree.TreePath;\r
+import javax.swing.tree.DefaultTreeCellRenderer;\r
+import javax.swing.tree.DefaultTreeModel;\r
+import javax.swing.tree.MutableTreeNode;\r
+import javax.swing.event.TreeWillExpandListener;\r
+import javax.swing.event.TreeExpansionEvent;\r
+import javax.swing.tree.ExpandVetoException;\r
+import javax.swing.tree.TreeNode;\r
+\r
+import java.awt.Cursor;\r
+import java.awt.Point;\r
+import java.awt.Component;\r
+import java.awt.GridLayout;\r
+import java.awt.Dimension;\r
+import java.awt.Container;\r
+import java.awt.event.ActionListener;\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.MouseListener;\r
+import java.awt.event.MouseAdapter;\r
+import java.awt.event.MouseEvent;\r
+import java.awt.event.KeyEvent;\r
+import java.awt.dnd.DropTarget;\r
+import java.awt.dnd.DropTargetListener;\r
+import java.awt.dnd.DropTargetDragEvent;\r
+import java.awt.dnd.DropTargetDropEvent;\r
+import java.awt.dnd.DropTargetEvent;\r
+import java.awt.dnd.DnDConstants;\r
+import java.awt.datatransfer.Transferable;\r
+import java.awt.datatransfer.DataFlavor;\r
+import java.awt.datatransfer.UnsupportedFlavorException;\r
+\r
+import java.io.IOException;\r
+\r
+import java.util.Vector;\r
+\r
+import org.w3c.jigadmin.RemoteResourceWrapper;\r
+import org.w3c.jigadmin.PropertyManager;\r
+import org.w3c.jigadmin.gui.Message;\r
+import org.w3c.jigadmin.events.ResourceActionListener;\r
+import org.w3c.jigadmin.events.ResourceActionEvent;\r
+import org.w3c.jigadmin.widgets.Icons;\r
+\r
+import org.w3c.jigsaw.admin.RemoteAccessException;\r
+import org.w3c.jigsaw.admin.RemoteResource;\r
+\r
+/**\r
+ * A JTree used to manage RemoteResource.\r
+ * @version $Revision: 1.1 $\r
+ * @author Benoît Mahé (bmahe@w3.org)\r
+ */\r
+public class ResourceTreeBrowser extends JTree \r
+ implements DropTargetListener, ResourceActionListener\r
+{\r
+\r
+ public static final String DELETE_RESOURCE_AC = "delres";\r
+\r
+ protected RemoteResourceWrapperNode rootNode = null;\r
+ protected String resIdentifier = null;\r
+ protected String resClassname = null;\r
+ protected JDialog popup = null;\r
+\r
+ private boolean isDragging = false;\r
+\r
+ /**\r
+ * Our TreeWillExpandListener\r
+ */\r
+ TreeWillExpandListener twel = new TreeWillExpandListener() {\r
+ public void treeWillExpand(TreeExpansionEvent event)\r
+ throws ExpandVetoException\r
+ {\r
+ TreeNode node = \r
+ (TreeNode)event.getPath().getLastPathComponent();\r
+ ((RemoteNode)node).nodeWillExpand();\r
+ ((DefaultTreeModel)getModel()).reload(node);\r
+ }\r
+\r
+ public synchronized void treeWillCollapse(TreeExpansionEvent event)\r
+ throws ExpandVetoException\r
+ {\r
+ TreeNode node = \r
+ (TreeNode)event.getPath().getLastPathComponent();\r
+ ((RemoteNode)node).nodeWillCollapse();\r
+ ((DefaultTreeModel)getModel()).reload(node);\r
+ }\r
+ };\r
+\r
+ /**\r
+ * Our ActionListener\r
+ */\r
+ ActionListener al = new ActionListener() {\r
+ public void actionPerformed(ActionEvent evt) {\r
+ String command = evt.getActionCommand();\r
+ if (command.equals(DELETE_RESOURCE_AC)) {\r
+ //delete the selected resource\r
+ deleteSelectedResources();\r
+ }\r
+ }\r
+ };\r
+ /**\r
+ * Our MouseListener\r
+ */\r
+ MouseAdapter mouseAdapter = new MouseAdapter() {\r
+ public void mouseClicked(MouseEvent e) {\r
+ int selRow = getRowForLocation(e.getX(), e.getY());\r
+ TreePath selPath = getPathForLocation(e.getX(), e.getY());\r
+ if(selRow != -1) {\r
+ if(e.getClickCount() == 1) {\r
+ simpleClick(selPath);\r
+ }\r
+ else if(e.getClickCount() == 2) {\r
+ doubleClick(selPath);\r
+ }\r
+ }\r
+ }\r
+\r
+ public void mousePressed(MouseEvent e) {\r
+ maybeShowPopup(e);\r
+ }\r
+ \r
+ public void mouseReleased(MouseEvent e) {\r
+ maybeShowPopup(e);\r
+ }\r
+ \r
+ private void maybeShowPopup(MouseEvent e) {\r
+ if (e.isPopupTrigger()) {\r
+ RemoteResourceWrapper rrw = getSelectedResourceWrapper();\r
+ if (rrw != null)\r
+ getPopupMenu(rrw).show(e.getComponent(), \r
+ e.getX(), e.getY());\r
+ }\r
+ }\r
+ };\r
+\r
+ //DropTargetListener\r
+\r
+ DropTarget dropTarget;\r
+\r
+ /**\r
+ * Is the mouse dragging something on the resource tree?\r
+ * @return a boolean\r
+ */\r
+ public boolean isDragging() {\r
+ return isDragging;\r
+ }\r
+\r
+ /**\r
+ * a Drag operation has encountered the DropTarget\r
+ */\r
+ public void dragEnter (DropTargetDragEvent dropTargetDragEvent) {\r
+ dropTargetDragEvent.acceptDrag(DnDConstants.ACTION_COPY);\r
+ isDragging = true;\r
+ }\r
+\r
+ /**\r
+ * The Drag operation has departed the DropTarget without dropping.\r
+ */\r
+ public void dragExit (DropTargetEvent dropTargetEvent) {\r
+ isDragging = false;\r
+ }\r
+\r
+ /**\r
+ * a Drag operation is ongoing on the DropTarget\r
+ */\r
+ public void dragOver (DropTargetDragEvent dropTargetDragEvent) {\r
+ Point location = dropTargetDragEvent.getLocation();\r
+ TreePath path = getClosestPathForLocation(location.x,\r
+ location.y);\r
+ setSelectionPath(path);\r
+ }\r
+\r
+ /**\r
+ * The user as modified the current drop gesture\r
+ */\r
+ public void dropActionChanged (DropTargetDragEvent dropTargetDragEvent) {\r
+ }\r
+\r
+ /**\r
+ * The Drag operation has terminated with a Drop on this DropTarget\r
+ */\r
+ public synchronized void drop (DropTargetDropEvent dropTargetDropEvent) {\r
+ isDragging = false;\r
+ Transferable tr = dropTargetDropEvent.getTransferable();\r
+ DataFlavor required = TransferableResourceCell.RESOURCE_CELL_FLAVOR;\r
+ try {\r
+ if (tr.isDataFlavorSupported(required)) {\r
+ dropTargetDropEvent.acceptDrop(DnDConstants.ACTION_COPY);\r
+ ResourceCell cell = (ResourceCell)tr.getTransferData(required);\r
+ dropTargetDropEvent.dropComplete(dropResource(cell));\r
+ } else {\r
+ dropTargetDropEvent.rejectDrop();\r
+ }\r
+ } catch (IOException ex) {\r
+ ex.printStackTrace();\r
+ dropTargetDropEvent.rejectDrop();\r
+ } catch (UnsupportedFlavorException ufe) {\r
+ ufe.printStackTrace();\r
+ dropTargetDropEvent.rejectDrop();\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Drop a resource.\r
+ * @param cell The resource cell\r
+ * @see org.w3c.jigadmin.editors.ResourceCell\r
+ */\r
+ protected boolean dropResource(ResourceCell cell) {\r
+ RemoteResourceWrapper rrw = getSelectedResourceWrapper();\r
+ PropertyManager pm = PropertyManager.getPropertyManager();\r
+ try {\r
+ if (! pm.isExtensible(rrw)) {\r
+ return false;\r
+ } else if ((cell.isFrame() || cell.isFilter()) && \r
+ (pm.isEditable(rrw))) {\r
+ //popupresource\r
+ popupResource(rrw);\r
+ return true;\r
+ } else if (((cell.isContainer() || cell.isResource()) && \r
+ (! rrw.getResource().isIndexersCatalog())) \r
+ ||\r
+ (rrw.getResource().isIndexersCatalog() && \r
+ cell.isIndexer())) {\r
+ //must be droppped on a Container\r
+ if (rrw.getResource().isContainer()) {\r
+ //add the resource\r
+ String identifier = getIdentifier(cell, rrw);\r
+ if (identifier != null) {\r
+ TreePath path = getSelectionPath();\r
+ addResource(identifier, cell.toString(), \r
+ rrw, path);\r
+ return true;\r
+ } \r
+ }\r
+ }\r
+ return false;\r
+ } catch (RemoteAccessException ex) {\r
+ Message.showErrorMessage(this, ex);\r
+ return false;\r
+ }\r
+ }\r
+\r
+ //End of DropTargetListener\r
+\r
+ /**\r
+ * A resource action occured.\r
+ * @param e the ResourceActionEvent\r
+ */\r
+ public void resourceActionPerformed(ResourceActionEvent e) {\r
+ int cmd = e.getResourceActionCommand();\r
+ if (isShowing()) {\r
+ if (cmd == ResourceActionEvent.DELETE_EVENT) {\r
+ deleteSelectedResources();\r
+ } else if (cmd == ResourceActionEvent.REINDEX_EVENT) {\r
+ reindexSelectedResources(false); //FIXME\r
+ } else if (cmd == ResourceActionEvent.REFERENCE_EVENT) {\r
+ showReferenceDocumentation();\r
+ } else if (cmd == ResourceActionEvent.ADD_EVENT) {\r
+ addResourceToSelectedContainer();\r
+ } else if (cmd == ResourceActionEvent.EDIT_EVENT) {\r
+ doubleClick(getSelectionPath());\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Add a resource to the resource wrapped.\r
+ * @param identifier The new resource identifier\r
+ * @param classname The new resource class name\r
+ * @param rrwf the Wrapper of the father resource\r
+ * @param fpath The path of the father node\r
+ */\r
+ protected void addResource(String identifier, String classname,\r
+ RemoteResourceWrapper rrwf, TreePath fpath) \r
+ throws RemoteAccessException\r
+ {\r
+ RemoteResource rc = \r
+ rrwf.getResource().registerResource(identifier, classname);\r
+ RemoteResourceWrapper nrrw = \r
+ new RemoteResourceWrapper(rrwf, rc);\r
+ RemoteResourceWrapperNode parent = \r
+ (RemoteResourceWrapperNode)fpath.getLastPathComponent();\r
+ RemoteResourceWrapperNode child = \r
+ new RemoteResourceWrapperNode(parent, nrrw, identifier);\r
+ ((DefaultTreeModel)getModel()).insertNodeInto(child, parent, 0);\r
+ expandPath(fpath);\r
+ }\r
+\r
+ /**\r
+ * Add a resource to the selected container.\r
+ * @param classname the resource class name\r
+ * @param identifier the resource identifier\r
+ */\r
+ protected void addResourceToSelectedContainer(String classname,\r
+ String identifier)\r
+ throws RemoteAccessException \r
+ {\r
+ RemoteResourceWrapper rrw = getSelectedResourceWrapper();\r
+ if (rrw == null)\r
+ return;\r
+ addResource(identifier, classname, rrw, getSelectionPath());\r
+ }\r
+\r
+ /**\r
+ * Get (compute) the resource identifier of the dropped resource.\r
+ * @param cell the ResourceCell dropped\r
+ * @param rrw the RemoteResourceWrapper of the father\r
+ * @return a String instance\r
+ * @see org.w3c.jigadmin.editors.ResourceCell\r
+ */\r
+ protected String getIdentifier(ResourceCell cell, \r
+ RemoteResourceWrapper rrw) \r
+ throws RemoteAccessException\r
+ {\r
+ String id = cell.toString();\r
+ id = id.substring(id.lastIndexOf('.')+1);\r
+ String names[] = rrw.getResource().enumerateResourceIdentifiers();\r
+ String identifier = id;\r
+ int cpt = 0; \r
+ int i = 0;\r
+ loop:\r
+ while (i < names.length) {\r
+ if (names[i].equals(identifier)) {\r
+ identifier = id+String.valueOf(++cpt);\r
+ i = 0;\r
+ continue loop;\r
+ }\r
+ i++;\r
+ }\r
+ return identifier;\r
+ }\r
+\r
+ /**\r
+ * Get the RemoteResourceWrapper associated to the selected node.\r
+ * @return a RemoteResourceWrapper\r
+ */\r
+ protected RemoteResourceWrapper getSelectedResourceWrapper() {\r
+ RemoteResourceWrapperNode node = \r
+ (RemoteResourceWrapperNode)getLastSelectedPathComponent();\r
+ if (node == null)\r
+ return null;\r
+ return node.getResourceWrapper();\r
+ }\r
+\r
+ /**\r
+ * Get the RemoteResourceWrapper associated to the selected node.\r
+ * @param path the selected path\r
+ * @return a RemoteResourceWrapper\r
+ */\r
+ protected RemoteResourceWrapper getSelectedResourceWrapper(TreePath path) {\r
+ if (path == null)\r
+ return null;\r
+ RemoteResourceWrapperNode node = \r
+ (RemoteResourceWrapperNode) path.getLastPathComponent();\r
+ return node.getResourceWrapper();\r
+ }\r
+\r
+ /**\r
+ * Get the Panel used to add a new resource\r
+ * @param title The title\r
+ * @param rrw The wrapper of the father RemoteResource\r
+ * @return a AddResourcePanel instance\r
+ * @see org.w3c.jigadmin.editors.AddResourcePanel\r
+ */\r
+ protected AddResourcePanel getAddResourcePanel(String title, \r
+ RemoteResourceWrapper rrw)\r
+ throws RemoteAccessException\r
+ {\r
+ return new AddResourcePanel(title, rrw, this);\r
+ }\r
+\r
+ /**\r
+ * Popup a "add resource" Dialog\r
+ * @param title the popup title\r
+ * @param rrw The wrapper of the father RemoteResource\r
+ */\r
+ protected void popupAddResourceDialog(String title, \r
+ RemoteResourceWrapper rrw) \r
+ {\r
+ try {\r
+ AddResourcePanel arp = getAddResourcePanel(title, rrw);\r
+ JFrame frame = \r
+ rootNode.\r
+ getResourceWrapper().getServerBrowser().getFrame();\r
+ popup = new JDialog(frame, title, false);\r
+ Container cont = popup.getContentPane();\r
+ cont.setLayout(new GridLayout(1,1));\r
+ cont.add(arp);\r
+ popup.setSize(new Dimension(600, 220));\r
+ popup.show();\r
+ arp.getFocus();\r
+ while(! arp.waitForCompletion());\r
+ } catch (RemoteAccessException ex) {\r
+ Message.showErrorMessage(this, ex);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Dispose the "add resource" popup\r
+ */\r
+ protected void disposeAddResourcePopup() {\r
+ if (popup != null) {\r
+ popup.dispose();\r
+ popup = null;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Specify some properties of the resource to add\r
+ * @param classnema the new resource class name\r
+ * @param identifier the new resource identifier\r
+ */\r
+ protected void setResourceToAdd(String classname, String identifier) {\r
+ this.resClassname = classname;\r
+ this.resIdentifier = identifier;\r
+ }\r
+\r
+ private void performAddResourceToSelectedContainer() {\r
+ popupAddResourceDialog("Add Resource", getSelectedResourceWrapper());\r
+ if ((resIdentifier != null) && (resClassname != null)) {\r
+ try {\r
+ addResourceToSelectedContainer(resClassname, \r
+ resIdentifier);\r
+ } catch (RemoteAccessException ex) {\r
+ Message.showErrorMessage(this, ex);\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Add a (new) resource to the container associated to the\r
+ * selected node.\r
+ */\r
+ protected void addResourceToSelectedContainer() {\r
+ RemoteResourceWrapper selected = getSelectedResourceWrapper();\r
+ PropertyManager pm = PropertyManager.getPropertyManager();\r
+ try {\r
+ if (selected == null) {\r
+ JOptionPane.showMessageDialog(this, \r
+ "No Container selected",\r
+ "Error",\r
+ JOptionPane.ERROR_MESSAGE);\r
+ return;\r
+ } else if (! pm.isExtensible(selected)) {\r
+ JOptionPane.showMessageDialog(this, \r
+ "The resource selected is not "+\r
+ "extensible.",\r
+ "Error",\r
+ JOptionPane.ERROR_MESSAGE);\r
+ }else if (selected.getResource().isContainer()) {\r
+ Thread thread = new Thread() {\r
+ public void run() {\r
+ performAddResourceToSelectedContainer();\r
+ }\r
+ };\r
+ thread.start();\r
+ } else {\r
+ JOptionPane.showMessageDialog(this, \r
+ "The resource selected is not "+\r
+ "container.",\r
+ "Error",\r
+ JOptionPane.ERROR_MESSAGE);\r
+ }\r
+ } catch (RemoteAccessException ex) {\r
+ Message.showErrorMessage(this, ex);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Filter the TreePath array. Remove all nodes that have one of their\r
+ * parent in this array.\r
+ * @param paths the TreePath array\r
+ * @return the filtered array\r
+ */\r
+ protected TreePath[] removeDescendants(TreePath[] paths) {\r
+ if (paths == null)\r
+ return null;\r
+ Vector newpaths = new Vector();\r
+ for (int i = 0 ; i < paths.length ; i++) {\r
+ TreePath currentp = paths[i];\r
+ boolean hasParent = false;\r
+ for (int j = 0 ; j < paths.length ; j++) {\r
+ if ((!(j == i)) && (paths[j].isDescendant(currentp)))\r
+ hasParent = true;\r
+ }\r
+ if (! hasParent)\r
+ newpaths.addElement(currentp);\r
+ }\r
+ TreePath[] filteredPath = new TreePath[newpaths.size()];\r
+ newpaths.copyInto(filteredPath);\r
+ return filteredPath;\r
+ }\r
+\r
+ /**\r
+ * Reindex the containers associated to the selected nodes.\r
+ * Display an error message (dialog) if there is no node selected or\r
+ * if one of the selected resource is not a ResourceContainer.\r
+ * @param rec recursivly?\r
+ */\r
+ protected void reindexSelectedResources(boolean rec) {\r
+ TreePath path[] = removeDescendants(getSelectionPaths());\r
+ if (path == null) {\r
+ JOptionPane.showMessageDialog(this, \r
+ "No Container selected",\r
+ "Error",\r
+ JOptionPane.ERROR_MESSAGE);\r
+ return;\r
+ }\r
+ if (path.length > 0) {\r
+ int result = \r
+ JOptionPane.showConfirmDialog(this, \r
+ "Reindex selected resource(s)?", \r
+ "Reindex Resource(s)", \r
+ JOptionPane.YES_NO_OPTION);\r
+ if (result == JOptionPane.YES_OPTION) {\r
+ for (int i = 0 ; i < path.length ; i++) {\r
+ RemoteResourceWrapper rrw = \r
+ getSelectedResourceWrapper(path[i]);\r
+ if (rrw == null)\r
+ continue;\r
+ try {\r
+ reindexResource(rrw, rec);\r
+ } catch (RemoteAccessException ex) {\r
+ Message.showErrorMessage(this, ex);\r
+ continue;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Reindex the container wrapped by the given wrapper.\r
+ * Display an error message (dialog) if the resource\r
+ * is not a ResourceContainer.\r
+ * @param rrw the RemoteResourceWrapper\r
+ * @param rec recursivly?\r
+ * @exception RemoteAccessException if a Remote Error occurs\r
+ */\r
+ protected void reindexResource(RemoteResourceWrapper rrw, boolean rec) \r
+ throws RemoteAccessException\r
+ {\r
+ RemoteResource rr = rrw.getResource();\r
+ if (rr.isContainer()) {\r
+ rr.reindex(rec);\r
+ } else {\r
+ JOptionPane.\r
+ showMessageDialog(this, \r
+ rr.getValue("identifier")+\r
+ " is not a container.",\r
+ "Error",\r
+ JOptionPane.ERROR_MESSAGE);\r
+ }\r
+ }\r
+ \r
+\r
+ /**\r
+ * Delete the resources associated to the selected nodes.\r
+ * Display an error message if there is no node selected or if\r
+ * the resource is not editable.\r
+ */\r
+ protected void deleteSelectedResources() {\r
+ PropertyManager pm = PropertyManager.getPropertyManager();\r
+ TreePath path[] = removeDescendants(getSelectionPaths());\r
+ if (path == null) {\r
+ JOptionPane.showMessageDialog(this, \r
+ "No Resource selected",\r
+ "Error",\r
+ JOptionPane.ERROR_MESSAGE);\r
+ return;\r
+ }\r
+ if (path.length > 0) {\r
+ int result = \r
+ JOptionPane.showConfirmDialog(this, \r
+ "Delete selected resource(s)?", \r
+ "Delete Resource(s)", \r
+ JOptionPane.YES_NO_OPTION);\r
+ if (result == JOptionPane.YES_OPTION) {\r
+ DefaultTreeModel model = (DefaultTreeModel) getModel();\r
+ for (int i = 0 ; i < path.length ; i++) {\r
+ RemoteResourceWrapper rrw = \r
+ getSelectedResourceWrapper(path[i]);\r
+ if (rrw == null)\r
+ continue;\r
+ try {\r
+ if (pm.isEditable(rrw)) {\r
+ deleteResource(rrw);\r
+ MutableTreeNode node = (MutableTreeNode) \r
+ path[i].getLastPathComponent();\r
+ model.removeNodeFromParent(node);\r
+ } else {\r
+ String name = (String)\r
+ rrw.getResource().getValue("identifier");\r
+ Message.showInformationMessage(this, name+\r
+ " is not editable");\r
+ }\r
+ } catch (RemoteAccessException ex) {\r
+ Message.showErrorMessage(this, ex);\r
+ continue;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Delete the resource wrapped by the given wrapper\r
+ * @param rrw The RemoteResourceWrapper\r
+ */\r
+ protected void deleteResource(RemoteResourceWrapper rrw) \r
+ throws RemoteAccessException\r
+ {\r
+ rrw.getResource().delete();\r
+ }\r
+\r
+ /**\r
+ * Display (in another frame) the reference documentation relative\r
+ * to the resource associated to the selected node.\r
+ * Display en error message (dialog) if no node is selected.\r
+ */\r
+ protected void showReferenceDocumentation() {\r
+ try {\r
+ RemoteResourceWrapper selected = \r
+ getSelectedResourceWrapper();\r
+ if (selected == null) {\r
+ JOptionPane.showMessageDialog(this, \r
+ "No Resource selected",\r
+ "Error",\r
+ JOptionPane.ERROR_MESSAGE);\r
+ return;\r
+ } else {\r
+ String url = (String)\r
+ selected.getResource().getValue("help-url");\r
+ MiniBrowser.showDocumentationURL(url, \r
+ "Reference documentation");\r
+ }\r
+ } catch (RemoteAccessException rae) {\r
+ Message.showErrorMessage(this, rae);\r
+ } catch (Exception ex) {\r
+\r
+ }\r
+ }\r
+\r
+ /**\r
+ * A simle click occured on the node with the given path.\r
+ * @param path The path where the click occured.\r
+ */\r
+ protected void simpleClick(TreePath path) {\r
+ }\r
+\r
+ /**\r
+ * A double click occured on the node with the given path.\r
+ * @param path The path where the double click occured.\r
+ */\r
+ protected void doubleClick(TreePath path) {\r
+ if (path == null)\r
+ return;\r
+ RemoteResourceWrapperNode node = \r
+ (RemoteResourceWrapperNode) path.getLastPathComponent();\r
+ RemoteResourceWrapper rrw = node.getResourceWrapper();\r
+ PropertyManager pm = PropertyManager.getPropertyManager();\r
+ if (pm.isEditable(rrw))\r
+ popupResource(node.getResourceWrapper());\r
+ else {\r
+ try {\r
+ String name = (String)\r
+ rrw.getResource().getValue("identifier");\r
+ Message.showInformationMessage(this, name+" is not editable");\r
+ } catch (RemoteAccessException ex) {\r
+ Message.showErrorMessage(this, ex);\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Popup a dialog where the user can edit the resource properties.\r
+ * @param rrw the wrapper if the resource to edit.\r
+ */\r
+ protected void popupResource(RemoteResourceWrapper rrw) {\r
+ rrw.getServerBrowser().popupResource(rrw);\r
+ }\r
+\r
+ /**\r
+ * Set the cursor.\r
+ * @param a cursor type\r
+ */ \r
+ protected void setCursor(int cursor) {\r
+ rootNode.getResourceWrapper().getServerBrowser().setCursor(cursor);\r
+ }\r
+\r
+ \r
+ /**\r
+ * The popup menu action listener.\r
+ */\r
+ ActionListener pmal = new ActionListener() {\r
+ public void actionPerformed(ActionEvent evt) {\r
+ setCursor(Cursor.WAIT_CURSOR);\r
+ String command = evt.getActionCommand();\r
+ if (command.equals("del")) {\r
+ deleteSelectedResources();\r
+ } else if (command.equals("add")) {\r
+ addResourceToSelectedContainer();\r
+ } else if (command.equals("reindex")) {\r
+ reindexSelectedResources(true);\r
+ } else if (command.equals("reindex-locally")) {\r
+ reindexSelectedResources(false);\r
+ } else if (command.equals("info")) {\r
+ showReferenceDocumentation();\r
+ } else if (command.equals("edit")) {\r
+ doubleClick(getSelectionPath());\r
+ }\r
+ setCursor(Cursor.DEFAULT_CURSOR);\r
+ }\r
+ };\r
+\r
+ /**\r
+ * Get the popup menu relative to the selected resource.\r
+ * @param rrw the wrapper of the resource\r
+ * @return a JPopupMenu instance\r
+ */\r
+ protected JPopupMenu getPopupMenu(RemoteResourceWrapper rrw) {\r
+\r
+ JPopupMenu popupMenu = new JPopupMenu();\r
+\r
+ boolean container = false;\r
+ boolean editable = false;\r
+\r
+ try {\r
+ PropertyManager pm = PropertyManager.getPropertyManager();\r
+ container = rrw.getResource().isContainer();\r
+ editable = pm.isEditable(rrw);\r
+ } catch (RemoteAccessException ex) {\r
+ container = false;\r
+ }\r
+\r
+ JMenuItem menuItem = null;\r
+\r
+ if (container) {\r
+ menuItem = new JMenuItem("Reindex", Icons.reindexIcon);\r
+ menuItem.addActionListener(pmal);\r
+ menuItem.setActionCommand("reindex");\r
+ popupMenu.add(menuItem);\r
+\r
+ menuItem = new JMenuItem("Reindex Locally", Icons.reindexIcon);\r
+ menuItem.addActionListener(pmal);\r
+ menuItem.setActionCommand("reindex-locally");\r
+ popupMenu.add(menuItem);\r
+ \r
+ menuItem = new JMenuItem("Add resource", Icons.addIcon);\r
+ menuItem.addActionListener(pmal);\r
+ menuItem.setActionCommand("add");\r
+ popupMenu.add(menuItem);\r
+ }\r
+\r
+ if (editable) {\r
+ menuItem = new JMenuItem("Delete resource", Icons.deleteIcon);\r
+ menuItem.addActionListener(pmal);\r
+ menuItem.setActionCommand("del");\r
+ popupMenu.add(menuItem);\r
+\r
+ menuItem = new JMenuItem("Edit resource", Icons.editIcon);\r
+ menuItem.addActionListener(pmal);\r
+ menuItem.setActionCommand("edit");\r
+ popupMenu.add(menuItem);\r
+\r
+ popupMenu.addSeparator();\r
+ }\r
+\r
+ menuItem = new JMenuItem("Info", Icons.infoIcon);\r
+ menuItem.addActionListener(pmal);\r
+ menuItem.setActionCommand("info");\r
+ popupMenu.add(menuItem);\r
+\r
+ return popupMenu;\r
+ }\r
+\r
+ /**\r
+ * Constructor\r
+ * @param root The root node\r
+ */\r
+ protected ResourceTreeBrowser(RemoteResourceWrapperNode root) {\r
+ super(root);\r
+ this.rootNode = root;\r
+ dropTarget = new DropTarget (this, this);\r
+ setEditable(true);\r
+ setLargeModel(true);\r
+ setScrollsOnExpand(true);\r
+ setUI(new ResourceTreeUI());\r
+ addTreeWillExpandListener(twel);\r
+ KeyStroke delK = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);\r
+ registerKeyboardAction(al, DELETE_RESOURCE_AC, delK, WHEN_FOCUSED);\r
+ addMouseListener(mouseAdapter);\r
+ }\r
+\r
+ /**\r
+ * Get a ResourceTreeBrowser.\r
+ * @param rrw The root resource\r
+ * @param rootName The root identifier.\r
+ * @return a ResourceTreeBrowser instance\r
+ */\r
+ public static \r
+ ResourceTreeBrowser getResourceTreeBrowser(RemoteResourceWrapper rrw,\r
+ String rootName)\r
+ {\r
+ RemoteResourceWrapperNode rnode = \r
+ new RemoteResourceWrapperNode(rrw, rootName);\r
+ ResourceTreeBrowser treebrowser = new ResourceTreeBrowser(rnode);\r
+ return treebrowser;\r
+ }\r
+}\r