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