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