1 package uk.ac.vamsas.test.simpleclient;
4 import java.io.InputStream;
5 import java.io.InputStreamReader;
6 import java.io.PrintWriter;
7 import java.text.DateFormat;
9 import java.util.Hashtable;
10 import java.util.Vector;
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;
25 public class ArchiveWriter {
28 * Test program for writing archive files.
29 * form is ArchiveWriter new/modified argive command list
32 static Log log = LogFactory.getLog(ArchiveWriter.class);
34 private static void mergeVecs(Object[] destvec, Object[] svec1, Object[] svec2) {
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];
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
45 public static Hashtable hashOfAppDatas(Hashtable ht, Instance[] appdatas) {
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());
54 // ensure urns and references are unique
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
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();
81 //while (o.getUrn().equals(urn)) {
82 // urn = entry.getUrn()+v++;
85 // check each user ApplicationData
87 // copy over valid objects
92 * Copy new datasets and appdatas from one vamsas document to another.
97 * @return true if merge was successful.
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
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]);
121 return true; // success
124 private static CommandProcessor cproc;
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");
133 public static void main(String argv[]) {
135 * TODO: switches for setting user identities for writing to vamsas document
138 log.fatal("Usage : <archive to create> [(commands)]");
141 File newarch = new File(argv[0]);
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]);
152 if (archive.exists()) {
153 VamsasArchiveReader vdoc = new VamsasArchiveReader(archive);
154 if (vdoc.isValid()) {
155 istream = vdoc.getVamsasDocumentStream();
157 VamsasDocument cdocroot = VamsasDocument.unmarshal(new InputStreamReader(istream));
159 mergeDocs(varc, docroot, vdoc, cdocroot);
161 log.warn("Unexpectedly null document stream from existing document "+archive);
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);
172 // Begin a new vamsas document
173 PrintWriter docwriter = varc.getDocumentOutputStream();
176 } catch (Exception e) {
177 log.error("Whilst manipulating "+argv[0], e);