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