trivial doc
[vamsas.git] / src / org / vamsas / test / simpleclient / ArchiveWriter.java
1 package org.vamsas.test.simpleclient;
2
3 import java.io.File;
4 import java.io.InputStream;
5 import java.io.InputStreamReader;
6 import java.io.PrintWriter;
7 import java.text.DateFormat;
8 import java.util.Date;
9 import java.util.Hashtable;
10
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13 import org.vamsas.client.simpleclient.VamsasArchive;
14 import org.vamsas.client.simpleclient.VamsasArchiveReader;
15 import org.vamsas.objects.core.ApplicationData;
16 import org.vamsas.objects.core.Entry;
17 import org.vamsas.objects.core.Provenance;
18 import org.vamsas.objects.core.VAMSAS;
19 import org.vamsas.objects.core.VamsasDocument;
20
21 public class ArchiveWriter {
22   
23   /**
24    * Test program for writing archive files.
25    * form is ArchiveWriter new/modified argive command list
26    */
27   
28   static Log log = LogFactory.getLog("org.vamsas.test.simpleclient.ArchiveWriter");
29   
30   /**
31    * @param action
32    *          text for action entry
33    * @return new Provenance entry for ArchiveWriter created docs.
34    * TODO: Verify and move to SimpleClient class for provenance handling
35    */
36   public static Entry newProvenanceEntry(String user, String action) { 
37     log.debug("Adding ProvenanceEntry("+user+","+action+")");
38     Entry e = new Entry();
39     e.setAction(action);
40     e.setUser(user);
41     e.setDate(new org.exolab.castor.types.Date(new Date()));
42     return e;
43   }
44   
45   public static Provenance newProvenance() {
46     Provenance list = new Provenance();
47     list.addEntry(newProvenanceEntry("ArchiveWriter", "Created new Vamsas Document"));
48     return list;
49   }
50   
51   private static void mergeVecs(Object[] destvec, Object[] svec1, Object[] svec2) {
52     int i;
53     for (i=0; i<svec1.length; i++)
54       destvec[i] = svec1[i];
55     for (int j=0; j<svec2.length; i++, j++)
56       destvec[i] = svec2[j];
57   }
58   // Merge appDataReferences require transfer of jar entries, perhaps with a renaming of the entry.
59   // Merge appDatas require eventually unique URNS
60   
61   public static Hashtable hashOfAppDatas(Hashtable ht, ApplicationData[] appdatas) {
62     if (ht==null)
63       ht = new Hashtable();
64     for (int i=0, j=appdatas.length; i<j; i++) {
65       if (!ht.containsKey(appdatas[i].getUrn())) {
66         Hashtable aphash = new Hashtable();
67         ht.put(appdatas[i].getUrn(), aphash);
68         aphash.put(appdatas[i], appdatas[i].getAppDataChoice().getDataReference());
69       } else {
70         // ensure urns and references are unique
71         
72         
73       }
74           
75     }
76     return ht;
77   }
78   /**
79    * safely copies an appData from one archive to another.
80    * @param darc destination archive
81    * @param dest destination document object
82    * @param sarc source archive reader
83    * @param entry application data to be copied from source archive
84    */
85   public static void addAppDataEntry(VamsasArchive darc, VamsasDocument dest,  VamsasArchiveReader sarc, ApplicationData entry) {
86     
87     // check uniqueness of entry.urn amongst dest.ApplicationData[].urn
88     //  check uniqueness of entry.user[].urn amongst dest.ApplicationData[].user[].urn
89     // check uniqueness of entry.user
90     // entry.getAppDataChoice().getData() or getDataReference is unique
91     ApplicationData newo = new ApplicationData();
92     for (int i=0, j=dest.getApplicationDataCount(); i<j; i++) {
93       ApplicationData o = dest.getApplicationData()[i];
94       // ensure new urn is really unique
95       String urn = entry.getUrn();
96       int v = 1;
97       while (o.getUrn().equals(urn)) {
98         urn = entry.getUrn()+v++;      
99       }
100       // uniqueness of urn
101       // check each user ApplicationData
102       // uniqueness (again)
103       // copy over valid objects
104       // 
105     }
106   }
107   /**
108    * Copy new datasets and appdatas from one vamsas document to another.
109    * @param darc
110    * @param dest
111    * @param sarc
112    * @param source
113    * @return true if merge was successful.
114    */
115   public static boolean mergeDocs(VamsasArchive darc, VamsasDocument dest,  VamsasArchiveReader sarc, VamsasDocument source) {
116     log.debug("mergeDocs entered.");
117     // search for appDatas in cdoc
118     VAMSAS[] newr = new VAMSAS[dest.getVAMSASCount()+source.getVAMSASCount()];
119     mergeVecs(newr, dest.getVAMSAS(), source.getVAMSAS());
120     dest.setVAMSAS(newr);
121     /** TODO: LATER: should verify that all ids really are unique in newly merged document. If not then what ?
122      *  investigate possibility of having an id translation between appDatas and the core document - 
123      *  the mapping is stored when an external application performs a merge, but when the owning 
124      *  Application accesses the object, the vorba_id is updated to the new one when it writes its 
125      *  references in to its appdata again
126      */
127     if (source.getApplicationDataCount()>0) {
128       ApplicationData[] newdat = new ApplicationData[source.getApplicationDataCount()+dest.getApplicationDataCount()];
129       ApplicationData[] sappd = source.getApplicationData();
130       // check refs and update/modify if necessary
131       for (int i=0; i<sappd.length; i++) {
132         addAppDataEntry(darc, dest, sarc, sappd[i]);
133       }
134       
135     }
136     
137     return true; // success    
138   }
139   
140   
141   public static void main(String argv[]) {
142     /**
143      * TODO: switches for setting user identities for writing to vamsas document
144      */ 
145     if (argv.length<1) {
146       log.fatal("Usage : <archive to create> [(commands)]");
147       return;
148     }
149     File newarch = new File(argv[0]);
150     int argpos = 0;
151     try {
152       // test fully fledged doc construction
153       VamsasArchive varc = new VamsasArchive(newarch, true);
154       VamsasDocument docroot;
155       docroot = new VamsasDocument();
156       docroot.setProvenance(newProvenance());
157       while (++argpos<argv.length) {
158         File archive = new File(argv[argpos]);
159         InputStream istream;
160         if (archive.exists()) {
161           VamsasArchiveReader vdoc = new VamsasArchiveReader(archive);
162           if (vdoc.isValid()) {
163             istream = vdoc.getVamsasDocumentStream(); 
164             if (istream!=null) {
165               VamsasDocument cdocroot = VamsasDocument.unmarshal(new InputStreamReader(istream));
166               if (cdocroot!=null) 
167                 mergeDocs(varc, docroot, vdoc, cdocroot);
168             } else 
169               log.warn("Unexpectedly null document stream from existing document "+archive);
170           } else {
171               // updating an oldformat stream ?
172               if ((istream = vdoc.getVamsasXmlStream())!=null) {
173                 // make a new vamsas document from the vamsas.xml entry
174                 VAMSAS root = VAMSAS.unmarshal(new InputStreamReader(istream)); // TODO: verify only one VAMSAS element per vamsas.xml entry.
175                 docroot.getProvenance().addEntry(newProvenanceEntry("user", "added vamsas.xml from "+argv[argpos-1]));
176                 docroot.addVAMSAS(root);
177               }
178           }
179         } else {
180           // Begin a new vamsas document
181           PrintWriter docwriter = varc.getDocumentOutputStream();
182         }
183       }
184     } catch (Exception e) {
185       log.error("Whilst manipulating "+argv[0], e);
186     }
187   }
188 }