more rar friendly appdata reference name and uniqueness check,
[vamsas.git] / src / uk / ac / vamsas / objects / utils / AppDataReference.java
1 /**
2  * 
3  */
4 package uk.ac.vamsas.objects.utils;
5 import java.util.Vector;
6
7
8 import uk.ac.vamsas.client.ClientHandle;
9 import uk.ac.vamsas.client.UserHandle;
10 import uk.ac.vamsas.client.simpleclient.VamsasArchive;
11 import uk.ac.vamsas.client.simpleclient.VamsasArchiveReader;
12 import uk.ac.vamsas.objects.core.*;
13 /**
14  * Form, accessors and validation for ApplicationData references in
15  * vamsas document.
16  * TODO: LATER:extend XML Schema to properly validate against the same forms required by this class
17  * TODO: VAMSAS: URNS for appDatas are supposed to be unique, aren't they ?
18  */
19 public class AppDataReference {
20   /**
21    * search interface for collecting particular types of AppDatas in a vamsas document
22    * @author jimp
23    *
24    */
25   interface IAppDSearch {
26     /**
27      * process the appData Vobject d
28      * @param d
29      * @return true if appData should be collected
30      */
31     public boolean process(AppData d);
32   }
33   /**
34    * collect all appData reference strings in a vamsas document
35    * @param doc
36    * @return vector of String objects
37    */
38   static public Vector getAppDataReferences(VamsasDocument doc) {
39     if ((doc!=null) && (doc.getApplicationDataCount()>0)) {
40       Vector apdrefs = new Vector();
41       ApplicationData[] appdatas = doc.getApplicationData();
42       for (int q=0; q<appdatas.length; q++) {
43         String refstring=appdatas[q].getDataReference();
44         if (refstring!=null) 
45           apdrefs.add(refstring);
46         User users[] = appdatas[q].getUser();
47         
48         if (users!=null)
49           for (int u=0; u<users.length; u++) {
50             refstring=users[u].getDataReference();
51             if (refstring!=null)
52               apdrefs.add(new String(refstring)); // avoid referencing.
53           }
54       }
55       if (apdrefs.size()>0)
56         return apdrefs;
57     }
58     return null;
59   }
60   /**
61    * General search through the set of AppData objects for a particular profile of Client and User handle.
62    * @param doc
63    * @param test interface implemented by the filter selecting particular AppDatas.
64    * @param cascade if true only User objects for ApplicationData objects that test.process returned true will be tested.
65    * @return set of uk.ac.vamsas.objects.core.AppData objects for which test.process returned true
66    */
67   static public Vector searchAppDatas(VamsasDocument doc, IAppDSearch test, boolean cascade) {
68     if ((doc!=null) && (doc.getApplicationDataCount()>0)) {
69       Vector apdrefs = new Vector();
70       ApplicationData[] appdatas = doc.getApplicationData();
71       for (int q=0; q<appdatas.length; q++) {
72         boolean t;
73         if (t=test.process(appdatas[q])) 
74           apdrefs.add(appdatas[q]);
75         if (t || cascade) { 
76           User users[] = appdatas[q].getUser();
77           if (users!=null)
78             for (int u=0; u<users.length; u++) 
79               if (test.process(users[u]))
80                 apdrefs.add(users[u]);
81         }
82       }
83       if (apdrefs.size()>0)
84         return apdrefs;
85     }
86     return null;
87   }
88   static public boolean equals(User p, UserHandle u) {
89     if (p.getFullname().equals(u.getFullName())
90         && p.getOrganization().equals(u.getOrganization()))
91       return true;
92     return false;
93   }
94   /**
95    * returns true if Name matches in c and p, and Urn's match (or c.getUrn()==null) and Version's match (or c.getVersion()==null)
96    * @param p
97    * @param c
98    * @return match of p on template c.
99    */
100   static public boolean equals(ApplicationData p, ClientHandle c) {
101     if (
102         //((c.getClientUrn()==null) || p.getUrn().equals(c.getClientUrn()))
103         //&&
104         (p.getName().equals(c.getClientName()))
105         &&
106         ((c.getVersion()==null) || (p.getVersion().equals(c.getVersion())))
107         )
108       return true;
109     return false;
110   }
111   /**
112    * Searches document appData structure for particular combinations of client and user data
113    * @param doc the data 
114    * @param user template user data to match against
115    * @see AppDataReference.equals(uk.ac.vamsas.objects.core.User, uk.ac.vamsas.client.UserHandle)
116    * @param app
117    * @see AppDataReference.equals(uk.ac.vamsas.objects.core.ApplicationData, uk.ac.vamsas.client.ClientHandle)
118    * @return set of matching client app datas for this client and user combination
119    */
120   static public Vector getUserandApplicationsData(VamsasDocument doc, UserHandle user, ClientHandle app) {
121     if (doc==null) {
122       return null;
123     }
124     final UserHandle u = user;
125     final ClientHandle c = app;
126     
127     IAppDSearch match = new IAppDSearch() {
128       public boolean process(AppData p) {
129         if (p instanceof User) {
130           if (AppDataReference.equals((User) p, u))
131             return true;
132         } else 
133         if (p instanceof ApplicationData) {
134           if (AppDataReference.equals((ApplicationData) p, c))
135             return true;
136         }
137         return false;
138       }
139     };
140     
141     return searchAppDatas(doc, match, true); // only return AppDatas belonging to appdata app.
142   }
143   /**
144    * safely creates a new appData reference
145    * @param dest destination document Vobject
146    * @param entry base application reference to make unique 
147    */
148   public static String uniqueAppDataReference(VamsasDocument dest,String base) {
149     String urn = base.replace('/','.').replace('\\','.').replace(':', '_');
150     int v = 1;
151     for (int i=0, j=dest.getApplicationDataCount(); i<j; i++) {
152       ApplicationData o = dest.getApplicationData()[i];
153       // ensure new urn is really unique
154       while (o.getDataReference()!=null && o.getDataReference().equals(urn)) {
155         urn = base+"."+v++;      
156       } 
157     }
158     return urn;
159   }
160 }