test clientsFile handlers.
[vamsas.git] / src / org / vamsas / client / SimpleClient.java
1 /*
2  * Created on 15-Sep-2005
3  *
4  * TODO To change the template for this generated file go to
5  * Window - Preferences - Java - Code Style - Code Templates
6  */
7 package org.vamsas.client;
8
9 import java.beans.EventHandler;
10 import java.beans.PropertyChangeEvent;
11 import java.beans.PropertyChangeListener;
12 import java.beans.PropertyChangeSupport;
13 import java.io.BufferedReader;
14 import java.io.File;
15 import java.io.IOException;
16 import java.io.Reader;
17 import java.io.Writer;
18 import java.lang.reflect.Field;
19 import java.util.Hashtable;
20 import java.util.Vector;
21
22 import org.exolab.castor.xml.IDResolver;
23 import org.exolab.castor.xml.MarshalException;
24 import org.exolab.castor.xml.Marshaller;
25 import org.exolab.castor.xml.UnmarshalListener;
26 import org.exolab.castor.xml.Unmarshaller;
27 import org.exolab.castor.xml.ValidationException;
28 import org.vamsas.objects.core.VamsasDocument;
29
30 /**
31  * @author jimp
32  */
33 public class SimpleClient implements IClient {
34
35   UserHandle user = null;
36
37   SessionHandle session = null;
38
39   ClientHandle client = null;
40   
41   /*
42    * (non-Javadoc)
43    * TODO: check that build substitution variables are correct
44    * @see org.vamsas.client.IClient#getAbout()
45    */
46   public String getAbout() {
47     return new String("VORBA SimpleClient version $version$ build $build$");
48   }
49
50   /*
51    * (non-Javadoc)
52    * 
53    * @see org.vamsas.client.IClient#getSessionUrn()
54    */
55   public String getSessionUrn() {
56     return session.getSessionUrn();
57   }
58
59   /*
60    * (non-Javadoc)
61    * 
62    * @see org.vamsas.client.IClient#getSessionHandle()
63    */
64   public SessionHandle getSessionHandle() {
65     return session;
66   }
67
68   /*
69    * (non-Javadoc)
70    * 
71    * @see org.vamsas.client.IClient#getClientHandle()
72    */
73   public ClientHandle getClientHandle() {
74     return client;
75   }
76
77   /*
78    * (non-Javadoc)
79    * 
80    * @see org.vamsas.client.IClient#getUserHandle()
81    */
82   public UserHandle getUserHandle() {
83     return user;
84   }
85
86   private Hashtable handlers = initHandlers();
87
88   private Vector listeners = new Vector();
89
90   /**
91    * make all the PropertyChangeSupport objects for the
92    * events described in org.vamsas.client.Event
93    * @return
94    */
95   private static Hashtable initHandlers() {
96     Hashtable events = new Hashtable();
97     java.util.Iterator evt = Events.EventList.iterator();
98     while (evt.hasNext()) {
99       Object ths = evt.next();
100       events.put(ths, (Object) new PropertyChangeSupport(ths));
101     }
102     return events;
103   }
104
105   /*
106    * (non-Javadoc)
107    * 
108    * @see org.vamsas.client.IClient#addDocumentUpdateHandler(java.util.EventListener)
109    */
110   public void addDocumentUpdateHandler(PropertyChangeListener evt) {
111     if (handlers.containsKey(Events.DOCUMENT_UPDATE)) {
112       Object handler;
113       ((PropertyChangeSupport) (handler = handlers.get(Events.DOCUMENT_UPDATE)))
114           .addPropertyChangeListener(evt);
115       listeners.add(handler);
116       listeners.add((Object) evt);
117     }
118   }
119
120   /*
121    * (non-Javadoc)
122    * 
123    * @see org.vamsas.client.IClient#finalizeClient()
124    */
125   public void finalizeClient() {
126     // TODO: determine if this is last client in session
127     // TODO: raise events like : ((lst_client && document.request.to.close), (client_finalization), (
128     
129     // if (handlers.containsKey(Events.))
130     // if (handlers.containsKey(Events.CLIENT_FINALIZATION))
131     // deregister listeners.
132     // mark this instance as finalized
133   }
134
135   /**
136    * writes the VamsasDocument to the given stream.
137    * TODO: ensure that (at least) default provenance entries are written for objects.
138    * @param outstream
139    * @param doc
140    * @throws IOException
141    * @throws MarshalException
142    * @throws ValidationException
143    */
144   private static void setVamsasDocument(Writer outstream, VamsasDocument doc)
145       throws IOException, MarshalException, ValidationException {
146     Marshaller marshaller = new Marshaller(outstream);
147     marshaller.marshal(doc);
148   }
149
150   /**
151    * Unmarshals a vamsasDocument object from a stream, registers
152    * unregistered objects, records existing VorbaIds, and completes 
153    * the org.vamsas.client.object housekeeping fields.
154    * For a valid unmarshalling, the array of returned objects also includes
155    * a <return>sync</return> parameter which is true if new VorbaIds
156    * were created. If sync is false, then the caller should ensure that the
157    * vamsasDocument is written back to disk to propagate the new VorbaIds.
158    *  TODO: ensure that provenance is correct for newly registered objects
159    * @param instream - the XML input stream 
160    * @param factory - the SimpleClient's properly configured VorbaId factory to make new references.
161    * @return null or {(Object) VamsasDocument object, (Object) Hashtable of object references, (Object) Boolean(sync) }
162    */
163 private static Object[] getVamsasDocument(Reader instream,
164       IVorbaIdFactory factory) {
165     Unmarshaller unmarshaller = new Unmarshaller(instream);
166     unmarshaller.setIDResolver(new IDResolver() {
167       public Object resolve(String id) {
168         System.err.println("Warning - id " + id
169             + " is not found in the VamsasDocument!");
170         return null;
171       }
172     });
173     Hashtable refbase = new Hashtable();
174     Vector unrefed = new Vector();
175     final Hashtable objrefs = refbase;
176     final IVorbaIdFactory vorbafactory = factory;
177     final Vector unrefedObj =  unrefed;
178     unmarshaller.setUnmarshalListener(new UnmarshalListener() {
179
180       /*
181        * (non-Javadoc)
182        * 
183        * @see org.exolab.castor.xml.UnmarshalListener#attributesProcessed(java.lang.Object)
184        */
185       public void attributesProcessed(Object object) {
186       }
187
188       /*
189        * (non-Javadoc)
190        * 
191        * @see org.exolab.castor.xml.UnmarshalListener#fieldAdded(java.lang.String,
192        *      java.lang.Object, java.lang.Object)
193        */
194       public void fieldAdded(String fieldName, Object parent, Object child) {
195       }
196
197       /*
198        * (non-Javadoc)
199        * 
200        * @see org.exolab.castor.xml.UnmarshalListener#initialized(java.lang.Object)
201        */
202       public void initialized(Object object) {
203       }
204
205       /*
206        * Check if the object has an 'id' field - if it does, copy the value into
207        * the VorbaId field of object, and add the object to the VorbaId hash.
208        * 
209        * @see org.exolab.castor.xml.UnmarshalListener#unmarshalled(java.lang.Object)
210        */
211       public void unmarshalled(Object newobj) {
212         if (newobj instanceof object) {
213           object nobj = (object) newobj;
214           nobj.set__stored_in_document(true);
215           Field fd = null;
216           try {
217             if (nobj.isRegisterable()) {
218               // look for the id field (should be an NCName string)
219               nobj.__vorba = vorbafactory;
220               fd = nobj.getClass().getField("id");
221               String idstring;
222               if (fd.get(nobj) != null) {
223                 idstring = (String) fd.get(nobj);
224                 if (idstring.length() > 0) {
225                   if (!objrefs.containsKey(idstring)) {
226                     objrefs.put(idstring, nobj);
227                     nobj.setVorbaId(VorbaId.newId(idstring));
228                   } else {
229                     System.err.println("Serious problem : duplicate id '"+idstring+"' found! expect badness.");
230                     // TODO: HANDLE duplicate XML ids correctly
231                   }
232                 } else {
233                   // add to list of objects without a valid vorbaId
234                   unrefedObj.add(nobj);
235                 }
236               } else {
237                 // add to list of objects without a valid vorbaId
238                 unrefedObj.add(nobj);
239               }
240               
241             nobj.doHash();
242           }
243           } catch (Exception e) {
244             return;
245           };
246           
247         }
248       }
249
250     });
251     // Call the unmarshaller.
252     try {
253       while (instream.ready()) {
254         Object obj = unmarshaller.unmarshal(instream);
255         boolean sync=true;
256         if (obj instanceof VamsasDocument) {
257           if (unrefed.size()>0) {
258             sync=false; // document is out of sync - ids have been created.
259             java.util.Iterator newobj = unrefed.listIterator();
260             while (newobj.hasNext()) {
261               object o = (object) newobj.next();
262               // forces registration and id field update.
263               VorbaId id = o.getVorbaId();
264               if (!objrefs.containsKey(id)) {
265                 objrefs.put(id.id, o);
266               } else {
267                 throw new Error("Serious! Duplicate reference made by vorbaIdFactory!");
268               }
269             }
270           }
271           return new Object[] { obj, objrefs, new Boolean(sync)};
272         }
273       }
274     } catch (MarshalException e) {
275       // TODO Auto-generated catch block
276       e.printStackTrace();
277     } catch (ValidationException e) {
278       // TODO Auto-generated catch block
279       e.printStackTrace();
280     } catch (IOException e) {
281       // TODO Auto-generated catch block
282       e.printStackTrace();
283     }
284     return null;
285   }
286   /**
287    * extract data appropriate for client, session and user
288    * from vamsas document.
289    * @return application's byte array
290    */
291   private byte[] getApplicationData() {
292     // TODO: extract correct byte object from Jar and return it to application.
293     return null;
294   }
295
296   /*
297    * (non-Javadoc)
298    * 
299    * @see org.vamsas.client.IClient#getClientDocument()
300    */
301   public IClientDocument getClientDocument() {
302     Object[] vdoc;//  TODO: = getVamsasDocument(new Reader());
303     // ClientDocument cdoc = new ClientDocument(getApplicationData(),
304         // ((VamsasDocument) vdoc[0]).getVAMSAS(), (Hashtable) vdoc[1], this);
305     // 
306     return null;
307   }
308
309   /*
310    * (non-Javadoc)
311    * 
312    * @see org.vamsas.client.IClient#updateDocument(org.vamsas.client.IClientDocument)
313    */
314   public void updateDocument(IClientDocument newdoc) {
315     // TODO Auto-generated method stub
316     // 
317   }
318
319   /*
320    * (non-Javadoc)
321    * 
322    * @see org.vamsas.client.IClient#storeDocument(java.io.File)
323    */
324   public void storeDocument(File location) {
325     // TODO Auto-generated method stub
326
327   }
328
329   /*
330    * (non-Javadoc)
331    * 
332    * @see org.vamsas.client.IClient#addVorbaEventHandler(java.lang.String,
333    *      java.beans.PropertyChangeListener)
334    */
335   public void addVorbaEventHandler(String EventChain, PropertyChangeListener evt) {
336     if (handlers.containsKey(EventChain)) {
337       Object handler;
338       ((PropertyChangeSupport) (handler = handlers.get(EventChain)))
339           .addPropertyChangeListener(evt);
340       listeners.add(handler);
341       listeners.add((Object) evt);
342     }
343   }
344
345   /* (non-Javadoc)
346    * @see org.vamsas.client.IClient#pollUpdate()
347    */
348   public void pollUpdate() {
349     // TODO wake up UpdateWatcher thread to check for updates.
350
351   }
352
353   public static void main(String[] args) {
354   }
355
356   /* (non-Javadoc)
357    * @see org.vamsas.client.IClient#joinSession()
358    */
359   public void joinSession() throws Exception {
360     // TODO Auto-generated method stub
361     
362   }
363 }