]> sjero.net Git - linphone/blob - p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/access/AccessList.java
2ffec1b6410b6d41afae62850c4c62a978f58988
[linphone] / p2pproxy / dependencies-src / jxse-src-2.5 / impl / src / net / jxta / impl / access / AccessList.java
1 /*
2  * Copyright (c) 2001-2007 Sun Microsystems, Inc.  All rights reserved.
3  *  
4  *  The Sun Project JXTA(TM) Software License
5  *  
6  *  Redistribution and use in source and binary forms, with or without 
7  *  modification, are permitted provided that the following conditions are met:
8  *  
9  *  1. Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *  
12  *  2. Redistributions in binary form must reproduce the above copyright notice, 
13  *     this list of conditions and the following disclaimer in the documentation 
14  *     and/or other materials provided with the distribution.
15  *  
16  *  3. The end-user documentation included with the redistribution, if any, must 
17  *     include the following acknowledgment: "This product includes software 
18  *     developed by Sun Microsystems, Inc. for JXTA(TM) technology." 
19  *     Alternately, this acknowledgment may appear in the software itself, if 
20  *     and wherever such third-party acknowledgments normally appear.
21  *  
22  *  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must 
23  *     not be used to endorse or promote products derived from this software 
24  *     without prior written permission. For written permission, please contact 
25  *     Project JXTA at http://www.jxta.org.
26  *  
27  *  5. Products derived from this software may not be called "JXTA", nor may 
28  *     "JXTA" appear in their name, without prior written permission of Sun.
29  *  
30  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
31  *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
32  *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN 
33  *  MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
34  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
35  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
36  *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
37  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
38  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
39  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *  
41  *  JXTA is a registered trademark of Sun Microsystems, Inc. in the United 
42  *  States and other countries.
43  *  
44  *  Please see the license information page at :
45  *  <http://www.jxta.org/project/www/license.html> for instructions on use of 
46  *  the license in source files.
47  *  
48  *  ====================================================================
49  *  
50  *  This software consists of voluntary contributions made by many individuals 
51  *  on behalf of Project JXTA. For more information on Project JXTA, please see 
52  *  http://www.jxta.org.
53  *  
54  *  This license is based on the BSD license adopted by the Apache Foundation. 
55  */
56
57 package net.jxta.impl.access;
58
59
60 import net.jxta.document.Attributable;
61 import net.jxta.document.Attribute;
62 import net.jxta.document.Document;
63 import net.jxta.document.Element;
64 import net.jxta.document.MimeMediaType;
65 import net.jxta.document.StructuredDocument;
66 import net.jxta.document.StructuredDocumentFactory;
67 import net.jxta.document.XMLElement;
68 import net.jxta.document.XMLDocument;
69 import net.jxta.id.ID;
70 import net.jxta.id.IDFactory;
71 import java.util.logging.Level;
72 import net.jxta.logging.Logging;
73 import java.util.logging.Logger;
74
75 import java.io.File;
76 import java.io.FileInputStream;
77 import java.io.IOException;
78 import java.io.InputStream;
79 import java.lang.reflect.UndeclaredThrowableException;
80 import java.net.URI;
81 import java.net.URISyntaxException;
82 import java.net.URL;
83 import java.net.URLConnection;
84 import java.util.Enumeration;
85 import java.util.HashMap;
86 import java.util.Map;
87
88
89 /**
90  * Manages Access Permissions.
91  */
92 public class AccessList {
93     
94     /**
95      * Logger
96      */
97     private final static transient Logger LOG = Logger.getLogger(AccessList.class.getName());
98
99     private final static String PEER_TAG = "peer";
100     private final static String NAME_TAG = "name";
101     private final static String DESCRIPTION_TAG = "description";
102     private final static String GRANTALL_TAG = "grantAll";
103     private final static String ACCESS_TAG = "access";
104     private final static String ACCESS_TAG_DENY_VALUE = "deny";
105     private final static String ACCESS_TAG_GRANT_VALUE = "grant";
106     
107     protected final Map<ID, Entry> accessMap = new HashMap<ID, Entry>();
108     
109     String description = null;
110     boolean grantAll = false;
111     
112     /**
113      * Default Constructor
114      */
115     public AccessList() {}
116
117     /**
118      * Initialize access list from an InputStream
119      *
120      * @param stream the input stream
121      * @throws java.io.IOException if an io error occurs
122      */
123     public AccessList(InputStream stream) throws IOException {
124         init(stream);
125     }
126
127     /**
128      * Initialize access list from a URI
129      * <p/>
130      * e.g. file:/export/dist/acl.xml, e.g. http://configserver.net/edge.acl
131      *
132      * @param uri the URI to the access control list
133      * @throws IOException if an i/o error occurs
134      */
135     public AccessList(URI uri) throws IOException {
136         init(uri);
137     }
138
139     /**
140      * Initialize the access list from a URI
141      *
142      * @param uri the refresh URI
143      * @throws IOException if an io error occurs
144      */
145     public void init(URI uri) throws IOException {
146         InputStream input = getInputStream(uri);
147
148         init(input);
149         input.close();
150     }
151
152     /**
153      * Initialize access list from a file
154      *
155      * @param fromFile file to init from
156      * @throws IOException if an io error occurs
157      */
158     public void init(File fromFile) throws IOException {
159         InputStream is = new FileInputStream(fromFile);
160
161         init(is);
162         is.close();
163     }
164
165     /**
166      * Refresh access list from a file
167      *
168      * @param file file to refresh from
169      * @deprecated use URI variant
170      */
171     @Deprecated
172     public void refresh(File file) {
173         if (file.exists()) {
174             try {
175                 InputStream is = new FileInputStream(file);
176
177                 refresh(is);
178                 is.close();
179             } catch (IOException io) {// bad input
180             }
181         }
182     }
183
184     /**
185      * refresh the access list from a stream
186      *
187      * @param stream the input stream
188      * @throws IOException if an io error occurs
189      */
190     public void refresh(InputStream stream) throws IOException {
191         AccessList tmp = new AccessList(stream);
192
193         refresh(tmp);
194     }
195
196     /**
197      * refresh the access list from a URI
198      *
199      * @param uri the refresh URI
200      * @throws IOException if an io error occurs
201      */
202     public void refresh(URI uri) throws IOException {
203         InputStream input = getInputStream(uri);
204         AccessList tmp = new AccessList(input);
205
206         refresh(tmp);
207         input.close();
208     }
209
210     private InputStream getInputStream(URI uri) throws IOException {
211         if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
212             LOG.fine("Loading ACL : " + uri.toString());
213         }
214
215         URL url = uri.toURL();
216
217         URLConnection connection = url.openConnection();
218
219         connection.setDoInput(true);
220         return connection.getInputStream();
221     }
222
223     private void init(InputStream stream) throws IOException {
224         XMLDocument doc = (XMLDocument) StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XMLUTF8, stream);
225         
226         initialize(doc);
227     }
228
229     /**
230      * @param map The map of addresses and permissions.
231      */
232     public AccessList(Map<ID, Entry> map) {
233         this.accessMap.clear();
234         this.accessMap.putAll(map);
235     }
236
237     /**
238      * Construct from a StructuredDocument
239      *
240      * @param root root element
241      */
242     public AccessList(Element root) {
243         if (!(root instanceof XMLElement)) {
244             throw new IllegalArgumentException(getClass().getName() + " only supports XLMElement");
245         }
246
247         XMLElement doc = (XMLElement) root;
248
249         if (!getAdvertisementType().equals(doc.getName())) {
250             throw new IllegalArgumentException(
251                     "Could not construct : " + getClass().getName() + "from doc containing a " + doc.getName());
252         }
253         
254         initialize(doc);
255     }
256
257     /**
258      * gets the description of this access control
259      *
260      * @return the document description
261      */
262     public String getDescrption() {
263         return description;
264     }
265
266     /**
267      * Determine if all access is granted.
268      *
269      * @return If {@code true} then all access requests will be granted.
270      */
271     public boolean getGrantAll() {
272         return grantAll;
273     }
274
275     /**
276      * Allows/denies all access
277      *
278      * @param grantAll If {@code true} then all access requests will be granted.
279      */
280     public void setGrantAll(boolean grantAll) {
281         this.grantAll = grantAll;
282     }
283
284     /**
285      * sets the ACL description
286      *
287      * @param description The new description
288      */
289     public void setDescrption(String description) {
290         this.description = description;
291     }
292
293     /**
294      * sets the entries list
295      *
296      * @param map The new access map
297      */
298     protected void setEntries(Map<ID, Entry> map) {
299         accessMap.clear();
300         accessMap.putAll(map);
301     }
302
303     /**
304      * Refreshes the access list
305      *
306      * @param acl The access list to refresh from
307      */
308     private void refresh(AccessList acl) {
309         grantAll = acl.grantAll;
310         description = acl.description;
311         accessMap.clear();
312         accessMap.putAll(acl.accessMap);
313     }
314
315     /**
316      * Adds an ACL entry
317      *
318      * @param entry the entry to add
319      */
320     public void add(Entry entry) {
321         if (!accessMap.containsKey(entry.id)) {
322             accessMap.put(entry.id, entry);
323         }
324     }
325
326     /**
327      * Removes an ACL entry
328      *
329      * @param entry the entry to remove
330      */
331     public void remove(Entry entry) {
332         if (accessMap.containsKey(entry.id)) {
333             accessMap.remove(entry.id);
334         }
335     }
336
337     /**
338      * Determines if an entry has access
339      * 
340      * @param id the PeerID
341      * @return ture if access is allowed, always true if grantAll is set
342      */
343     public boolean isAllowed(ID id) {
344         if (grantAll) {
345             return true;
346         } else if (accessMap.containsKey(id)) {
347             Entry entry = accessMap.get(id);
348
349             return entry.access;
350         } else {
351             return false;
352         }
353     }
354
355     /**
356      * gets the entries list
357      *
358      * @return List The List containing Entries
359      */
360     public Map<ID, Entry> getAccessMap() {
361         return accessMap;
362     }
363
364     /**
365      * Returns the Document
366      *
367      * @param asMimeType mime type encoding
368      * @return The document value
369      */
370     public Document getDocument(MimeMediaType asMimeType) {
371         StructuredDocument adv = StructuredDocumentFactory.newStructuredDocument(asMimeType, getAdvertisementType());
372
373         if (adv instanceof XMLDocument) {
374             ((XMLDocument) adv).addAttribute("xmlns:jxta", "http://jxta.org");
375         }
376
377         Element e;
378
379         if (grantAll) {
380             e = adv.createElement(GRANTALL_TAG, Boolean.valueOf(grantAll).toString());
381             adv.appendChild(e);
382         }
383         
384         if (description != null) {
385             e = adv.createElement(DESCRIPTION_TAG, description);
386             adv.appendChild(e);
387         }
388         
389         for (Object o : accessMap.values()) {
390             Entry entry = (Entry) o;
391
392             if (entry.id == null && entry.name == null) {
393                 // skip bad entries
394                 continue;
395             }
396             e = adv.createElement(PEER_TAG, entry.id.toString());
397             adv.appendChild(e);
398             ((Attributable) e).addAttribute(NAME_TAG, entry.name);
399             if (entry.access) {
400                 ((Attributable) e).addAttribute(ACCESS_TAG, ACCESS_TAG_GRANT_VALUE);
401             } else {
402                 ((Attributable) e).addAttribute(ACCESS_TAG, ACCESS_TAG_DENY_VALUE);
403             }
404         }
405         return adv;
406     }
407
408     /**
409      * Process an individual element from the document.
410      *
411      * @param doc the element
412      */
413     protected void initialize(XMLElement doc) {
414
415         Enumeration elements = doc.getChildren();
416
417         while (elements.hasMoreElements()) {
418             XMLElement elem = (XMLElement) elements.nextElement();
419             
420             if (GRANTALL_TAG.equals(elem.getName())) {
421                 grantAll = Boolean.getBoolean(elem.getTextValue());
422                 if (Logging.SHOW_CONFIG && LOG.isLoggable(Level.CONFIG)) {
423                     LOG.config("Grant all access = [ " + grantAll + " ]");
424                 }
425
426                 continue;
427             }
428             
429             if (DESCRIPTION_TAG.equals(elem.getName())) {
430                 description = elem.getTextValue();
431                 if (Logging.SHOW_CONFIG && LOG.isLoggable(Level.CONFIG)) {
432                     LOG.config("Loading [ " + description + " ] access list :");
433                 }
434                 
435                 continue;
436             }
437             
438             if (PEER_TAG.equals(elem.getName())) {
439                 String name = "NA";
440                 Attribute nameAttr = elem.getAttribute(NAME_TAG);
441
442                 if (nameAttr != null) {
443                     name = nameAttr.getValue();
444                 }
445                 String access = ACCESS_TAG_GRANT_VALUE;
446                 Attribute accessAttr = elem.getAttribute(ACCESS_TAG);
447
448                 if (accessAttr != null) {
449                     access = accessAttr.getValue();
450                 }
451                 boolean acl = ACCESS_TAG_GRANT_VALUE.equalsIgnoreCase(access);
452                 
453                 ID pid;
454
455                 try {
456                     URI id = new URI(elem.getTextValue().trim());
457
458                     pid = IDFactory.fromURI(id);
459                 } catch (URISyntaxException badID) {
460                     throw new IllegalArgumentException("unknown ID format in advertisement: " + elem.getTextValue());
461                 }
462                 
463                 Entry entry = new Entry(pid, name, acl);
464
465                 if (Logging.SHOW_CONFIG && LOG.isLoggable(Level.CONFIG)) {
466                     LOG.config("Adding entry to access list :" + entry);
467                 }
468                 
469                 accessMap.put(entry.id, entry);
470                 
471                 continue;
472             }
473             
474             if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) {
475                 LOG.warning("Unrecognized tag : " + elem.getName());
476             }            
477         }
478     }
479
480     /**
481      * returns the document string representation of this object
482      *
483      * @return String representation of the of this message type
484      */
485     @Override
486     public String toString() {
487
488         try {
489             XMLDocument doc = (XMLDocument) getDocument(MimeMediaType.XMLUTF8);
490
491             return doc.toString();
492         } catch (Throwable e) {
493             if (e instanceof Error) {
494                 throw (Error) e;
495             } else if (e instanceof RuntimeException) {
496                 throw (RuntimeException) e;
497             } else {
498                 throw new UndeclaredThrowableException(e);
499             }
500         }
501     }
502
503     /**
504      * All messages have a type (in xml this is &#0033;doctype) which
505      * identifies the message
506      *
507      * @return String "jxta:XACL"
508      */
509     public static String getAdvertisementType() {
510         return "jxta:XACL";
511     }
512
513     /**
514      * Entries class
515      */
516     public final static class Entry {
517
518         /**
519          * Entry ID entry id
520          */
521         public final ID id;
522
523         /**
524          * Entry name
525          */
526         public final String name;
527
528         /**
529          * Entry name
530          */
531         public final boolean access;
532
533         /**
534          * Creates a Entry with id and name
535          *
536          * @param id     id
537          * @param name   node name
538          * @param access access control
539          */
540
541         public Entry(ID id, String name, boolean access) {
542             this.id = id;
543             this.name = name;
544             this.access = access;
545         }
546
547         @Override
548         public String toString() {
549             return "[" + name + "  access = " + access + " : " + id.toString() + "]";
550         }
551
552         @Override
553         public boolean equals(Object obj) {
554             return this == obj || (obj != null && id.equals(((Entry) obj).id));
555         }
556
557         @Override
558         public int hashCode() {
559             return id.hashCode();
560         }
561     }
562 }
563