2 * Copyright (c) 2001-2007 Sun Microsystems, Inc. All rights reserved.
4 * The Sun Project JXTA(TM) Software License
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
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.
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.
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.
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.
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.
41 * JXTA is a registered trademark of Sun Microsystems, Inc. in the United
42 * States and other countries.
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.
48 * ====================================================================
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.
54 * This license is based on the BSD license adopted by the Apache Foundation.
57 package net.jxta.impl.access;
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;
76 import java.io.FileInputStream;
77 import java.io.IOException;
78 import java.io.InputStream;
79 import java.lang.reflect.UndeclaredThrowableException;
81 import java.net.URISyntaxException;
83 import java.net.URLConnection;
84 import java.util.Enumeration;
85 import java.util.HashMap;
90 * Manages Access Permissions.
92 public class AccessList {
97 private final static transient Logger LOG = Logger.getLogger(AccessList.class.getName());
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";
107 protected final Map<ID, Entry> accessMap = new HashMap<ID, Entry>();
109 String description = null;
110 boolean grantAll = false;
113 * Default Constructor
115 public AccessList() {}
118 * Initialize access list from an InputStream
120 * @param stream the input stream
121 * @throws java.io.IOException if an io error occurs
123 public AccessList(InputStream stream) throws IOException {
128 * Initialize access list from a URI
130 * e.g. file:/export/dist/acl.xml, e.g. http://configserver.net/edge.acl
132 * @param uri the URI to the access control list
133 * @throws IOException if an i/o error occurs
135 public AccessList(URI uri) throws IOException {
140 * Initialize the access list from a URI
142 * @param uri the refresh URI
143 * @throws IOException if an io error occurs
145 public void init(URI uri) throws IOException {
146 InputStream input = getInputStream(uri);
153 * Initialize access list from a file
155 * @param fromFile file to init from
156 * @throws IOException if an io error occurs
158 public void init(File fromFile) throws IOException {
159 InputStream is = new FileInputStream(fromFile);
166 * Refresh access list from a file
168 * @param file file to refresh from
169 * @deprecated use URI variant
172 public void refresh(File file) {
175 InputStream is = new FileInputStream(file);
179 } catch (IOException io) {// bad input
185 * refresh the access list from a stream
187 * @param stream the input stream
188 * @throws IOException if an io error occurs
190 public void refresh(InputStream stream) throws IOException {
191 AccessList tmp = new AccessList(stream);
197 * refresh the access list from a URI
199 * @param uri the refresh URI
200 * @throws IOException if an io error occurs
202 public void refresh(URI uri) throws IOException {
203 InputStream input = getInputStream(uri);
204 AccessList tmp = new AccessList(input);
210 private InputStream getInputStream(URI uri) throws IOException {
211 if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
212 LOG.fine("Loading ACL : " + uri.toString());
215 URL url = uri.toURL();
217 URLConnection connection = url.openConnection();
219 connection.setDoInput(true);
220 return connection.getInputStream();
223 private void init(InputStream stream) throws IOException {
224 XMLDocument doc = (XMLDocument) StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XMLUTF8, stream);
230 * @param map The map of addresses and permissions.
232 public AccessList(Map<ID, Entry> map) {
233 this.accessMap.clear();
234 this.accessMap.putAll(map);
238 * Construct from a StructuredDocument
240 * @param root root element
242 public AccessList(Element root) {
243 if (!(root instanceof XMLElement)) {
244 throw new IllegalArgumentException(getClass().getName() + " only supports XLMElement");
247 XMLElement doc = (XMLElement) root;
249 if (!getAdvertisementType().equals(doc.getName())) {
250 throw new IllegalArgumentException(
251 "Could not construct : " + getClass().getName() + "from doc containing a " + doc.getName());
258 * gets the description of this access control
260 * @return the document description
262 public String getDescrption() {
267 * Determine if all access is granted.
269 * @return If {@code true} then all access requests will be granted.
271 public boolean getGrantAll() {
276 * Allows/denies all access
278 * @param grantAll If {@code true} then all access requests will be granted.
280 public void setGrantAll(boolean grantAll) {
281 this.grantAll = grantAll;
285 * sets the ACL description
287 * @param description The new description
289 public void setDescrption(String description) {
290 this.description = description;
294 * sets the entries list
296 * @param map The new access map
298 protected void setEntries(Map<ID, Entry> map) {
300 accessMap.putAll(map);
304 * Refreshes the access list
306 * @param acl The access list to refresh from
308 private void refresh(AccessList acl) {
309 grantAll = acl.grantAll;
310 description = acl.description;
312 accessMap.putAll(acl.accessMap);
318 * @param entry the entry to add
320 public void add(Entry entry) {
321 if (!accessMap.containsKey(entry.id)) {
322 accessMap.put(entry.id, entry);
327 * Removes an ACL entry
329 * @param entry the entry to remove
331 public void remove(Entry entry) {
332 if (accessMap.containsKey(entry.id)) {
333 accessMap.remove(entry.id);
338 * Determines if an entry has access
340 * @param id the PeerID
341 * @return ture if access is allowed, always true if grantAll is set
343 public boolean isAllowed(ID id) {
346 } else if (accessMap.containsKey(id)) {
347 Entry entry = accessMap.get(id);
356 * gets the entries list
358 * @return List The List containing Entries
360 public Map<ID, Entry> getAccessMap() {
365 * Returns the Document
367 * @param asMimeType mime type encoding
368 * @return The document value
370 public Document getDocument(MimeMediaType asMimeType) {
371 StructuredDocument adv = StructuredDocumentFactory.newStructuredDocument(asMimeType, getAdvertisementType());
373 if (adv instanceof XMLDocument) {
374 ((XMLDocument) adv).addAttribute("xmlns:jxta", "http://jxta.org");
380 e = adv.createElement(GRANTALL_TAG, Boolean.valueOf(grantAll).toString());
384 if (description != null) {
385 e = adv.createElement(DESCRIPTION_TAG, description);
389 for (Object o : accessMap.values()) {
390 Entry entry = (Entry) o;
392 if (entry.id == null && entry.name == null) {
396 e = adv.createElement(PEER_TAG, entry.id.toString());
398 ((Attributable) e).addAttribute(NAME_TAG, entry.name);
400 ((Attributable) e).addAttribute(ACCESS_TAG, ACCESS_TAG_GRANT_VALUE);
402 ((Attributable) e).addAttribute(ACCESS_TAG, ACCESS_TAG_DENY_VALUE);
409 * Process an individual element from the document.
411 * @param doc the element
413 protected void initialize(XMLElement doc) {
415 Enumeration elements = doc.getChildren();
417 while (elements.hasMoreElements()) {
418 XMLElement elem = (XMLElement) elements.nextElement();
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 + " ]");
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 :");
438 if (PEER_TAG.equals(elem.getName())) {
440 Attribute nameAttr = elem.getAttribute(NAME_TAG);
442 if (nameAttr != null) {
443 name = nameAttr.getValue();
445 String access = ACCESS_TAG_GRANT_VALUE;
446 Attribute accessAttr = elem.getAttribute(ACCESS_TAG);
448 if (accessAttr != null) {
449 access = accessAttr.getValue();
451 boolean acl = ACCESS_TAG_GRANT_VALUE.equalsIgnoreCase(access);
456 URI id = new URI(elem.getTextValue().trim());
458 pid = IDFactory.fromURI(id);
459 } catch (URISyntaxException badID) {
460 throw new IllegalArgumentException("unknown ID format in advertisement: " + elem.getTextValue());
463 Entry entry = new Entry(pid, name, acl);
465 if (Logging.SHOW_CONFIG && LOG.isLoggable(Level.CONFIG)) {
466 LOG.config("Adding entry to access list :" + entry);
469 accessMap.put(entry.id, entry);
474 if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) {
475 LOG.warning("Unrecognized tag : " + elem.getName());
481 * returns the document string representation of this object
483 * @return String representation of the of this message type
486 public String toString() {
489 XMLDocument doc = (XMLDocument) getDocument(MimeMediaType.XMLUTF8);
491 return doc.toString();
492 } catch (Throwable e) {
493 if (e instanceof Error) {
495 } else if (e instanceof RuntimeException) {
496 throw (RuntimeException) e;
498 throw new UndeclaredThrowableException(e);
504 * All messages have a type (in xml this is !doctype) which
505 * identifies the message
507 * @return String "jxta:XACL"
509 public static String getAdvertisementType() {
516 public final static class Entry {
526 public final String name;
531 public final boolean access;
534 * Creates a Entry with id and name
537 * @param name node name
538 * @param access access control
541 public Entry(ID id, String name, boolean access) {
544 this.access = access;
548 public String toString() {
549 return "[" + name + " access = " + access + " : " + id.toString() + "]";
553 public boolean equals(Object obj) {
554 return this == obj || (obj != null && id.equals(((Entry) obj).id));
558 public int hashCode() {
559 return id.hashCode();