Clover Coverage Report
Coverage timestamp: Sun Mar 23 2008 08:24:39 GMT
38   333   7   2.24
18   90   0.61   17
17     1.35  
1    
 
 
  URLHandler       Line # 55 38 7 76.7% 0.7671233
 
No Tests
 
1    /*
2    * Copyright (c) 2000-2005, University of Salford
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    *
8    * Redistributions of source code must retain the above copyright notice, this
9    * list of conditions and the following disclaimer.
10    *
11    * Redistributions in binary form must reproduce the above copyright notice,
12    * this list of conditions and the following disclaimer in the documentation
13    * and/or other materials provided with the distribution.
14    *
15    * Neither the name of the University of Salford nor the names of its
16    * contributors may be used to endorse or promote products derived from this
17    * software without specific prior written permission.
18    *
19    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22    * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29    * POSSIBILITY OF SUCH DAMAGE.
30    */
31   
32    package issrg.pba.rbac;
33   
34    import java.util.Map;
35    import java.util.Hashtable;
36    import java.security.Principal;
37    import issrg.utils.repository.Entry;
38    import issrg.pba.rbac.policies.Subtree;
39    import issrg.pba.rbac.policies.URLSubtree;
40    import issrg.utils.repository.FileRepository;
41    import issrg.utils.repository.RepositoryException;
42   
43    /**
44    * This class is a constructor of various URL-related instances:
45    * Subtrees (for domain matching), Principals and Entries (for domain matching).
46    * It also maintains a register of URL Handlers for other protocols, so that
47    * a relevant URL Handler can be found for a specific URL.
48    *
49    * <p>The instances of this class handle all URLs as if they were HTTP URLs.
50    * Subclass it and override the methods to handle URLs of other types.
51    *
52    * @author A.Otenko
53    * @version 1.0
54    */
 
55    public class URLHandler {
56   
57    public static final String HTTP_PROTOCOL = "http";
58    public static final String HTTPS_PROTOCOL = "https";
59    public static final String FILE_PROTOCOL = "file";
60   
61    public static final int HTTP_PORT = 80;
62    public static final int HTTPS_PORT = 443;
63   
64    /**
65    * This variable is here to allow emulation of file: URLs as HTTP URLs.
66    */
67    protected static final int FILE_PORT = 0;
68   
69    private static Map protocols = new Hashtable();
70   
 
71  11 toggle static{
72  11 addProtocol(new URLHandler(HTTP_PROTOCOL, HTTP_PORT));
73  11 addProtocol(new URLHandler(HTTPS_PROTOCOL, HTTPS_PORT));
74  11 addProtocol(new URLHandler(FILE_PROTOCOL, FILE_PORT));
75  11 addProtocol(new LDAPURLHandler());
76    }
77   
78    /**
79    * This method registers a new protocol URL handler, so if a URL
80    * for this protocol has to be parsed, the getPrincipal and getSubtree nodes
81    * will know who can handle such URLs.
82    *
83    * @param u the URLHandler that can handle URLs for a specific protocol
84    */
 
85  49 toggle public static void addProtocol(URLHandler u){
86  49 protocols.put(u.getProtocol().toLowerCase(), u);
87    }
88   
89    /**
90    * This method removes a protocol handler for a particular protocol name.
91    *
92    * @param protocol the protocol name for which handler has to be removed
93    */
 
94  0 toggle public static void removeProtocol(String protocol){
95  0 protocols.remove(protocol.toLowerCase());
96    }
97   
98    /**
99    * This method returns a handler for URLs for a given protocol.
100    *
101    * @param protocol the protocol to get the handler for
102    *
103    * @return the URLHandler object handling URLs for a given protocol; null, if no handler
104    * has been assigned
105    */
 
106  120 toggle public static URLHandler getURLHandler(String protocol){
107  0 if (protocol==null) return null;
108  120 return (URLHandler)protocols.get(protocol.toLowerCase());
109    }
110   
111    /**
112    * This method returns the protocol name, given a URL.
113    *
114    * @param url the URL to get the protocol name from
115    *
116    * @return the protocol name as it is in the URL
117    *
118    * @throws BadURLException if this is not a URL with a protocol string in it
119    */
 
120  257 toggle public static String getProtocolName(String url) throws BadURLException {
121  0 if (url==null) return null;
122   
123  257 int i = url.indexOf(":"); // find the position of the first colon character
124  257 if (i<0) throw new BadURLException("URL "+url+" does not have a protocol part");
125   
126  132 return url.substring(0, i);
127    }
128   
129    /**
130    * This method returns a Principal, created by corresponding URLHandler.
131    *
132    * <p>This is equivalent to getURLHandler(getProtocolName(url)).getPrincipal(url);
133    *
134    * @param url the URL as the Principal
135    *
136    * @return the Principal object, created by corresponding URLHandler; null, if no
137    * matching URLHandler has been found
138    *
139    * @throws BadURLException if the URL does not have a protocol part, or the
140    * URLHandler doesn't like it
141    */
 
142  3 toggle public static Principal getPrincipalByURL(String url) throws BadURLException {
143  3 URLHandler uh = getURLHandler(getProtocolName(url));
144   
145  3 return uh==null? null: uh.getPrincipal(url);
146    }
147   
148   
149    /**
150    * This method returns a Entry object, created by corresponding URLHandler.
151    *
152    * <p>This is equivalent to getURLHandler(getProtocolName(url)).getEntry(url);
153    *
154    * @param url the URL of the Entry
155    *
156    * @return the Entry object, created by corresponding URLHandler; null, if no
157    * matching URLHandler has been found
158    *
159    * @throws BadURLException if the URL does not have a protocol part, or the
160    * URLHandler doesn't like it
161    */
 
162  56 toggle public static Entry getEntryByURL(String url) throws BadURLException {
163   
164  56 URLHandler uh = getURLHandler(getProtocolName(url));
165  56 return uh==null? null: uh.getEntry(url);
166    }
167   
168    /**
169    * This method returns a Subtree object, created by corresponding URLHandler.
170    *
171    * <p>This is equivalent to getURLHandler(getProtocolName(url)).getSubtree(url, min, max);
172    *
173    * @param url the URL of the base Entry
174    * @param min the minimum number of levels below the base Entry where the
175    * matching entries can be located; pass 0, if no retriction is placed
176    * @param max the maximum number of levels below the base Entry where the
177    * matching entries can be located; pass -1 if no restriction is placed
178    * @param exclude the array of the subtrees specifying what entries to exclude
179    * from this subtree
180    *
181    * @return the Subtree object, created by corresponding URLHandler; null, if no
182    * matching URLHandler has been found
183    *
184    * @throws BadURLException if the URL does not have a protocol part, or the
185    * URLHandler doesn't like it
186    */
 
187  44 toggle public static Subtree getSubtreeByURL(String url, int min, int max, Subtree [] exclude) throws BadURLException {
188  44 URLHandler uh = getURLHandler(getProtocolName(url));
189  44 return uh==null? null: uh.getSubtree(url, min, max, exclude);
190    }
191   
192    /**
193    * This method will find a URLHandler for the protocol and create the
194    * AttributeRepository that will provide access to that repository.
195    *
196    * <p>Same as URLHandler.getURLHandler(URLHandler.getProtocolName(url)).getRepository(url);
197    *
198    * @param url - the URL of the repository
199    *
200    * @return AttributeRepository pointed to by the URL, or null, if no repository
201    * could be created (e.g. no URLHandler could be found)
202    *
203    * @throws BadURLException if the URL is malformed
204    */
 
205  7 toggle public static issrg.utils.repository.AttributeRepository getRepositoryByURL(String url) throws BadURLException {
206    //System.err.println("getting a repository for "+url);//***************
207  7 URLHandler uh = getURLHandler(getProtocolName(url));
208  7 return uh==null? null: uh.getRepository(url);
209    }
210   
 
211  13 toggle protected URLHandler(){}
212   
213    protected String protocol;
214    protected int defaultPort;
215   
216    /**
217    * This constructor builds an instance of URLHandler that will be able to
218    * handle
219    * URLs of given protocol, and listening on given default port.
220    *
221    * @param protocol the string name of the protocol (without trailing ":");
222    * case of characters is ignored
223    * @param defaultPort the number of the default port the protocol listens on
224    */
 
225  36 toggle public URLHandler(String protocol, int defaultPort){
226  36 this.protocol=protocol.toLowerCase();
227  36 this.defaultPort=defaultPort;
228    }
229   
230    /**
231    * This method returns the string name of the protocol (without the trailing
232    * colon).
233    * The protocol is in lowercase letters.
234    *
235    * @return string name of the protocol in lowercase characters
236    */
 
237  33 toggle public String getProtocol(){
238  33 return protocol;
239    }
240   
241    /**
242    * This method returns the number of the defaul port that the protocol listens
243    * on
244    *
245    * @return integer number of the port on which the protocol listens by default
246    */
 
247  0 toggle public int getDefaultPort(){
248  0 return defaultPort;
249    }
250   
251    /**
252    * This method returns a Principal for a given HTTP URL string.
253    * It checks if the passed URL string matches the protocol this Handler is
254    * registered for.
255    *
256    * @param url the string representation of the HTTP URL (including the
257    * protocol name part)
258    * (the actual protocol name is checked with the string returned by
259    * getProtocol,
260    * but the format of the rest of the URL is as specified in HTTP RFC)
261    *
262    * @return Principal of the corresponding URL
263    *
264    * @throws BadURLException if the URL is malformed
265    */
 
266  57 toggle public Principal getPrincipal(String url) throws BadURLException {
267  57 URLPrincipal upi=new URLPrincipal(url, defaultPort);
268   
269  57 if (!upi.getProtocol().equals(protocol)){
270  0 throw new BadURLException("Wrong URL parser: "+upi.getProtocol()+": found, "+protocol+": expected");
271    }
272   
273  57 return upi;
274    }
275   
276    /**
277    * This method returns an Entry identified by a given HTTP URL.
278    *
279    * <p>This URLHandler does (Entry)getPrincipal(url) - so if your Principal
280    * implements the Entry interface, you can leave the getEntry method.
281    *
282    * @param url the string representation of the HTTP URL (see comments for
283    * getPrincipal method)
284    *
285    * @return Entry identified by the URL
286    *
287    * @throws BadURLException if the URL is malformed
288    */
 
289  56 toggle public Entry getEntry(String url) throws BadURLException {
290  56 return (Entry)getPrincipal(url); // invoke the same method, so it will do the same checks
291    }
292   
293    /**
294    * This method returns a Subtree specified using a Base Entry URL and Min
295    * and Max level
296    * specifications.
297    *
298    * @param url the URL of the Base Entry; port may be specified as a range of
299    * ports by using nn-mm notation (two numbers separated by hyphen);
300    * if no port is specified, any port matches the subtree specification
301    * @param min the Min value for the subtree
302    * @param max the Max value for the subtree
303    *
304    * @see issrg.pba.rbac.policies.Subtree
305    *
306    * @throws BadURLException if the URL is malformed
307    */
 
308  44 toggle public Subtree getSubtree(String url, int min, int max, Subtree [] exclude) throws BadURLException {
309  44 return new URLSubtree(url, defaultPort, min, max, exclude);
310    }
311   
312    /**
313    * This method returns an instance of a repository that would be able to
314    * retrieve attributes given the URL. Some Repositories may use only the
315    * host part of the URL to connect to the server, ignoring the path part.
316    *
317    * <p>In this version of the URLHandler, no HTTP/HTTPS repositories are
318    * implemented, so null is returned for such URLs.
319    *
320    * @param url - the URL of the repository
321    *
322    * @return the AttributeRepository
323    */
 
324  6 toggle public issrg.utils.repository.AttributeRepository getRepository(String url) throws BadURLException {
325  0 if (!protocol.equals(FILE_PROTOCOL)) return null;
326   
327  6 try{
328  6 return new FileRepository(url);
329    }catch (RepositoryException re){
330  0 throw new BadURLException("File Repository could not be connected: "+url, re);
331    }
332    }
333    }