applied LGPLv3 and source code formatting.
[vamsas.git] / src / uk / ac / vamsas / test / simpleclient / simpleapp / VamsasDatastore.java
1 /*\r
2  * This file is part of the Vamsas Client version 0.1. \r
3  * Copyright 2009 by Jim Procter, Iain Milne, Pierre Marguerite, \r
4  *  Andrew Waterhouse and Dominik Lindner.\r
5  * \r
6  * Earlier versions have also been incorporated into Jalview version 2.4 \r
7  * since 2008, and TOPALi version 2 since 2007.\r
8  * \r
9  * The Vamsas Client is free software: you can redistribute it and/or modify\r
10  * it under the terms of the GNU Lesser General Public License as published by\r
11  * the Free Software Foundation, either version 3 of the License, or\r
12  * (at your option) any later version.\r
13  *  \r
14  * The Vamsas Client is distributed in the hope that it will be useful,\r
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
17  * GNU Lesser General Public License for more details.\r
18  * \r
19  * You should have received a copy of the GNU Lesser General Public License\r
20  * along with the Vamsas Client.  If not, see <http://www.gnu.org/licenses/>.\r
21  */\r
22 package uk.ac.vamsas.test.simpleclient.simpleapp;\r
23 \r
24 import java.io.*;\r
25 import java.util.HashMap;\r
26 import java.util.HashSet;\r
27 import java.util.Hashtable;\r
28 import java.util.IdentityHashMap;\r
29 import java.util.Vector;\r
30 import java.util.jar.*;\r
31 import org.exolab.castor.xml.*;\r
32 import org.exolab.castor.mapping.Mapping;\r
33 \r
34 import uk.ac.vamsas.client.Vobject;\r
35 import uk.ac.vamsas.client.VorbaId;\r
36 import uk.ac.vamsas.objects.core.*;\r
37 import uk.ac.vamsas.objects.utils.DocumentStuff;\r
38 import uk.ac.vamsas.test.simpleclient.ClientDoc;\r
39 \r
40 /*\r
41  * \r
42  * static {\r
43  * org.exolab.castor.util.LocalConfiguration.getInstance().getProperties().setProperty(\r
44  * "org.exolab.castor.serializer", "org.apache.xml.serialize.XMLSerilazizer"); }\r
45  * \r
46  */\r
47 \r
48 public class VamsasDatastore {\r
49   org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory\r
50       .getLog(VamsasDatastore.class);\r
51 \r
52   Entry provEntry = null;\r
53 \r
54   org.exolab.castor.types.Date date = new org.exolab.castor.types.Date(\r
55       new java.util.Date());\r
56 \r
57   ClientDoc cdoc;\r
58 \r
59   Hashtable vobj2jv;\r
60 \r
61   IdentityHashMap jv2vobj;\r
62 \r
63   public VamsasDatastore(ClientDoc cdoc, Hashtable vobj2jv,\r
64       IdentityHashMap jv2vobj, Entry provEntry) {\r
65     this.cdoc = cdoc;\r
66     this.vobj2jv = vobj2jv;\r
67     this.jv2vobj = jv2vobj;\r
68     this.provEntry = provEntry;\r
69   }\r
70 \r
71   /*\r
72    * public void storeJalview(String file, AlignFrame af) { try { // 1. Load the\r
73    * mapping information from the file Mapping map = new\r
74    * Mapping(getClass().getClassLoader()); java.net.URL url =\r
75    * getClass().getResource("/jalview_mapping.xml"); map.loadMapping(url); // 2.\r
76    * Unmarshal the data // Unmarshaller unmar = new Unmarshaller();\r
77    * //unmar.setIgnoreExtraElements(true); //unmar.setMapping(map); // uni =\r
78    * (UniprotFile) unmar.unmarshal(new FileReader(file)); // 3. marshal the data\r
79    * with the total price back and print the XML in the console Marshaller\r
80    * marshaller = new Marshaller( new FileWriter(file) );\r
81    * \r
82    * marshaller.setMapping(map); marshaller.marshal(af); } catch (Exception e) {\r
83    * e.printStackTrace(); } }\r
84    */\r
85   /**\r
86    * @return the Vobject bound to Jalview datamodel object\r
87    */\r
88   protected Vobject getjv2vObj(Object jvobj) {\r
89     if (jv2vobj.containsKey(jvobj))\r
90       return cdoc.getObject((VorbaId) jv2vobj.get(jvobj));\r
91     return null;\r
92   }\r
93 \r
94   /**\r
95    * \r
96    * @param vobj\r
97    * @return Jalview datamodel object bound to the vamsas document object\r
98    */\r
99   protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj) {\r
100     VorbaId id = vobj.getVorbaId();\r
101     if (id == null) {\r
102       id = cdoc.registerObject(vobj);\r
103       log.debug("Registering new object and returning null for getvObj2jv");\r
104       return null;\r
105     }\r
106     if (vobj2jv.containsKey(vobj.getVorbaId()))\r
107       return vobj2jv.get(vobj.getVorbaId());\r
108     return null;\r
109   }\r
110 \r
111   protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj) {\r
112     VorbaId id = vobj.getVorbaId();\r
113     if (id == null) {\r
114       id = cdoc.registerObject(vobj);\r
115       if (id == null || vobj.getVorbaId() == null)\r
116         log.error("Failed to get id for "\r
117             + (vobj.isRegisterable() ? "registerable" : "unregisterable")\r
118             + " object " + vobj);\r
119     }\r
120     if (vobj2jv.containsKey(vobj.getVorbaId()) || jv2vobj.containsKey(jvobj)) {\r
121       log.error("Duplicate object binding! " + vobj + " id "\r
122           + vobj.getVorbaId().getId() + " to " + jvobj);\r
123     } else {\r
124       vobj2jv.put(vobj.getVorbaId(), jvobj);// JBPNote - better implementing a\r
125       // hybrid invertible hash.\r
126       jv2vobj.put(jvobj, vobj.getVorbaId());\r
127     }\r
128   }\r
129 \r
130   /**\r
131    * put the alignment viewed by AlignViewport into cdoc.\r
132    * \r
133    * @param av\r
134    */\r
135   public void storeVAMSAS(Object fromAppsDatamodel) {\r
136     boolean nw = false;\r
137     VAMSAS root = null; // will be resolved based on Dataset Parent.\r
138     DataSet dataset = (DataSet) getjv2vObj(fromAppsDatamodel);\r
139     if (dataset == null) {\r
140       root = cdoc.getVamsasRoots()[0]; // default vamsas root for modifying.\r
141       dataset = new DataSet();\r
142       root.addDataSet(dataset);\r
143       bindjvvobj(fromAppsDatamodel, dataset);\r
144       dataset.setProvenance(dummyProvenance());\r
145       dataset.getProvenance().addEntry(provEntry);\r
146       nw = true;\r
147     } else {\r
148       root = (VAMSAS) dataset.getV_parent();\r
149     }\r
150     // etc...\r
151   }\r
152 \r
153   private Property newProperty(String name, String type, String content) {\r
154     Property vProperty = new Property();\r
155     vProperty.setName(name);\r
156     if (type != null)\r
157       vProperty.setType(type);\r
158     vProperty.setContent(content);\r
159     return vProperty;\r
160   }\r
161 \r
162   /**\r
163    * get start<end range of segment, adjusting for inclusivity flag and\r
164    * polarity.\r
165    * \r
166    * @param visSeg\r
167    * @param ensureDirection\r
168    *          when true - always ensure start is less than end.\r
169    * @return int[] { start, end, direction} where direction==1 for range running\r
170    *         from end to start.\r
171    */\r
172   private int[] getSegRange(Seg visSeg, boolean ensureDirection) {\r
173     boolean incl = visSeg.getInclusive();\r
174     // adjust for inclusive flag.\r
175     int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of\r
176     // region.\r
177     int start = visSeg.getStart() + (incl ? 0 : pol);\r
178     int end = visSeg.getEnd() + (incl ? 0 : -pol);\r
179     if (ensureDirection && pol == -1) {\r
180       // jalview doesn't deal with inverted ranges, yet.\r
181       int t = end;\r
182       end = start;\r
183       start = t;\r
184     }\r
185     return new int[] { start, end, pol < 0 ? 1 : 0 };\r
186   }\r
187 \r
188   public void updateToJalview() {\r
189     VAMSAS _roots[] = cdoc.getVamsasRoots();\r
190 \r
191     for (int _root = 0; _root < _roots.length; _root++) {\r
192       VAMSAS root = _roots[_root];\r
193       boolean newds = false;\r
194       for (int _ds = 0, _nds = root.getDataSetCount(); _ds < _nds; _ds++) {\r
195         // ///////////////////////////////////\r
196         // ///LOAD DATASET\r
197         DataSet dataset = root.getDataSet(_ds);\r
198         int i, iSize = dataset.getSequenceCount();\r
199         Vector dsseqs;\r
200         Object appsdataset = (Object) getvObj2jv(dataset);\r
201         int jremain = 0;\r
202         if (appsdataset == null) {\r
203           log.debug("Initialising new dataset fields");\r
204           newds = true;\r
205           dsseqs = new Vector();\r
206         } else {\r
207           log.debug("Update dataset from vamsas dataset.");\r
208         }\r
209         // etc for annotations, alignments, trees, etc.\r
210       }\r
211     }\r
212   }\r
213 \r
214   /**\r
215    * get real bounds of a RangeType's specification. start and end are an\r
216    * inclusive range within which all segments and positions lie. TODO: refactor\r
217    * to vamsas utils\r
218    * \r
219    * @param dseta\r
220    * @return int[] { start, end}\r
221    */\r
222   private int[] getBounds(RangeType dseta) {\r
223     if (dseta != null) {\r
224       int[] se = null;\r
225       if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)\r
226         throw new Error(\r
227             "Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
228       if (dseta.getSegCount() > 0) {\r
229         se = getSegRange(dseta.getSeg(0), true);\r
230         for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++) {\r
231           int nse[] = getSegRange(dseta.getSeg(s), true);\r
232           if (se[0] > nse[0])\r
233             se[0] = nse[0];\r
234           if (se[1] < nse[1])\r
235             se[1] = nse[1];\r
236         }\r
237       }\r
238       if (dseta.getPosCount() > 0) {\r
239         // could do a polarity for pos range too. and pass back indication of\r
240         // discontinuities.\r
241         int pos = dseta.getPos(0).getI();\r
242         se = new int[] { pos, pos };\r
243         for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++) {\r
244           pos = dseta.getPos(p).getI();\r
245           if (se[0] > pos)\r
246             se[0] = pos;\r
247           if (se[1] < pos)\r
248             se[1] = pos;\r
249         }\r
250       }\r
251       return se;\r
252     }\r
253     return null;\r
254   }\r
255 \r
256   /**\r
257    * map from a rangeType's internal frame to the referenced object's coordinate\r
258    * frame.\r
259    * \r
260    * @param dseta\r
261    * @return int [] { ref(pos)...} for all pos in rangeType's frame.\r
262    */\r
263   private int[] getMapping(RangeType dseta) {\r
264     Vector posList = new Vector();\r
265     if (dseta != null) {\r
266       int[] se = null;\r
267       if (dseta.getSegCount() > 0 && dseta.getPosCount() > 0)\r
268         throw new Error(\r
269             "Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
270       if (dseta.getSegCount() > 0) {\r
271         for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++) {\r
272           se = getSegRange(dseta.getSeg(s), false);\r
273           int se_end = se[1 - se[2]] + (se[2] == 0 ? 1 : -1);\r
274           for (int p = se[se[2]]; p != se_end; p += se[2] == 0 ? 1 : -1) {\r
275             posList.add(new Integer(p));\r
276           }\r
277         }\r
278       } else if (dseta.getPosCount() > 0) {\r
279         int pos = dseta.getPos(0).getI();\r
280 \r
281         for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++) {\r
282           pos = dseta.getPos(p).getI();\r
283           posList.add(new Integer(pos));\r
284         }\r
285       }\r
286     }\r
287     if (posList != null && posList.size() > 0) {\r
288       int[] range = new int[posList.size()];\r
289       for (int i = 0; i < range.length; i++)\r
290         range[i] = ((Integer) posList.elementAt(i)).intValue();\r
291       posList.clear();\r
292       return range;\r
293     }\r
294     return null;\r
295   }\r
296 \r
297   /**\r
298    * \r
299    * @return default initial provenance list for a VamsasDatastore created\r
300    *         vamsas object.\r
301    */\r
302   Provenance dummyProvenance() {\r
303     return dummyProvenance(null);\r
304   }\r
305 \r
306   Entry dummyPEntry(String action) {\r
307     Entry entry = new Entry();\r
308     entry.setApp(this.provEntry.getApp());\r
309     if (action != null)\r
310       entry.setAction(action);\r
311     else\r
312       entry.setAction("created.");\r
313     entry.setDate(new java.util.Date());\r
314     entry.setUser(this.provEntry.getUser());\r
315     return entry;\r
316   }\r
317 \r
318   Provenance dummyProvenance(String action) {\r
319     Provenance prov = new Provenance();\r
320     prov.addEntry(dummyPEntry(action));\r
321     return prov;\r
322   }\r
323 \r
324   void addProvenance(Provenance p, String action) {\r
325     p.addEntry(dummyPEntry(action));\r
326   }\r
327 \r
328 }\r