OracleDatastoreViewer.java
001 /*
002  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
003  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
004  *
005  *  This file is part of GATE (see http://gate.ac.uk/), and is free
006  *  software, licenced under the GNU Library General Public License,
007  *  Version 2, June 1991 (in the distribution as file licence.html,
008  *  and also available at http://gate.ac.uk/gate/licence.html).
009  *
010  *  Kalina Bontcheva (based on code from Valentin Tablan) 31/10/2001
011  *
012  *  $Id: OracleDatastoreViewer.java 12006 2009-12-01 17:24:28Z thomas_heitz $
013  *
014  */
015 package gate.gui;
016 
017 import java.awt.event.*;
018 import java.beans.BeanInfo;
019 import java.beans.Introspector;
020 import java.text.NumberFormat;
021 import java.util.*;
022 
023 import javax.swing.*;
024 import javax.swing.tree.*;
025 
026 import gate.*;
027 import gate.creole.*;
028 import gate.creole.metadata.CreoleResource;
029 import gate.creole.metadata.GuiType;
030 import gate.event.DatastoreEvent;
031 import gate.event.DatastoreListener;
032 import gate.persist.PersistenceException;
033 import gate.util.*;
034 
035 @CreoleResource(name = "JDBC Datastore Viewer", guiType = GuiType.LARGE,
036     resourceDisplayed = "gate.persist.JDBCDataStore", mainViewer = true)
037 public class OracleDatastoreViewer extends JTree
038                                    implements VisualResource,
039                                               DatastoreListener {
040 
041   public OracleDatastoreViewer() {
042   }
043 
044 
045   public void cleanup(){
046     myHandle = null;
047   }
048 
049   /** Accessor for features. */
050   public FeatureMap getFeatures(){
051     return features;
052   }//getFeatures()
053 
054   /** Mutator for features*/
055   public void setFeatures(FeatureMap features){
056     this.features = features;
057   }// setFeatures()
058 
059   //Parameters utility methods
060   /**
061    * Gets the value of a parameter of this resource.
062    @param paramaterName the name of the parameter
063    @return the current value of the parameter
064    */
065   public Object getParameterValue(String paramaterName)
066                 throws ResourceInstantiationException{
067     return AbstractResource.getParameterValue(this, paramaterName);
068   }
069 
070   /**
071    * Sets the value for a specified parameter.
072    *
073    @param paramaterName the name for the parameteer
074    @param parameterValue the value the parameter will receive
075    */
076   public void setParameterValue(String paramaterName, Object parameterValue)
077               throws ResourceInstantiationException{
078     // get the beaninfo for the resource bean, excluding data about Object
079     BeanInfo resBeanInf = null;
080     try {
081       resBeanInf = Introspector.getBeanInfo(this.getClass(), Object.class);
082     catch(Exception e) {
083       throw new ResourceInstantiationException(
084         "Couldn't get bean info for resource " this.getClass().getName()
085         + Strings.getNl() "Introspector exception was: " + e
086       );
087     }
088     AbstractResource.setParameterValue(this, resBeanInf, paramaterName, parameterValue);
089   }
090 
091   /**
092    * Sets the values for more parameters in one step.
093    *
094    @param parameters a feature map that has paramete names as keys and
095    * parameter values as values.
096    */
097   public void setParameterValues(FeatureMap parameters)
098               throws ResourceInstantiationException{
099     AbstractResource.setParameterValues(this, parameters);
100   }
101 
102   /** Initialise this resource, and return it. */
103   public Resource init() throws ResourceInstantiationException {
104     return this;
105   }//init()
106 
107   public void clear(){
108   }
109 
110   public void setTarget(Object target){
111     if(target instanceof DataStore){
112       datastore = (DataStore)target;
113       initLocalData();
114       initGuiComponents();
115       initListeners();
116     }else{
117       throw new IllegalArgumentException(
118         "SerialDatastoreViewers can only be used with GATE serial datastores!\n" +
119         target.getClass().toString() " is not a GATE serial datastore!");
120     }
121   }
122 
123 
124   public void setHandle(Handle handle){
125     if(handle instanceof NameBearerHandle){
126       myHandle = (NameBearerHandle)handle;
127     }
128   }
129 
130   protected void fireProgressChanged(int e) {
131     myHandle.fireProgressChanged(e);
132   }//protected void fireProgressChanged(int e)
133 
134   protected void fireProcessFinished() {
135     myHandle.fireProcessFinished();
136   }//protected void fireProcessFinished()
137 
138   protected void fireStatusChanged(String e) {
139     myHandle.fireStatusChanged(e);
140   }
141 
142   protected void initLocalData(){
143   }
144 
145   protected void initGuiComponents(){
146     treeRoot = new DefaultMutableTreeNode(
147                  datastore.getName()true);
148     treeModel = new DefaultTreeModel(treeRoot, true);
149     setModel(treeModel);
150     setExpandsSelectedPaths(true);
151     expandPath(new TreePath(treeRoot));
152     try {
153       Iterator lrTypesIter = datastore.getLrTypes().iterator();
154       CreoleRegister cReg = Gate.getCreoleRegister();
155       while(lrTypesIter.hasNext()){
156         String type = (String)lrTypesIter.next();
157         ResourceData rData = (ResourceData)cReg.get(type);
158         DefaultMutableTreeNode node = new DefaultMutableTreeNode(
159                                                               rData.getName());
160         treeModel.insertNodeInto(node, treeRoot, treeRoot.getChildCount());
161         expandPath(new TreePath(new Object[]{treeRoot, node}));
162         Iterator lrIDsIter = datastore.getLrIds(type).iterator();
163         while(lrIDsIter.hasNext()){
164           Object id = (Object)lrIDsIter.next();
165           DSEntry entry = new DSEntry(datastore.getLrName(id), id, type);
166           DefaultMutableTreeNode lrNode =
167             new DefaultMutableTreeNode(entry, false);
168           treeModel.insertNodeInto(lrNode, node, node.getChildCount());
169           node.add(lrNode);
170         }
171       }
172     catch(PersistenceException pe) {
173       throw new GateRuntimeException(pe.toString());
174     }
175 
176     DefaultTreeSelectionModel selectionModel = new DefaultTreeSelectionModel();
177     selectionModel.setSelectionMode(
178         DefaultTreeSelectionModel.SINGLE_TREE_SELECTION);
179     setSelectionModel(selectionModel);
180 
181   }//protected void initGuiComponents()
182 
183   protected void initListeners(){
184     datastore.addDatastoreListener(this);
185     addMouseListener(new MouseAdapter() {
186       public void mouseClicked(MouseEvent e) {
187         //where inside the tree?
188         TreePath path = getPathForLocation(e.getX(), e.getY());
189         Object value = null;
190         if(path != nullvalue = ((DefaultMutableTreeNode)
191                                   path.getLastPathComponent()).getUserObject();
192 
193         if(SwingUtilities.isRightMouseButton(e)){
194           //right click
195           if(value != null && value instanceof DSEntry){
196             JPopupMenu popup = ((DSEntry)value).getPopup();
197             popup.show(OracleDatastoreViewer.this, e.getX(), e.getY());
198           }
199         }else if(SwingUtilities.isLeftMouseButton(e&&
200                  e.getClickCount() == 2){
201           //double click -> just load the resource
202           if(value != null && value instanceof DSEntry){
203             new LoadAction((DSEntry)value).actionPerformed(null);
204           }
205         }
206       }//public void mouseClicked(MouseEvent e)
207     });
208   }//protected void initListeners()
209 
210 
211   class LoadAction extends AbstractAction {
212     LoadAction(DSEntry entry){
213       super("Load");
214       this.entry = entry;
215     }
216 
217     public void actionPerformed(ActionEvent e){
218       Runnable runnable = new Runnable(){
219         public void run(){
220           try{
221             MainFrame.lockGUI("Loading " + entry.name);
222             long start = System.currentTimeMillis();
223             fireStatusChanged("Loading " + entry.name);
224             fireProgressChanged(0);
225             FeatureMap params = Factory.newFeatureMap();
226             params.put(DataStore.DATASTORE_FEATURE_NAME, datastore);
227             params.put(DataStore.LR_ID_FEATURE_NAME, entry.id);
228             FeatureMap features = Factory.newFeatureMap();
229             Resource res = Factory.createResource(entry.type, params, features,
230                                                   entry.name);
231             //project.frame.resourcesTreeModel.treeChanged();
232             fireProgressChanged(0);
233             fireProcessFinished();
234             long end = System.currentTimeMillis();
235             fireStatusChanged(entry.name + " loaded in " +
236                               NumberFormat.getInstance().format(
237                               (double)(end - start1000" seconds");
238           catch(ResourceInstantiationException rie){
239             MainFrame.unlockGUI();
240             JOptionPane.showMessageDialog(OracleDatastoreViewer.this,
241                                           "Error!\n" + rie.toString(),
242                                           "GATE", JOptionPane.ERROR_MESSAGE);
243             rie.printStackTrace(Err.getPrintWriter());
244             fireProgressChanged(0);
245             fireProcessFinished();
246           }finally{
247             MainFrame.unlockGUI();
248           }
249         }
250       };//runnable
251       Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
252                                  runnable,
253                                  "Loader from DS");
254       thread.setPriority(Thread.MIN_PRIORITY);
255       thread.start();
256     }// public void actionPerformed(ActionEvent e)
257     DSEntry entry;
258   }//class LoadAction extends AbstractAction
259 
260   class DeleteAction extends AbstractAction {
261     DeleteAction(DSEntry entry){
262       super("Delete");
263       this.entry = entry;
264     }
265 
266     public void actionPerformed(ActionEvent e){
267       try{
268         datastore.delete(entry.type, entry.id);
269         //project.frame.resourcesTreeModel.treeChanged();
270       }catch(gate.persist.PersistenceException pe){
271         JOptionPane.showMessageDialog(OracleDatastoreViewer.this,
272                                       "Error!\n" + pe.toString(),
273                                       "GATE", JOptionPane.ERROR_MESSAGE);
274         pe.printStackTrace(Err.getPrintWriter());
275       }catch(gate.security.SecurityException se){
276         JOptionPane.showMessageDialog(OracleDatastoreViewer.this,
277                                       "Error!\n" + se.toString(),
278                                       "GATE", JOptionPane.ERROR_MESSAGE);
279         se.printStackTrace(Err.getPrintWriter());
280       }
281     }// public void actionPerformed(ActionEvent e)
282     DSEntry entry;
283   }// class DeleteAction
284 
285 
286   class DSEntry {
287     DSEntry(String name, Object id, String type){
288       this.name = name;
289       this.type = type;
290       this.id = id;
291       popup = new JPopupMenu();
292       popup.add(new LoadAction(this));
293       popup.add(new DeleteAction(this));
294     }// DSEntry
295 
296     public String toString(){
297       return name;
298     }
299 
300     public JPopupMenu getPopup(){
301       return popup;
302     }
303 
304     String name;
305     String type;
306     Object id;
307     JPopupMenu popup;
308   }// class DSEntry
309 
310   DefaultMutableTreeNode treeRoot;
311   DefaultTreeModel treeModel;
312   DataStore datastore;
313   NameBearerHandle myHandle;
314   protected FeatureMap features;
315 
316   private transient Vector progressListeners;
317   private transient Vector statusListeners;
318   public void resourceAdopted(DatastoreEvent e) {
319     //do nothing; SerialDataStore does actually nothing on adopt()
320     //we'll have to listen for RESOURE_WROTE events
321   }
322 
323   public void resourceDeleted(DatastoreEvent e) {
324     Object resID = e.getResourceID();
325     DefaultMutableTreeNode node = null;
326     Enumeration nodesEnum = treeRoot.depthFirstEnumeration();
327     boolean found = false;
328     while(nodesEnum.hasMoreElements() && !found){
329       node = (DefaultMutableTreeNode)nodesEnum.nextElement();
330       Object userObject = node.getUserObject();
331       found = userObject instanceof DSEntry &&
332               ((DSEntry)userObject).id.equals(resID);
333     }
334     if(found){
335       DefaultMutableTreeNode parent = (DefaultMutableTreeNode)node.getParent();
336       treeModel.removeNodeFromParent(node);
337       if(parent.getChildCount() == 0treeModel.removeNodeFromParent(parent);
338     }
339   }
340 
341   public void resourceWritten(DatastoreEvent e) {
342     Resource res = e.getResource();
343     Object resID = e.getResourceID();
344     String resType = ((ResourceData)Gate.getCreoleRegister().
345                       get(res.getClass().getName())).getName();
346     DefaultMutableTreeNode parent = treeRoot;
347     DefaultMutableTreeNode node = null;
348     //first look for the type node
349     Enumeration childrenEnum = parent.children();
350     boolean found = false;
351     while(childrenEnum.hasMoreElements() && !found){
352       node = (DefaultMutableTreeNode)childrenEnum.nextElement();
353       found = node.getUserObject().equals(resType);
354     }
355     if(!found){
356       //exhausted the children without finding the node -> new type
357       node = new DefaultMutableTreeNode(resType);
358       treeModel.insertNodeInto(node, parent, parent.getChildCount());
359     }
360     expandPath(new TreePath(new Object[]{parent, node}));
361 
362     //now look for the resource node
363     parent = node;
364     childrenEnum = parent.children();
365     found = false;
366     while(childrenEnum.hasMoreElements() && !found){
367       node = (DefaultMutableTreeNode)childrenEnum.nextElement();
368       found = ((DSEntry)node.getUserObject()).id.equals(resID);
369     }
370     if(!found){
371       //exhausted the children without finding the node -> new resource
372       try{
373         DSEntry entry = new DSEntry(datastore.getLrName(resID), resID,
374                                     res.getClass().getName());
375         node = new DefaultMutableTreeNode(entry, false);
376         treeModel.insertNodeInto(node, parent, parent.getChildCount());
377       }catch(PersistenceException pe){
378         pe.printStackTrace(Err.getPrintWriter());
379       }
380     }
381   }//public void resourceWritten(DatastoreEvent e)
382 
383 }//public class DSHandle