aecf14f575fa1bb559c47186677ffebb37693332
[vamsas.git] / src / uk / ac / 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 uk.ac.vamsas.test.simpleclient.simpleapp;\r
21 \r
22 \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.getLog(VamsasDatastore.class);\r
50   Entry provEntry = null;\r
51 \r
52 \r
53   org.exolab.castor.types.Date date = new org.exolab.castor.types.Date(\r
54       new java.util.Date());\r
55 \r
56   ClientDoc cdoc;\r
57 \r
58   Hashtable vobj2jv;\r
59 \r
60   IdentityHashMap jv2vobj;\r
61 \r
62   public VamsasDatastore(ClientDoc cdoc, Hashtable vobj2jv,\r
63       IdentityHashMap jv2vobj, Entry provEntry) {\r
64       this.cdoc = cdoc;\r
65     this.vobj2jv = vobj2jv;\r
66     this.jv2vobj = jv2vobj;\r
67     this.provEntry = provEntry;\r
68   }\r
69 \r
70   /*\r
71    * public void storeJalview(String file, AlignFrame af) { try { // 1. Load the\r
72    * mapping information from the file Mapping map = new\r
73    * Mapping(getClass().getClassLoader()); java.net.URL url =\r
74    * getClass().getResource("/jalview_mapping.xml"); map.loadMapping(url); // 2.\r
75    * Unmarshal the data // Unmarshaller unmar = new Unmarshaller();\r
76    * //unmar.setIgnoreExtraElements(true); //unmar.setMapping(map); // uni =\r
77    * (UniprotFile) unmar.unmarshal(new FileReader(file)); // 3. marshal the data\r
78    * with the total price back and print the XML in the console Marshaller\r
79    * marshaller = new Marshaller( new FileWriter(file) );\r
80    * \r
81    * marshaller.setMapping(map); marshaller.marshal(af); } catch (Exception e) {\r
82    * e.printStackTrace(); } }\r
83    * \r
84    * \r
85    */\r
86   /**\r
87    * @return the Vobject bound to Jalview datamodel object\r
88    */\r
89   protected Vobject getjv2vObj(Object jvobj) {\r
90     if (jv2vobj.containsKey(jvobj))\r
91       return cdoc.getObject((VorbaId) jv2vobj.get(jvobj));\r
92     return null;\r
93   }\r
94 \r
95   /**\r
96    * \r
97    * @param vobj\r
98    * @return Jalview datamodel object bound to the vamsas document object\r
99    */\r
100   protected Object getvObj2jv(uk.ac.vamsas.client.Vobject vobj) {\r
101     VorbaId id = vobj.getVorbaId();\r
102     if (id == null)\r
103     {\r
104       id = cdoc.registerObject(vobj);\r
105       log\r
106       .debug("Registering new object and returning null for getvObj2jv");\r
107       return null;\r
108     }\r
109     if (vobj2jv.containsKey(vobj.getVorbaId()))\r
110       return vobj2jv.get(vobj.getVorbaId());\r
111     return null;\r
112   }\r
113 \r
114   protected void bindjvvobj(Object jvobj, uk.ac.vamsas.client.Vobject vobj) {\r
115     VorbaId id = vobj.getVorbaId();\r
116     if (id == null)\r
117     {\r
118       id = cdoc.registerObject(vobj);\r
119       if (id==null || vobj.getVorbaId()==null)\r
120         log.error("Failed to get id for "+(vobj.isRegisterable() ? "registerable" : "unregisterable") +" object "+vobj);\r
121     }\r
122     if (vobj2jv.containsKey(vobj.getVorbaId()) || jv2vobj.containsKey(jvobj))\r
123     {\r
124       log.error("Duplicate object binding! "+vobj+" id " +vobj.getVorbaId().getId()+" to "+jvobj);\r
125     }\r
126     else\r
127     {\r
128       vobj2jv.put(vobj.getVorbaId(), jvobj);// JBPNote - better implementing a\r
129       // hybrid invertible hash.\r
130       jv2vobj.put(jvobj, vobj.getVorbaId());\r
131     }\r
132   }\r
133 \r
134   /**\r
135    * put the alignment viewed by AlignViewport into cdoc.\r
136    * \r
137    * @param av\r
138    */\r
139   public void storeVAMSAS(Object fromAppsDatamodel) {\r
140     boolean nw = false;\r
141     VAMSAS root = null; // will be resolved based on Dataset Parent.\r
142     DataSet dataset = (DataSet) getjv2vObj(fromAppsDatamodel);\r
143     if (dataset == null)\r
144     {\r
145       root = cdoc.getVamsasRoots()[0]; // default vamsas root for modifying.\r
146       dataset = new DataSet();\r
147       root.addDataSet(dataset);\r
148       bindjvvobj(fromAppsDatamodel, dataset);\r
149       dataset.setProvenance(dummyProvenance());\r
150       dataset.getProvenance().addEntry(provEntry);\r
151       nw = true;\r
152     } else {\r
153       root = (VAMSAS) dataset.getV_parent();\r
154     }\r
155     // etc...\r
156   }\r
157 \r
158   private Property newProperty(String name, String type, String content) {\r
159     Property vProperty=new Property();\r
160     vProperty.setName(name);\r
161     if (type!=null)\r
162       vProperty.setType(type);\r
163     vProperty.setContent(content);\r
164     return vProperty;\r
165   }\r
166 \r
167   /**\r
168    * get start<end range of segment, adjusting for inclusivity flag and\r
169    * polarity.\r
170    *  \r
171    * @param visSeg\r
172    * @param ensureDirection when true - always ensure start is less than end.\r
173    * @return int[] { start, end, direction} where direction==1 for range running from end to start.\r
174    */\r
175   private int[] getSegRange(Seg visSeg, boolean ensureDirection) {\r
176     boolean incl = visSeg.getInclusive();\r
177     // adjust for inclusive flag.\r
178     int pol = (visSeg.getStart() <= visSeg.getEnd()) ? 1 : -1; // polarity of\r
179     // region.\r
180     int start = visSeg.getStart() + (incl ? 0 : pol);\r
181     int end = visSeg.getEnd() + (incl ? 0 : -pol);\r
182     if (ensureDirection && pol==-1)\r
183     {\r
184       // jalview doesn't deal with inverted ranges, yet.\r
185       int t = end;\r
186       end = start;\r
187       start = t;\r
188     }\r
189     return new int[] { start, end, pol<0 ? 1 : 0 };\r
190   }\r
191 \r
192   public void updateToJalview() {\r
193     VAMSAS _roots[] = cdoc.getVamsasRoots();\r
194 \r
195     for (int _root = 0; _root<_roots.length; _root++) {\r
196       VAMSAS root = _roots[_root];\r
197       boolean newds=false;\r
198       for (int _ds=0,_nds=root.getDataSetCount(); _ds<_nds; _ds++) {\r
199         // ///////////////////////////////////\r
200         // ///LOAD DATASET\r
201         DataSet dataset = root.getDataSet(_ds);\r
202         int i, iSize = dataset.getSequenceCount();\r
203         Vector dsseqs;\r
204         Object appsdataset = (Object) getvObj2jv(dataset);\r
205         int jremain=0;\r
206         if (appsdataset==null) {\r
207           log.debug("Initialising new dataset fields");\r
208           newds=true;\r
209           dsseqs=new Vector();\r
210         } else {\r
211           log.debug("Update dataset from vamsas dataset.");\r
212         }\r
213         // etc for annotations, alignments, trees, etc. \r
214       }\r
215     }\r
216   }\r
217   /**\r
218    * get real bounds of a RangeType's specification. start and end are an\r
219    * inclusive range within which all segments and positions lie.\r
220    * TODO: refactor to vamsas utils\r
221    * @param dseta\r
222    * @return int[] { start, end}\r
223    */\r
224   private int[] getBounds(RangeType dseta) {\r
225     if (dseta != null)\r
226     {\r
227       int[] se = null;\r
228       if (dseta.getSegCount()>0 && dseta.getPosCount()>0)\r
229         throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
230       if (dseta.getSegCount() > 0)\r
231       {\r
232         se = getSegRange(dseta.getSeg(0),true);\r
233         for (int s = 1, sSize = dseta.getSegCount(); s < sSize; s++)\r
234         {\r
235           int nse[] = getSegRange(dseta.getSeg(s), true);\r
236           if (se[0] > nse[0])\r
237             se[0] = nse[0];\r
238           if (se[1] < nse[1])\r
239             se[1] = nse[1];\r
240         }\r
241       }\r
242       if (dseta.getPosCount() > 0)\r
243       {\r
244         // could do a polarity for pos range too. and pass back indication of discontinuities.\r
245         int pos = dseta.getPos(0).getI();\r
246         se = new int[] { pos, pos };\r
247         for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)\r
248         {\r
249           pos = dseta.getPos(p).getI();\r
250           if (se[0] > pos)\r
251             se[0] = pos;\r
252           if (se[1] < pos)\r
253             se[1] = pos;\r
254         }\r
255       }\r
256       return se;\r
257     }\r
258     return null;\r
259   }\r
260   /**\r
261    * map from a rangeType's internal frame to the referenced object's coordinate frame.\r
262    * @param dseta\r
263    * @return int [] { ref(pos)...} for all pos in rangeType's frame.\r
264    */\r
265   private int[] getMapping(RangeType dseta) {\r
266     Vector posList=new Vector();\r
267     if (dseta != null)\r
268     {\r
269       int[] se = null;\r
270       if (dseta.getSegCount()>0 && dseta.getPosCount()>0)\r
271         throw new Error("Invalid vamsas RangeType - cannot resolve both lists of Pos and Seg from choice!");\r
272       if (dseta.getSegCount() > 0)\r
273       {\r
274         for (int s = 0, sSize = dseta.getSegCount(); s < sSize; s++)\r
275         {\r
276           se = getSegRange(dseta.getSeg(s), false);\r
277           int se_end=se[1-se[2]]+(se[2]==0 ? 1 : -1);\r
278           for (int p=se[se[2]]; p!=se_end; p+=se[2]==0 ? 1 : -1 ) {\r
279             posList.add(new Integer(p));\r
280           }\r
281         }\r
282       } \r
283       else if (dseta.getPosCount() > 0)\r
284       {\r
285         int pos = dseta.getPos(0).getI();\r
286 \r
287         for (int p = 0, pSize = dseta.getPosCount(); p < pSize; p++)\r
288         {\r
289           pos = dseta.getPos(p).getI();\r
290           posList.add(new Integer(pos));\r
291         }\r
292       }\r
293     }\r
294     if (posList!=null && posList.size()>0) {\r
295       int[] range=new int[posList.size()];\r
296       for (int i=0; i<range.length; i++)\r
297         range[i] = ((Integer)posList.elementAt(i)).intValue();\r
298       posList.clear();\r
299       return range;\r
300     }\r
301     return null;\r
302   }\r
303   /**\r
304    * \r
305    * @return default initial provenance list for a VamsasDatastore created vamsas\r
306    *         object.\r
307    */\r
308   Provenance dummyProvenance() {\r
309     return dummyProvenance(null);\r
310   }\r
311 \r
312   Entry dummyPEntry(String action) {\r
313     Entry entry = new Entry();\r
314     entry.setApp(this.provEntry.getApp());\r
315     if (action != null)\r
316       entry.setAction(action);\r
317     else\r
318       entry.setAction("created.");\r
319     entry.setDate(new java.util.Date());\r
320     entry.setUser(this.provEntry.getUser());\r
321     return entry;\r
322   }\r
323 \r
324   Provenance dummyProvenance(String action) {\r
325     Provenance prov = new Provenance();\r
326     prov.addEntry(dummyPEntry(action));\r
327     return prov;\r
328   }\r
329 \r
330   void addProvenance(Provenance p, String action) {\r
331     p.addEntry(dummyPEntry(action));\r
332   }\r
333 \r
334 }\r