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