/* * This file is part of the Vamsas Client version 0.1. * Copyright 2009 by Jim Procter, Iain Milne, Pierre Marguerite, * Andrew Waterhouse and Dominik Lindner. * * Earlier versions have also been incorporated into Jalview version 2.4 * since 2008, and TOPALi version 2 since 2007. * * The Vamsas Client is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Vamsas Client is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the Vamsas Client. If not, see . */ package uk.ac.vamsas.test.simpleclient; import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.text.DateFormat; import java.util.Date; import java.util.Hashtable; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import uk.ac.vamsas.objects.core.Alignment; import uk.ac.vamsas.objects.core.ApplicationData; import uk.ac.vamsas.objects.core.Entry; import uk.ac.vamsas.objects.core.Instance; import uk.ac.vamsas.objects.core.Provenance; import uk.ac.vamsas.objects.core.VAMSAS; import uk.ac.vamsas.objects.core.VamsasDocument; import uk.ac.vamsas.objects.utils.ProvenanceStuff; import uk.ac.vamsas.client.simpleclient.VamsasArchive; import uk.ac.vamsas.client.simpleclient.VamsasArchiveReader; public class ArchiveWriter { /** * Test program for writing archive files. form is ArchiveWriter new/modified * argive command list */ static Log log = LogFactory.getLog(ArchiveWriter.class); private static void mergeVecs(Object[] destvec, Object[] svec1, Object[] svec2) { int i; for (i = 0; i < svec1.length; i++) destvec[i] = svec1[i]; for (int j = 0; j < svec2.length; i++, j++) destvec[i] = svec2[j]; } // Merge appDataReferences require transfer of jar entries, perhaps with a // renaming of the entry. // Merge appDatas require eventually unique URNS // TODO: merging global appdata from different documents where same app has // written them causes conflict public static Hashtable hashOfAppDatas(Hashtable ht, Instance[] appdatas) { if (ht == null) ht = new Hashtable(); for (int i = 0, j = appdatas.length; i < j; i++) { if (!ht.containsKey(appdatas[i].getUrn())) { Hashtable aphash = new Hashtable(); ht.put(appdatas[i].getUrn(), aphash); aphash.put(appdatas[i], appdatas[i].getDataReference()); } else { // ensure urns and references are unique } } return ht; } /** * safely copies an appData from one archive to another. * * @param darc * destination archive * @param dest * destination document Vobject * @param sarc * source archive reader * @param entry * application data to be copied from source archive */ public static void addAppDataEntry(VamsasArchive darc, VamsasDocument dest, VamsasArchiveReader sarc, ApplicationData entry) { // TODO: fix instances // check uniqueness of instance's[] entry.urn amongst // dest.ApplicationData[].getInstances[].urn // check uniqueness of entry.user[].urn amongst // dest.ApplicationData[].user[].urn // check uniqueness of entry.user // entry.getAppDataChoice().getData() or getDataReference is unique ApplicationData newo = new ApplicationData(); for (int i = 0, j = dest.getApplicationDataCount(); i < j; i++) { ApplicationData o = dest.getApplicationData()[i]; // ensure new urn is really unique // String urn = entry.getUrn(); int v = 1; // while (o.getUrn().equals(urn)) { // urn = entry.getUrn()+v++; // } // uniqueness of urn // check each user ApplicationData // uniqueness (again) // copy over valid objects // } } /** * Copy new datasets and appdatas from one vamsas document to another. * * @param darc * @param dest * @param sarc * @param source * @return true if merge was successful. */ public static boolean mergeDocs(VamsasArchive darc, VamsasDocument dest, VamsasArchiveReader sarc, VamsasDocument source) { log.debug("mergeDocs entered."); // search for appDatas in cdoc VAMSAS[] newr = new VAMSAS[dest.getVAMSASCount() + source.getVAMSASCount()]; mergeVecs(newr, dest.getVAMSAS(), source.getVAMSAS()); dest.setVAMSAS(newr); /** * TODO: LATER: should verify that all ids really are unique in newly merged * document. If not then what ? investigate possibility of having an id * translation between appDatas and the core document - the mapping is * stored when an external application performs a merge, but when the owning * Application accesses the Vobject, the vorba_id is updated to the new one * when it writes its references in to its appdata again */ if (source.getApplicationDataCount() > 0) { ApplicationData[] newdat = new ApplicationData[source .getApplicationDataCount() + dest.getApplicationDataCount()]; ApplicationData[] sappd = source.getApplicationData(); // check refs and update/modify if necessary for (int i = 0; i < sappd.length; i++) { addAppDataEntry(darc, dest, sarc, sappd[i]); } } return true; // success } private static CommandProcessor cproc; static { cproc.addCommand("new", 0, "no args"); cproc.addCommand("add", 1, "Need another vamsas document archive filename as argument."); cproc.addCommand("repair", 0, "no args"); cproc.addCommand("list", 0, "no args"); cproc.addCommand("monitor", 0, "no args"); } public static void main(String argv[]) { /** * TODO: switches for setting user identities for writing to vamsas document */ if (argv.length < 1) { log.fatal("Usage : [(commands)]"); return; } File newarch = new File(argv[0]); int argpos = 0; try { // test fully fledged doc construction VamsasArchive varc = new VamsasArchive(newarch, true); VamsasDocument docroot; docroot = new VamsasDocument(); docroot.setProvenance(ProvenanceStuff.newProvenance("ArchiveWriter", "user", "Created new Vamsas Document")); while (++argpos < argv.length) { File archive = new File(argv[argpos]); InputStream istream; if (archive.exists()) { VamsasArchiveReader vdoc = new VamsasArchiveReader(archive); if (vdoc.isValid()) { istream = vdoc.getVamsasDocumentStream(); if (istream != null) { VamsasDocument cdocroot = VamsasDocument .unmarshal(new InputStreamReader(istream)); if (cdocroot != null) mergeDocs(varc, docroot, vdoc, cdocroot); } else log .warn("Unexpectedly null document stream from existing document " + archive); } else { // updating an oldformat stream ? if ((istream = vdoc.getVamsasXmlStream()) != null) { // make a new vamsas document from the vamsas.xml entry VAMSAS root = VAMSAS.unmarshal(new InputStreamReader(istream)); // TODO: // verify // only // one // VAMSAS // element // per // vamsas.xml // entry. docroot.getProvenance().addEntry( ProvenanceStuff.newProvenanceEntry("ArchiveWriter", "user", "added vamsas.xml from " + argv[argpos - 1])); docroot.addVAMSAS(root); } } } else { // Begin a new vamsas document PrintWriter docwriter = varc.getDocumentOutputStream(); } } } catch (Exception e) { log.error("Whilst manipulating " + argv[0], e); } } }