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