d5b0d4207191a4768563ef0d8287c7a355fbd091
[vamsas.git] / src / org / vamsas / test / simpleclient / ClientDoc.java
1 package org.vamsas.test.simpleclient;
2
3 import java.util.Vector;
4
5 import org.apache.commons.logging.Log;
6 import org.apache.commons.logging.LogFactory;
7 import org.vamsas.client.VorbaId;
8 import org.vamsas.client.simpleclient.ClientDocument;
9 import org.vamsas.client.simpleclient.VamsasArchive;
10 import org.vamsas.client.simpleclient.VamsasArchiveReader;
11 import org.vamsas.objects.core.Entry;
12 import org.vamsas.objects.core.VAMSAS;
13 import org.vamsas.objects.core.VamsasDocument;
14 import org.vamsas.objects.utils.ProvenanceStuff;
15
16 // simple holder to pass to client.
17 public class ClientDoc {
18   protected boolean isModified=false;
19   private Log log = LogFactory.getLog(ClientDoc.class);
20   protected VamsasDocument doc;
21   public org.vamsas.objects.core.VAMSAS[] _VamsasRoots;
22   protected VamsasArchive iohandler=null;
23   protected VamsasArchiveReader reader=null;
24   private String user=null;
25   
26   /**
27    * @param doc
28    * @param iohandler
29    * @param reader
30    * @param user
31    */
32   public ClientDoc(VamsasDocument doc, VamsasArchive iohandler, VamsasArchiveReader reader, String user) {
33     super();
34     this.doc = doc;
35     this.iohandler = iohandler;
36     this.reader = reader;
37     this.user = user;
38     _VamsasRoots = doc.getVAMSAS();
39   }
40   // AppDataOutputStream appd;
41   //AppDataOutputStream userd;
42   /* (non-Javadoc)
43    * @see java.lang.Object#finalize()
44    */
45   protected Entry getProvenanceEntry(String action) {
46     // VAMSAS: modify schema to allow referencing of user field (plus other issues, ClientUrn field, machine readable action, input parameters, additional data generated notes
47     Entry prov = ProvenanceStuff.newProvenanceEntry(user, action);
48     return prov;
49   }
50   public VAMSAS[] getVamsasRoots() {
51     if (doc==null) {
52       log.debug("Null document for getVamsasRoots(), returning null");
53       return null;
54     }
55     if (iohandler==null) {
56       // LATER: decide on read-only status of ClientDocument object
57       log.warn("getVamsasRoots() called on possibly read-only document.");
58     }
59     if (_VamsasRoots!=null)
60       return _VamsasRoots;
61     VAMSAS[] roots = doc.getVAMSAS();
62     if (roots == null) {
63       // Make a new one to return to client to get filled. 
64       _VamsasRoots = new VAMSAS[] { new VAMSAS() };
65       // Do provenance now. just in case.
66       doc.getProvenance().addEntry(getProvenanceEntry("Created new document root [id="+_VamsasRoots[0].getId()+"]"));
67       doc.addVAMSAS(_VamsasRoots[0]);
68     } else {
69       _VamsasRoots = new VAMSAS[roots.length];
70       for (int r=0;r<roots.length; r++)
71         _VamsasRoots[r] = roots[r];
72     }
73     return _VamsasRoots;
74   }
75   
76   private int _contains(VAMSAS root, VAMSAS[] docRoots) {
77     if (root==null)
78       return -1;
79     if (docRoots==null || docRoots.length==0)
80       return -1;
81     VorbaId r_id = root.getVorbaId();
82     for (int i=0,j=docRoots.length; i<j; i++) {
83       VorbaId n_id=null;
84       if (docRoots[i]==root || (docRoots[i]!=null && (n_id=docRoots[i].getVorbaId())!=null && n_id.equals(r_id)))
85         return i;
86     }
87     return -1;
88   }
89 /**
90  * verify that newr version is really an intact version of the 
91  * @param newVersion (may be modified)
92  * @param oldVersion 
93  * @return true if newVersion is a valid root that preserves original references
94  */
95   private boolean isValidUpdate(VAMSAS newVersion, final VAMSAS oldVersion) {
96     // ideal - this cascades down the two structures, ensuring that all ID'd objects in one are present in the other.
97     if (oldVersion==newVersion) {
98       // may be a virgin root element.
99       if (!newVersion.isRegistered())
100         iohandler.getVorba().makeVorbaId(newVersion);
101       // Should retrieve original version and compare - unless local hashes can be used to determine if resultSet has been truncated.
102       // just do internal validation for moment.
103       if (newVersion.isValid())
104         return true;
105       return false;
106     } else {
107       // redundant ? if (oldVersion.is__stored_in_document())
108       if (!newVersion.isRegistered())
109         iohandler.getVorba().makeVorbaId(newVersion);
110       if (newVersion.isValid())
111         return true;
112     }
113     return false;
114   }
115     /**
116   /**
117    * merge old and new root vectors
118    * @param newr This array may be written to
119    * @param original
120    * @param the client document (usually this) which this root set belongs to.
121    * @return merged vector of vamsas roots
122    */
123   private VAMSAS[] _combineRoots(VAMSAS[] newr, final VAMSAS[] original, ClientDoc modflag) {
124     Vector rts = new Vector();
125     boolean modified=false;
126     for (int i=0,j=original.length; i<j; i++) {
127       int k = _contains(original[i], newr);
128       if (k>-1) {
129         if (isValidUpdate(newr[k], original[i])) {
130           modified=true;
131           rts.add(newr[k]);
132           newr[k]=null;
133         } else {
134           // LATER: try harder to merge ducument roots.
135           log.warn("Couldn't merge new VAMSAS root "+newr[k].getId());
136           newr[k] = null; // LATER: this means we ignore mangled roots. NOT GOOD
137         }
138       } else {
139         // add in order.
140         rts.add(original[i]);
141       }
142     }
143     // add remaining (new) roots
144     for (int i=0,j=newr.length; i<j; i++) {
145       if (newr[i]!=null) {
146         rts.add(newr[i]);
147         modified=true;
148       }
149     }
150     newr = new VAMSAS[rts.size()];
151     for (int i=0,j=rts.size(); i<j; i++)
152       newr[i] = (VAMSAS) rts.get(i);
153     if (modflag!=null)
154       modflag.isModified = modified;
155     return newr;
156   }
157   
158   /**
159    * update the document with new roots.
160    * LATER: decide: this affects the next call to getVamsasRoots()
161    * @see org.vamsas.IClientDocument.setVamsasRoots
162    */
163   public void setVamsasRoots(VAMSAS[] newroots) {
164     if (doc==null) {
165       log.debug("setVamsasRoots called on null document.");
166       return;
167     }
168     VAMSAS[] newr;
169     if (newroots==null) {
170       log.debug("setVamsasRoots(null) - do nothing.");
171       return;
172     }
173     // are we dealing with same array ?
174     if (_VamsasRoots!=newroots) {
175       // merge roots into local version.
176       newr = new VAMSAS[newroots.length];
177       for (int i=0;i<newr.length;i++)
178         newr[i] = newroots[i];
179       newr=_combineRoots(newr,_VamsasRoots,this);
180     } else {
181       newr = new VAMSAS[_VamsasRoots.length];
182       for (int i=0;i<newr.length;i++)
183         newr[i]=_VamsasRoots[i];
184     }
185     //  actually compare with document root set for final combination (to ensure nothing is lost)
186     _VamsasRoots = _combineRoots(newr, doc.getVAMSAS(), this); 
187   }
188   
189   
190   /* (non-Javadoc)
191    * LATER: decide: this affects the next call to getVamsasRoots()
192    * @see org.vamsas.client.IClientDocument#addVamsasRoot(org.vamsas.objects.core.VAMSAS)
193    */
194   public void addVamsasRoot(VAMSAS newroot) {
195     if (doc==null) {
196       log.debug("addVamsasRoots called on null document.");
197       return;
198     }
199     VAMSAS[] newroots = _combineRoots(new VAMSAS[] {newroot}, _VamsasRoots, this);
200     _VamsasRoots = newroots;  
201   }
202
203   public VamsasArchiveReader getReader() {
204     return reader;
205   }
206   protected void finalize() throws Throwable {
207     super.finalize();
208     //if (reader!=null)
209     //  reader.close();
210     //reader=null;
211 //    if (iohandler!=null) {
212 //      iohandler.cancelArchive(); // otherwise the original may be overwritten.
213 //    }
214   }
215   
216 }