1   /*
2    *  Copyright (c) 1998-2001, The University of Sheffield.
3    *
4    *  This file is part of GATE (see http://gate.ac.uk/), and is free
5    *  software, licenced under the GNU Library General Public License,
6    *  Version 2, June 1991 (in the distribution as file licence.html,
7    *  and also available at http://gate.ac.uk/gate/licence.html).
8    *
9    *  Kalina Bontcheva (based on code from Valentin Tablan) 31/10/2001
10   *
11   *  $Id: OracleDatastoreViewer.java,v 1.5 2001/11/13 17:12:49 marin Exp $
12   *
13   */
14  package gate.gui;
15  
16  import gate.*;
17  import gate.creole.*;
18  import gate.util.*;
19  import gate.persist.*;
20  
21  import javax.swing.*;
22  import java.awt.event.*;
23  import javax.swing.tree.*;
24  
25  import java.util.*;
26  import java.text.NumberFormat;
27  
28  import gate.event.*;
29  import java.beans.*;
30  
31  public class OracleDatastoreViewer extends JTree
32                                     implements VisualResource,
33                                                DatastoreListener {
34  
35    public OracleDatastoreViewer() {
36    }
37  
38  
39    public void cleanup(){
40    }
41  
42    /** Accessor for features. */
43    public FeatureMap getFeatures(){
44      return features;
45    }//getFeatures()
46  
47    /** Mutator for features*/
48    public void setFeatures(FeatureMap features){
49      this.features = features;
50    }// setFeatures()
51  
52    //Parameters utility methods
53    /**
54     * Gets the value of a parameter of this resource.
55     * @param paramaterName the name of the parameter
56     * @return the current value of the parameter
57     */
58    public Object getParameterValue(String paramaterName)
59                  throws ResourceInstantiationException{
60      return AbstractResource.getParameterValue(this, paramaterName);
61    }
62  
63    /**
64     * Sets the value for a specified parameter.
65     *
66     * @param paramaterName the name for the parameteer
67     * @param parameterValue the value the parameter will receive
68     */
69    public void setParameterValue(String paramaterName, Object parameterValue)
70                throws ResourceInstantiationException{
71      // get the beaninfo for the resource bean, excluding data about Object
72      BeanInfo resBeanInf = null;
73      try {
74        resBeanInf = Introspector.getBeanInfo(this.getClass(), Object.class);
75      } catch(Exception e) {
76        throw new ResourceInstantiationException(
77          "Couldn't get bean info for resource " + this.getClass().getName()
78          + Strings.getNl() + "Introspector exception was: " + e
79        );
80      }
81      AbstractResource.setParameterValue(this, resBeanInf, paramaterName, parameterValue);
82    }
83  
84    /**
85     * Sets the values for more parameters in one step.
86     *
87     * @param parameters a feature map that has paramete names as keys and
88     * parameter values as values.
89     */
90    public void setParameterValues(FeatureMap parameters)
91                throws ResourceInstantiationException{
92      AbstractResource.setParameterValues(this, parameters);
93    }
94  
95    /** Initialise this resource, and return it. */
96    public Resource init() throws ResourceInstantiationException {
97      return this;
98    }//init()
99  
100   public void clear(){
101   }
102 
103   public void setTarget(Object target){
104     if(target instanceof DataStore){
105       datastore = (DataStore)target;
106       initLocalData();
107       initGuiComponents();
108       initListeners();
109     }else{
110       throw new IllegalArgumentException(
111         "SerialDatastoreViewers can only be used with GATE serial datastores!\n" +
112         target.getClass().toString() + " is not a GATE serial datastore!");
113     }
114   }
115 
116 
117   public void setHandle(Handle handle){
118     if(handle instanceof NameBearerHandle){
119       myHandle = (NameBearerHandle)handle;
120     }
121   }
122 
123   protected void fireProgressChanged(int e) {
124     myHandle.fireProgressChanged(e);
125   }//protected void fireProgressChanged(int e)
126 
127   protected void fireProcessFinished() {
128     myHandle.fireProcessFinished();
129   }//protected void fireProcessFinished()
130 
131   protected void fireStatusChanged(String e) {
132     myHandle.fireStatusChanged(e);
133   }
134 
135   protected void initLocalData(){
136   }
137 
138   protected void initGuiComponents(){
139     treeRoot = new DefaultMutableTreeNode(
140                  datastore.getName(), true);
141     treeModel = new DefaultTreeModel(treeRoot, true);
142     setModel(treeModel);
143     setExpandsSelectedPaths(true);
144     expandPath(new TreePath(treeRoot));
145     try {
146       Iterator lrTypesIter = datastore.getLrTypes().iterator();
147       CreoleRegister cReg = Gate.getCreoleRegister();
148       while(lrTypesIter.hasNext()){
149         String type = (String)lrTypesIter.next();
150         ResourceData rData = (ResourceData)cReg.get(type);
151         DefaultMutableTreeNode node = new DefaultMutableTreeNode(
152                                                               rData.getName());
153         treeModel.insertNodeInto(node, treeRoot, treeRoot.getChildCount());
154         expandPath(new TreePath(new Object[]{treeRoot, node}));
155         Iterator lrIDsIter = datastore.getLrIds(type).iterator();
156         while(lrIDsIter.hasNext()){
157           Object id = (Object)lrIDsIter.next();
158           DSEntry entry = new DSEntry(datastore.getLrName(id), id, type);
159           DefaultMutableTreeNode lrNode =
160             new DefaultMutableTreeNode(entry, false);
161           treeModel.insertNodeInto(lrNode, node, node.getChildCount());
162           node.add(lrNode);
163         }
164       }
165     } catch(PersistenceException pe) {
166       throw new GateRuntimeException(pe.toString());
167     }
168 
169   }//protected void initGuiComponents()
170 
171   protected void initListeners(){
172     datastore.addDatastoreListener(this);
173     addMouseListener(new MouseAdapter() {
174       public void mouseClicked(MouseEvent e) {
175         //where inside the tree?
176         TreePath path = getPathForLocation(e.getX(), e.getY());
177         Object value = null;
178         if(path != null) value = ((DefaultMutableTreeNode)
179                                   path.getLastPathComponent()).getUserObject();
180 
181         if(SwingUtilities.isRightMouseButton(e)){
182           //right click
183           if(value != null && value instanceof DSEntry){
184             JPopupMenu popup = ((DSEntry)value).getPopup();
185             popup.show(OracleDatastoreViewer.this, e.getX(), e.getY());
186           }
187         }else if(SwingUtilities.isLeftMouseButton(e) &&
188                  e.getClickCount() == 2){
189           //double click -> just load the resource
190           if(value != null && value instanceof DSEntry){
191             new LoadAction((DSEntry)value).actionPerformed(null);
192           }
193         }
194       }//public void mouseClicked(MouseEvent e)
195     });
196   }//protected void initListeners()
197 
198 
199   class LoadAction extends AbstractAction {
200     LoadAction(DSEntry entry){
201       super("Load");
202       this.entry = entry;
203     }
204 
205     public void actionPerformed(ActionEvent e){
206       Runnable runnable = new Runnable(){
207         public void run(){
208           try{
209             long start = System.currentTimeMillis();
210             fireStatusChanged("Loading " + entry.name);
211             fireProgressChanged(0);
212             FeatureMap params = Factory.newFeatureMap();
213             params.put(DataStore.DATASTORE_FEATURE_NAME, datastore);
214             params.put(DataStore.LR_ID_FEATURE_NAME, entry.id);
215             FeatureMap features = Factory.newFeatureMap();
216             Resource res = Factory.createResource(entry.type, params, features,
217                                                   entry.name);
218             //project.frame.resourcesTreeModel.treeChanged();
219             fireProgressChanged(0);
220             fireProcessFinished();
221             long end = System.currentTimeMillis();
222             fireStatusChanged(entry.name + " loaded in " +
223                               NumberFormat.getInstance().format(
224                               (double)(end - start) / 1000) + " seconds");
225           } catch(ResourceInstantiationException rie){
226             JOptionPane.showMessageDialog(OracleDatastoreViewer.this,
227                                           "Error!\n" + rie.toString(),
228                                           "Gate", JOptionPane.ERROR_MESSAGE);
229             rie.printStackTrace(Err.getPrintWriter());
230             fireProgressChanged(0);
231             fireProcessFinished();
232           }
233         }
234       };//runnable
235       Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
236                                  runnable,
237                                  "Loader from DS");
238       thread.setPriority(Thread.MIN_PRIORITY);
239       thread.start();
240     }// public void actionPerformed(ActionEvent e)
241     DSEntry entry;
242   }//class LoadAction extends AbstractAction
243 
244   class DeleteAction extends AbstractAction {
245     DeleteAction(DSEntry entry){
246       super("Delete");
247       this.entry = entry;
248     }
249 
250     public void actionPerformed(ActionEvent e){
251       try{
252         datastore.delete(entry.type, entry.id);
253         //project.frame.resourcesTreeModel.treeChanged();
254       }catch(gate.persist.PersistenceException pe){
255         JOptionPane.showMessageDialog(OracleDatastoreViewer.this,
256                                       "Error!\n" + pe.toString(),
257                                       "Gate", JOptionPane.ERROR_MESSAGE);
258         pe.printStackTrace(Err.getPrintWriter());
259       }catch(gate.security.SecurityException se){
260         JOptionPane.showMessageDialog(OracleDatastoreViewer.this,
261                                       "Error!\n" + se.toString(),
262                                       "Gate", JOptionPane.ERROR_MESSAGE);
263         se.printStackTrace(Err.getPrintWriter());
264       }
265     }// public void actionPerformed(ActionEvent e)
266     DSEntry entry;
267   }// class DeleteAction
268 
269 
270   class DSEntry {
271     DSEntry(String name, Object id, String type){
272       this.name = name;
273       this.type = type;
274       this.id = id;
275       popup = new JPopupMenu();
276       popup.add(new LoadAction(this));
277       popup.add(new DeleteAction(this));
278     }// DSEntry
279 
280     public String toString(){
281       return name;
282     }
283 
284     public JPopupMenu getPopup(){
285       return popup;
286     }
287 
288     String name;
289     String type;
290     Object id;
291     JPopupMenu popup;
292   }// class DSEntry
293 
294   DefaultMutableTreeNode treeRoot;
295   DefaultTreeModel treeModel;
296   DataStore datastore;
297   NameBearerHandle myHandle;
298   protected FeatureMap features;
299 
300   private transient Vector progressListeners;
301   private transient Vector statusListeners;
302   public void resourceAdopted(DatastoreEvent e) {
303     //do nothing; SerialDataStore does actually nothing on adopt()
304     //we'll have to listen for RESOURE_WROTE events
305   }
306 
307   public void resourceDeleted(DatastoreEvent e) {
308     Object resID = e.getResourceID();
309     DefaultMutableTreeNode node = null;
310     Enumeration nodesEnum = treeRoot.depthFirstEnumeration();
311     boolean found = false;
312     while(nodesEnum.hasMoreElements() && !found){
313       node = (DefaultMutableTreeNode)nodesEnum.nextElement();
314       Object userObject = node.getUserObject();
315       found = userObject instanceof DSEntry &&
316               ((DSEntry)userObject).id.equals(resID);
317     }
318     if(found){
319       DefaultMutableTreeNode parent = (DefaultMutableTreeNode)node.getParent();
320       treeModel.removeNodeFromParent(node);
321       if(parent.getChildCount() == 0) treeModel.removeNodeFromParent(parent);
322     }
323   }
324 
325   public void resourceWritten(DatastoreEvent e) {
326     Resource res = e.getResource();
327     Object resID = e.getResourceID();
328     String resType = ((ResourceData)Gate.getCreoleRegister().
329                       get(res.getClass().getName())).getName();
330     DefaultMutableTreeNode parent = treeRoot;
331     DefaultMutableTreeNode node = null;
332     //first look for the type node
333     Enumeration childrenEnum = parent.children();
334     boolean found = false;
335     while(childrenEnum.hasMoreElements() && !found){
336       node = (DefaultMutableTreeNode)childrenEnum.nextElement();
337       found = node.getUserObject().equals(resType);
338     }
339     if(!found){
340       //exhausted the children without finding the node -> new type
341       node = new DefaultMutableTreeNode(resType);
342       treeModel.insertNodeInto(node, parent, parent.getChildCount());
343     }
344     expandPath(new TreePath(new Object[]{parent, node}));
345 
346     //now look for the resource node
347     parent = node;
348     childrenEnum = parent.children();
349     found = false;
350     while(childrenEnum.hasMoreElements() && !found){
351       node = (DefaultMutableTreeNode)childrenEnum.nextElement();
352       found = ((DSEntry)node.getUserObject()).id.equals(resID);
353     }
354     if(!found){
355       //exhausted the children without finding the node -> new resource
356       try{
357         DSEntry entry = new DSEntry(datastore.getLrName(resID), resID,
358                                     res.getClass().getName());
359         node = new DefaultMutableTreeNode(entry, false);
360         treeModel.insertNodeInto(node, parent, parent.getChildCount());
361       }catch(PersistenceException pe){
362         pe.printStackTrace(Err.getPrintWriter());
363       }
364     }
365   }//public void resourceWritten(DatastoreEvent e)
366 
367 }//public class DSHandle