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