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