You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tb...@apache.org on 2006/12/12 16:24:14 UTC

svn commit: r486187 [10/49] - in /directory/trunks/triplesec: ./ admin-api/ admin-api/src/ admin-api/src/main/ admin-api/src/main/java/ admin-api/src/main/java/org/ admin-api/src/main/java/org/safehaus/ admin-api/src/main/java/org/safehaus/triplesec/ a...

Added: directory/trunks/triplesec/crypto/src/main/java/org/safehaus/crypto/RuntimeCryptoException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/crypto/src/main/java/org/safehaus/crypto/RuntimeCryptoException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/crypto/src/main/java/org/safehaus/crypto/RuntimeCryptoException.java (added)
+++ directory/trunks/triplesec/crypto/src/main/java/org/safehaus/crypto/RuntimeCryptoException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,46 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.crypto;
+
+/**
+ * the foundation class for the exceptions thrown by the crypto packages.
+ */
+public class RuntimeCryptoException extends RuntimeException
+{
+	private static final long serialVersionUID = -8255171711596508358L;
+
+	/**
+     * base constructor.
+     */
+    public RuntimeCryptoException()
+    {
+    }
+
+    /**
+     * create a RuntimeCryptoException with the given message.
+     *
+     * @param message the message to be carried with the exception.
+     */
+    public RuntimeCryptoException(
+        String  message)
+    {
+        super(message);
+    }
+}

Added: directory/trunks/triplesec/crypto/src/main/java/org/safehaus/crypto/SHA1Digest.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/crypto/src/main/java/org/safehaus/crypto/SHA1Digest.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/crypto/src/main/java/org/safehaus/crypto/SHA1Digest.java (added)
+++ directory/trunks/triplesec/crypto/src/main/java/org/safehaus/crypto/SHA1Digest.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,277 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.crypto;
+
+
+/**
+ * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
+ *
+ * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
+ * is the "endienness" of the word processing!
+ */
+public class SHA1Digest
+    extends GeneralDigest
+{
+    private static final int    DIGEST_LENGTH = 20;
+
+    private int     H1, H2, H3, H4, H5;
+
+    private int[]   X = new int[80];
+    private int     xOff;
+
+    /**
+     * Standard constructor
+     */
+    public SHA1Digest()
+    {
+        reset();
+    }
+
+    /**
+     * Copy constructor.  This will copy the state of the provided
+     * message digest.
+     */
+    public SHA1Digest(SHA1Digest t)
+    {
+        super(t);
+
+        H1 = t.H1;
+        H2 = t.H2;
+        H3 = t.H3;
+        H4 = t.H4;
+        H5 = t.H5;
+
+        System.arraycopy(t.X, 0, X, 0, t.X.length);
+        xOff = t.xOff;
+    }
+
+    public String getAlgorithmName()
+    {
+        return "SHA-1";
+    }
+
+    public int getDigestSize()
+    {
+        return DIGEST_LENGTH;
+    }
+
+    protected void processWord(
+        byte[]  in,
+        int     inOff)
+    {
+        X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16)
+                    | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff)); 
+
+        if (xOff == 16)
+        {
+            processBlock();
+        }
+    }
+
+    private void unpackWord(
+        int     word,
+        byte[]  out,
+        int     outOff)
+    {
+        out[outOff]     = (byte)(word >>> 24);
+        out[outOff + 1] = (byte)(word >>> 16);
+        out[outOff + 2] = (byte)(word >>> 8);
+        out[outOff + 3] = (byte)word;
+    }
+
+    protected void processLength(
+        long    bitLength)
+    {
+        if (xOff > 14)
+        {
+            processBlock();
+        }
+
+        X[14] = (int)(bitLength >>> 32);
+        X[15] = (int)(bitLength & 0xffffffff);
+    }
+
+    public int doFinal(
+        byte[]  out,
+        int     outOff)
+    {
+        finish();
+
+        unpackWord(H1, out, outOff);
+        unpackWord(H2, out, outOff + 4);
+        unpackWord(H3, out, outOff + 8);
+        unpackWord(H4, out, outOff + 12);
+        unpackWord(H5, out, outOff + 16);
+
+        reset();
+
+        return DIGEST_LENGTH;
+    }
+
+    /**
+     * reset the chaining variables
+     */
+    public void reset()
+    {
+        super.reset();
+
+        H1 = 0x67452301;
+        H2 = 0xefcdab89;
+        H3 = 0x98badcfe;
+        H4 = 0x10325476;
+        H5 = 0xc3d2e1f0;
+
+        xOff = 0;
+        for (int i = 0; i != X.length; i++)
+        {
+            X[i] = 0;
+        }
+    }
+
+    //
+    // Additive constants
+    //
+    private static final int    Y1 = 0x5a827999;
+    private static final int    Y2 = 0x6ed9eba1;
+    private static final int    Y3 = 0x8f1bbcdc;
+    private static final int    Y4 = 0xca62c1d6;
+
+    private int f(
+        int    u,
+        int    v,
+        int    w)
+    {
+        return ((u & v) | ((~u) & w));
+    }
+
+    private int h(
+        int    u,
+        int    v,
+        int    w)
+    {
+        return (u ^ v ^ w);
+    }
+
+    private int g(
+        int    u,
+        int    v,
+        int    w)
+    {
+        return ((u & v) | (u & w) | (v & w));
+    }
+
+    private int rotateLeft(
+        int    x,
+        int    n)
+    {
+        return (x << n) | (x >>> (32 - n));
+    }
+
+    protected void processBlock()
+    {
+        //
+        // expand 16 word block into 80 word block.
+        //
+        for (int i = 16; i <= 79; i++)
+        {
+            X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
+        }
+
+        //
+        // set up working variables.
+        //
+        int     A = H1;
+        int     B = H2;
+        int     C = H3;
+        int     D = H4;
+        int     E = H5;
+
+        //
+        // round 1
+        //
+        for (int j = 0; j <= 19; j++)
+        {
+            int     t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1;
+
+            E = D;
+            D = C;
+            C = rotateLeft(B, 30);
+            B = A;
+            A = t;
+        }
+
+        //
+        // round 2
+        //
+        for (int j = 20; j <= 39; j++)
+        {
+            int     t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2;
+
+            E = D;
+            D = C;
+            C = rotateLeft(B, 30);
+            B = A;
+            A = t;
+        }
+
+        //
+        // round 3
+        //
+        for (int j = 40; j <= 59; j++)
+        {
+            int     t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3;
+
+            E = D;
+            D = C;
+            C = rotateLeft(B, 30);
+            B = A;
+            A = t;
+        }
+
+        //
+        // round 4
+        //
+        for (int j = 60; j <= 79; j++)
+        {
+            int     t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4;
+
+            E = D;
+            D = C;
+            C = rotateLeft(B, 30);
+            B = A;
+            A = t;
+        }
+
+        H1 += A;
+        H2 += B;
+        H3 += C;
+        H4 += D;
+        H5 += E;
+
+        //
+        // reset the offset and clean out the word buffer.
+        //
+        xOff = 0;
+        for (int i = 0; i != X.length; i++)
+        {
+            X[i] = 0;
+        }
+    }
+}

Added: directory/trunks/triplesec/crypto/src/test/org/safehaus/crypto/BlockCipherWrapperTest.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/crypto/src/test/org/safehaus/crypto/BlockCipherWrapperTest.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/crypto/src/test/org/safehaus/crypto/BlockCipherWrapperTest.java (added)
+++ directory/trunks/triplesec/crypto/src/test/org/safehaus/crypto/BlockCipherWrapperTest.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,42 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.crypto;
+
+
+import junit.framework.TestCase;
+
+
+/**
+ * Simple test for the BlockCipherWrapper.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class BlockCipherWrapperTest extends TestCase
+{
+    public void testWrapperOnDES() throws Exception
+    {
+        String message = "hello world this is a test";
+        BlockCipherWrapper wrapper = new BlockCipherWrapper( DESEngine.class );
+        byte[] encryped = wrapper.encrypt( "secret", message.getBytes( "UTF-8" ) );
+        String decrypted = new String( wrapper.decrypt( "secret", encryped ), "UTF-8" );
+        assertTrue( message.equals( decrypted.substring( 0, message.length()) ) );
+    }
+}

Added: directory/trunks/triplesec/guardian-api/pom.xml
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/pom.xml?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/pom.xml (added)
+++ directory/trunks/triplesec/guardian-api/pom.xml Tue Dec 12 07:23:31 2006
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+  
+    http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License. 
+-->
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.safehaus.triplesec</groupId>
+    <artifactId>build</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>triplesec-guardian-api</artifactId>
+  <name>Triplesec Guardian Authorization API</name>
+  <description>
+    An API used to access authorization policy information in a store 
+    neutral manner.  Separate driver implementations are designed for 
+    accessing different policy store types.
+  </description>
+  <packaging>jar</packaging>  
+</project>

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ApplicationPolicy.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ApplicationPolicy.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ApplicationPolicy.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ApplicationPolicy.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,145 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+
+import java.util.Iterator;
+import java.util.Set;
+
+
+
+/**
+ * The policy store for an application whose access policy is managed by Triplesec.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @author Trustin Lee
+ * @author <a href="mailto:ersiner@safehaus.org">Ersin Er</a>
+ * @version $Rev: 72 $, $Date: 2005-11-07 21:37:46 -0500 (Mon, 07 Nov 2005) $
+ */
+public interface ApplicationPolicy
+{
+    /**
+     * Removes a change listener so that it does not recieve policy change 
+     * notifications.
+     * 
+     * @param listener the listener to remove.
+     */
+    boolean removePolicyListener( PolicyChangeListener listener ) throws GuardianException;
+    
+    /**
+     * Adds a change listener so that it recieves policy change notifications.
+     * 
+     * @param listener the listener to add.
+     */
+    boolean addPolicyListener( PolicyChangeListener listener ) throws GuardianException;
+    
+    /** 
+     * Gets the name uniquely identifying the applicaiton associated
+     * with this store.
+     * 
+     * @return the name of this store
+     */
+    String getApplicationName();
+    
+    /**
+     * Gets a set of {@link Role}s defined for this store.
+     * 
+     * @return a set of {@link Role}s defined for this store.
+     */
+    Roles getRoles();
+    
+    /**
+     * Gets a set of {@link Permission}s defined for this store.
+     * 
+     * @return a set of {@link Permission}s defined for this store.
+     */
+    Permissions getPermissions();
+    
+    /**
+     * Gets the names of the profiles dependent on a role. The set contains
+     * Strings of the profile name.
+     * 
+     * @param role the role the dependent profiles are associated with
+     * @return the name's of profiles that depend on the supplied role
+     * @throws GuardianException if there is an error accessing the backing 
+     * store or the role is not associated with this ApplicationPolicy
+     */
+    Set getDependentProfileNames( Role role ) throws GuardianException;
+    
+    /**
+     * Gets the names of the profiles dependent on a permission.  The set 
+     * contains Strings of the profile names.
+     * 
+     * @param permission the permission the dependent profiles are associated with
+     * @return the name's of profiles that depend on the supplied permission
+     * @throws GuardianException if there is an error accessing the backing 
+     * store or the permission is not associated with this ApplicationPolicy
+     */
+    Set getDependentProfileNames( Permission permission ) throws GuardianException;
+    
+    /**
+     * Gets the set of profiles a user has for this ApplicationPolicy.
+     * 
+     * @param userName the name of the user to get the profile ids for
+     * @return a set of profile ids as Strings or the empty set if the userName is 
+     * invalid or does not have profiles defined
+     * @throws GuardianException if there are errors accessing the backing store
+     */
+    Set getUserProfileIds( String userName ) throws GuardianException;
+    
+    /**
+     * Gets an iterator over the set of profiles in this ApplicationPolicy.
+     * 
+     * @return an iterator over profileId Strings
+     * @throws GuardianException if there are errors accessing the backing store
+     */
+    Iterator getProfileIdIterator() throws GuardianException;
+
+    /**
+     * Gets this user's authorization {@link Profile} for the application.
+     *
+     * @param profileId the name of the user to get the {@link Profile} for
+     * @return the {@link Profile} for the application or null if no profile exists for
+     *      the specified <tt>profileId</tt>
+     */
+    Profile getProfile( String profileId ) throws GuardianException;
+    
+    /**
+     * Gets a profile for the admin user which is in all roles and has all permissions
+     * granted.
+     * 
+     * @return the admin user profile with all rights
+     */
+    Profile getAdminProfile();
+
+    /**
+     * Gets a breif description of this ApplicationPolicy.
+     *
+     * @return a breif description of this ApplicationPolicy
+     */
+    String getDescription();
+
+    /**
+     * Closes the application store.
+     *
+     * @throws GuardianException if the store cannot be properly closed.
+     */
+    void close() throws GuardianException;
+}

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ApplicationPolicyFactory.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ApplicationPolicyFactory.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ApplicationPolicyFactory.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ApplicationPolicyFactory.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,246 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+
+/**
+ * Connects to {@link ApplicationPolicy} and manages
+ * {@link ConnectionDriver}s.
+ *
+ * @author <a href="mailto:trustin@safehaus.org">Trustin Lee</a>
+ * 
+ * @version $Rev: 68 $, $Date: 2005-08-28 10:08:31 -0400 (Sun, 28 Aug 2005) $
+ *
+ */
+public abstract class ApplicationPolicyFactory
+{
+    /**
+     * A property key that specifies the maxinum number of retries in case of
+     * connection failure in {@link #newInstance(String, Properties)}.
+     */
+    public static final String RETRY_COUNT = ApplicationPolicyFactory.class.getName() + ".retryCount";
+    
+    /**
+     * A property key that specified the delay in seconds between connection retries
+     * in {@link #newInstance(String, Properties)}.
+     */
+    public static final String RETRY_DELAY = ApplicationPolicyFactory.class.getName() + ".retryDelay";
+
+    /** a static list of registered {@link ConnectionDriver}s */
+    private static final List drivers = new ArrayList();
+
+
+    /**
+     * Registers a {@link ConnectionDriver} with this factory.
+     *
+     * @param driver the {@link ConnectionDriver} being registered
+     * @return <tt>true</tt> if and only if the driver is registered
+     */
+    public static boolean registerDriver( ConnectionDriver driver )
+    {
+        synchronized( drivers )
+        {
+            for( Iterator i = drivers.iterator(); i.hasNext(); )
+            {
+                if( driver.getClass().equals( i.next().getClass() ) )
+                {
+                    return false;
+                }
+            }
+            
+            drivers.add( driver );
+        }
+        
+        return true;
+    }
+
+
+    /**
+     * Deregisters all {@link ConnectionDriver}s of the specified
+     * <tt>driverClass</tt> type.
+     * 
+     * @param driverClass the type of {@link ConnectionDriver}s to deregister
+     * @return <tt>true</tt> if and only if any drivers are deregistered
+     */
+    public static boolean deregisterDriver( Class driverClass )
+    {
+        boolean removed = false;
+        synchronized( drivers )
+        {
+            for( Iterator i = drivers.iterator(); i.hasNext(); )
+            {
+                if( driverClass.isAssignableFrom( i.next().getClass() ) )
+                {
+                    i.remove();
+                    removed = true;
+                }
+            }
+        }
+        
+        return removed;
+    }
+
+
+    /**
+     * Connects to the {@link ApplicationPolicy} with the specified <tt>urls</tt>
+     * and extra connection <tt>info</tt> using an appropriate {@link ConnectionDriver}.
+     * <p>
+     * URLs are separated by whitespace characters.  This operation tries the specified
+     * URLs in random order to distribute server-side load.
+     * 
+     * @param urls the whitespace-separated URLs of the {@link ApplicationPolicy}
+     * @param info the extra information to pass to {@link ConnectionDriver}
+     * @return the connected store
+     * @throws GuardianException if failed to connect to the store
+     */
+    public static ApplicationPolicy newInstance( String urls, Properties info ) throws GuardianException
+    {
+        List urlList = new ArrayList();
+        StringTokenizer tk = new StringTokenizer( urls );
+        while( tk.hasMoreElements() )
+        {
+            urlList.add( tk.nextToken() );
+        }
+        
+        Collections.shuffle( urlList );
+        
+        GuardianException ex = null;
+        for( Iterator ui = urlList.iterator(); ui.hasNext(); )
+        {
+            String url = ( String ) ui.next();
+            try
+            {
+                ex = null;
+                return newInstance0( url, info );
+            }
+            catch( GuardianException e )
+            {
+                ex = e;
+            }
+            catch( Throwable t )
+            {
+                ex = new GuardianException( "Driver exception.", t );
+            }
+        }
+        
+        throw ex;
+    }
+    
+    private static ApplicationPolicy newInstance0( String url, Properties info )
+    {
+        ConnectionDriver driver = null;
+        
+        synchronized( drivers )
+        {
+            for( Iterator i = drivers.iterator(); i.hasNext(); )
+            {
+                ConnectionDriver d = ( ConnectionDriver ) i.next();
+                if( d.accept( url ) )
+                {
+                    driver = d;
+                    break;
+                }
+            }
+        }
+        
+        if( driver == null )
+        {
+            throw new NoConnectionDriverException( url );
+        }
+        
+        if( info == null )
+        {
+            info = new Properties();
+        }
+    
+        String retryCountStr = info.getProperty( RETRY_COUNT );
+        String retryDelayStr = info.getProperty( RETRY_DELAY );
+        int retryCount; 
+        int retryDelay;
+        
+        // Get retryCount
+        if( retryCountStr == null )
+        {
+            retryCount = 0;
+        }
+        else
+        {
+            retryCount = Integer.parseInt( retryCountStr );
+        }
+        
+        // Adjust if invalid
+        if( retryCount < 0 )
+        {
+            retryCount = 0;
+        }
+        
+        // Get retryDelay
+        if( retryDelayStr == null )
+        {
+            retryDelay = 1;
+        }
+        else
+        {
+            retryDelay = Integer.parseInt( retryDelayStr );
+        }
+        
+        // Adjust if invalid
+        if( retryDelay < 0 )
+        {
+            retryDelay = 0;
+        }
+        
+        // Try to connect
+        for( int i = 0;; i++ )
+        {
+            try
+            {
+                return driver.newStore( url, info );
+            }
+            catch( StoreConnectionException e )
+            {
+                // Propagate exception if exceeded max retryCount.
+                if( i >= retryCount )
+                {
+                    throw e;
+                }
+                else
+                {
+                    // or sleep for the next try
+                    try
+                    {
+                        Thread.sleep( retryDelay * 1000L );
+                    }
+                    catch( InterruptedException e1 )
+                    {
+                    }
+                }
+            }
+        }        
+    }
+}

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ChangeType.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ChangeType.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ChangeType.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ChangeType.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,79 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+
+/**
+ * The enumerated type for changes to guardian entities.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev$, $Date$
+ */
+public class ChangeType
+{
+    /** the change type representing the addition of a guardian entity */
+    public static final ChangeType ADD = new ChangeType( "Add", 1 );
+    /** the change type representing the deletion of a guardian entity */
+    public static final ChangeType DEL = new ChangeType( "Delete", 2 );
+    /** the change type representing the modification of a guardian entity */
+    public static final ChangeType MODIFY = new ChangeType( "Modify", 4 );
+    /** the change type representing the name change of a guardian entity */
+    public static final ChangeType RENAME = new ChangeType( "Rename", 8 );
+
+    /** the name of this ChangeType enumeration value */
+    private final String name;
+    /** the value of this ChangeType enumeration value */
+    private final int value;
+    
+
+    /**
+     * Create a change type enumeration.
+     * 
+     * @param name the name of this ChangeType enumeration value
+     * @param value the value of this ChangeType enumeration value
+     */
+    private ChangeType( String name, int value )
+    {
+        this.name = name;
+        this.value = value;
+    }
+    
+    
+    /**
+     * Gets the name of this ChangeType enumeration value.
+     * 
+     * @return the name of this ChangeType enumeration value
+     */
+    public String getName()
+    {
+        return name;
+    }
+    
+    
+    /**
+     * Gets the primitive int value of this ChangeType enumeration value.
+     *
+     * @return the primitive int value of this ChangeType enumeration value
+     */
+    public int getValue()
+    {
+        return value;
+    }
+}

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ConnectionDriver.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ConnectionDriver.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ConnectionDriver.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/ConnectionDriver.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,57 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+
+import java.util.Properties;
+
+
+/**
+ * A driver interface that provides an extension mechanism for TripleSec
+ * Guardian API to support various connection types such as JNDI, in-memory
+ * store, and JDBC.
+ *
+ * @author Trustin Lee
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev: 53 $
+ */
+public interface ConnectionDriver
+{
+    /**
+     * Implement this method to return <tt>true</tt> if and only if
+     * this driver can connect to the specified <tt>url</tt>
+     *
+     * @param url the URL to connect to
+     * @return <tt>true</tt> if and only if this driver can connect to
+     *         the specified <tt>url</tt>
+     */
+    boolean accept( String url );
+
+    /**
+     * Implement this method to connect to the {@link ApplicationPolicy}
+     * with the specified <tt>url</tt> and return the connected {@link ApplicationPolicy}.
+     *
+     * @param url the URL to connect to
+     * @param info the extra information a user specified
+     * @return the connected {@link ApplicationPolicy}
+     * @throws GuardianException if failed to connect
+     */
+    ApplicationPolicy newStore( String url, Properties info ) throws GuardianException;
+}

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/GuardianException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/GuardianException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/GuardianException.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/GuardianException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,85 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+
+
+/**
+ * An exception thrown by {@link ApplicationPolicy} and
+ * {@link ApplicationPolicyFactory} when connection to the store is
+ * not established or crashed.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @author Trustin Lee
+ * 
+ * @version $Rev: 53 $, $Date: 2005-08-21 20:58:16 -0400 (Sun, 21 Aug 2005) $
+ */
+public class GuardianException extends RuntimeException
+{
+    private static final long serialVersionUID = 4460210351439248871L;
+
+
+    // ------------------------------------------------------------------------
+    // C O N S T R U C T O R S
+    // ------------------------------------------------------------------------
+    
+    
+    /**
+     * Creates a simple exception with no message.
+     */
+    public GuardianException()
+    {
+        super();
+    }
+    
+
+    /**
+     * Creates a an exception with a message.
+     * 
+     * @param message a message String indicating the problem
+     */
+    public GuardianException( String message )
+    {
+        super( message );
+    }
+
+    
+    /**
+     * Creates a nested exception wrapping another throwable.
+     *  
+     * @param nested the throwable wrapped by this ExceptionTests.
+     */
+    public GuardianException( Throwable nested )
+    {
+        super( nested );
+    }
+
+    
+    /**
+     * Creates a nested exception wrapping another throwable with a message.
+     * 
+     * @param message a message String indicating the problem
+     * @param nested the throwable wrapped by this ExceptionTests.
+     */
+    public GuardianException( String message, Throwable nested )
+    {
+        super( message, nested );
+    }
+}

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/NoConnectionDriverException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/NoConnectionDriverException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/NoConnectionDriverException.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/NoConnectionDriverException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,76 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+
+/**
+ * A {@link GuardianException} which is thrown when no appropriate 
+ * {@link ConnectionDriver} for the URL a user specified is found.
+ *
+ * @author Trustin Lee
+ * @version $Rev: 52 $, $Date: 2005-08-19 23:03:36 -0400 (Fri, 19 Aug 2005) $
+ */
+public class NoConnectionDriverException extends GuardianException
+{
+    private static final long serialVersionUID = -6051735665432589525L;
+
+
+    /**
+     * Creates a new instance.
+     */
+    public NoConnectionDriverException()
+    {
+        super();
+    }
+
+
+    /**
+     * Creates a new instance.
+     *
+     * @param message a detailed description
+     */
+    public NoConnectionDriverException( String message )
+    {
+        super(message);
+    }
+
+
+    /**
+     * Creates a new instance.
+     *
+     * @param nested the root cause of this exception
+     */
+    public NoConnectionDriverException( Throwable nested )
+    {
+        super(nested);
+    }
+
+
+    /**
+     * Creates a new instance.
+     *
+     * @param message a detailed description
+     * @param nested the root cause of this exception
+     */
+    public NoConnectionDriverException( String message, Throwable nested )
+    {
+        super(message, nested);
+    }
+}

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Permission.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Permission.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Permission.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Permission.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,179 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+import java.io.Serializable;
+
+
+/**
+ * An application permission.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @author Trustin Lee
+ * @version $Rev: 71 $, $Date: 2005-11-07 19:11:39 -0500 (Mon, 07 Nov 2005) $
+ */
+public class Permission implements Comparable, Cloneable, Serializable
+{
+    private static final long serialVersionUID = -522561010304299861L;
+
+    /** the name of the permission */
+    private final String permissionName;
+    /** the name of the application this permission is associated with */
+    private final String applicationName;
+    /** a short description of the permission */
+    private final String description;
+
+
+    /**
+     * Creates a new permission instance.
+     *
+     * @param applicationName the name of the application this permission is associated with
+     * @param permissionName the permissionName of the permission
+     */
+    public Permission( String applicationName, String permissionName )
+    {
+        this( applicationName, permissionName, null );
+    }
+
+
+    /**
+     * Creates a new permission instance with description.
+     *
+     * @param applicationName the name of the application this permission is associated with
+     * @param permissionName the permissionName of the permission
+     */
+    public Permission( String applicationName, String permissionName, String description )
+    {
+        if( applicationName == null )
+        {
+            throw new NullPointerException( "applicationName" );
+        }
+        if( permissionName == null )
+        {
+            throw new NullPointerException( "permissionName" );
+        }
+        if( applicationName.length() == 0 )
+        {
+            throw new IllegalArgumentException( "applicationName is empty.");
+        }
+        if( permissionName.length() == 0 )
+        {
+            throw new IllegalArgumentException( "permissionName is empty.");
+        }
+
+        this.permissionName = permissionName;
+        this.applicationName = applicationName;
+        this.description = description;
+    }
+
+
+    /**
+     * Gets the name of this permission.
+     *
+     * @return the name
+     */
+    public String getName()
+    {
+        return permissionName;
+    }
+
+
+    /**
+     * Gets the application name this permission is defined for.
+     *
+     * @return the name of the application.
+     */
+    public String getApplicationName()
+    {
+        return applicationName;
+    }
+
+
+    /**
+     * Gets the name of this permission.
+     *
+     * @return the description
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+
+    // ------------------------------------------------------------------------
+    // Object Overrides
+    // ------------------------------------------------------------------------
+
+
+    public int hashCode()
+    {
+        return applicationName.hashCode() ^ permissionName.hashCode();
+    }
+
+
+    public boolean equals( Object that )
+    {
+        if( this == that )
+        {
+            return true;
+        }
+        
+        if( that instanceof Permission )
+        {
+            Permission thatP = ( Permission ) that;
+            return this.applicationName.equals( thatP.applicationName ) &&
+                    this.permissionName.equals( thatP.permissionName );
+        }
+        
+        return false;
+    }
+
+
+    public int compareTo( Object that )
+    {
+        Permission thatP = ( Permission ) that;
+        int ret = this.applicationName.compareTo( thatP.applicationName );
+        if( ret != 0 )
+        {
+            return ret;
+        }
+        
+        return this.permissionName.compareTo( thatP.permissionName );
+    }
+
+
+    public String toString()
+    {
+        return "Permission(" + applicationName + ": " + permissionName + ')';
+    }
+
+
+    public Object clone()
+    {
+        try
+        {
+            return super.clone();
+        }
+        catch( CloneNotSupportedException e )
+        {
+            throw new InternalError();
+        }
+    }
+}

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Permissions.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Permissions.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Permissions.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Permissions.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,340 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+
+/**
+ * Represnets an immutable set of {@link Permission}s.
+ *
+ * @author Trustin Lee
+ * @version $Rev: 52 $, $Date: 2005-08-19 23:03:36 -0400 (Fri, 19 Aug 2005) $
+ */
+public class Permissions implements Cloneable, Serializable
+{
+    private static final long serialVersionUID = 824005229641450076L;
+    /** An empty array of {@link Permission}s which is used when <tt>null</tt> is specified */
+    private static final Permission[] EMPTY_PERMISSION_ARRAY = new Permission[0];
+
+    /** the name of application this permissions belong to */
+    private final String applicationName;
+    /** <tt>Map&lt;String permissionName, Permission permission&gt;</tt> */
+    private final Map permissions = new HashMap();
+
+
+    /**
+     * Creates a new instance.
+     * 
+     * @param applicationName The name of the application this permissions belong to
+     * @param permissions The array of {@link Permission}s that will belong to this permission set
+     */
+    public Permissions( String applicationName, Permission[] permissions )
+    {
+        // Check nulls and emptiness
+        if( applicationName == null )
+        {
+            throw new NullPointerException( "applicationName" );
+        }
+        if( applicationName.length() == 0 )
+        {
+            throw new IllegalArgumentException( "applicationName is empty." );
+        }
+        if( permissions == null )
+        {
+            permissions = EMPTY_PERMISSION_ARRAY;
+        }
+        
+        this.applicationName = applicationName;
+
+        // Add all permissions while checking if application names are all
+        // same with what user specified.
+        for( int i = permissions.length - 1; i >= 0; i -- )
+        {
+            Permission p = permissions[ i ];
+            if( p == null )
+            {
+                continue;
+            }
+            
+            if( !applicationName.equals( p.getApplicationName() ) )
+            {
+                throw new IllegalArgumentException( "Invalid applicationName: " + p.getApplicationName() );
+            }
+            
+            this.permissions.put( p.getName(), p );
+        }
+    }
+
+
+    /**
+     * Returns the name of the application this permissions belong to
+     * 
+     * @return the name of the application this permissions belong to
+     */
+    public String getApplicationName()
+    {
+        return applicationName;
+    }
+
+
+    /**
+     * Returns <tt>true</tt> if and only if this set contains the specified
+     * <tt>permission</tt>.
+     *
+     * @param permission the permission to find
+     * @return <tt>true</tt> if and only if this set contains the specified
+     *         <tt>permission</tt>
+     */
+    public boolean contains( Permission permission )
+    {
+        return applicationName.equals( permission.getApplicationName() ) &&
+               permissions.containsKey( permission.getName() );
+    }
+
+
+    /**
+     * Returns <tt>true</tt> if and only if this set contains the {@link Permission}
+     * with the specified <tt>permissionName</tt>.
+     *
+     * @param permissionName the name of the permission to find
+     * @return <tt>true</tt> if and only if this set contains the specified
+     *         <tt>permissionName</tt>
+     */
+    public boolean contains( String permissionName )
+    {
+        return permissions.containsKey( permissionName );
+    }
+
+
+    /**
+     * Returns <tt>true</tt> if and only if this set contains all elements of
+     * the specified <tt>permissions</tt>.
+     *
+     * @param permissions another set of permissions
+     * @return <tt>true</tt> if and only if this set contains all elements of
+     *         the specified <tt>permissions</tt>
+     */
+    public boolean containsAll( Permissions permissions )
+    {
+        checkApplicationName( permissions );
+        return this.permissions.keySet().containsAll( permissions.permissions.keySet() );
+    }
+
+
+    /**
+     * Returns the {@link Permission} with the specified <tt>permissionName</tt>.
+     *
+     * @param permissionName the name of the permission to find
+     * @return <tt>null</tt> if there's no permission with the specified name
+     */
+    public Permission get( String permissionName )
+    {
+        return ( Permission ) permissions.get( permissionName );
+    }
+
+
+    /**
+     * Returns <tt>true</tt> if this set is empty.
+     * 
+     * @return <tt>true</tt> if this set is empty
+     */
+    public boolean isEmpty()
+    {
+        return permissions.isEmpty();
+    }
+
+
+    /**
+     * Returns the number of elements this set contains.
+     * 
+     * @return the number of elements this set contains
+     */
+    public int size()
+    {
+        return permissions.size();
+    }
+
+
+    /**
+     * Returns an {@link Iterator} that iterates all {@link Permission}s this set contains.
+     * 
+     * @return an {@link Iterator} that iterates all {@link Permission}s this set contains
+     */
+    public Iterator iterator()
+    {
+        return Collections.unmodifiableCollection( permissions.values() ).iterator();
+    }
+
+
+    /**
+     * Creates a new set of {@link Permission}s which contains all elements of
+     * both this set and the specified set (OR operation).  This operation never
+     * modifies this set.
+     * 
+     * @param permissions a set of permissions to add
+     * @return a new set
+     */
+    public Permissions addAll( Permissions permissions )
+    {
+        checkApplicationName( permissions );
+        Permissions newPermissions = ( Permissions ) clone();
+        newPermissions.permissions.putAll( permissions.permissions );
+        return newPermissions;
+    }
+
+
+    /**
+     * Creates a new set of {@link Permission}s which contains elements of
+     * this set excluding what exists in the specified set (NAND operation).
+     * This operation never modifies this set.
+     * 
+     * @param permissions a set of permissions to remove
+     * @return a new set
+     */
+    public Permissions removeAll( Permissions permissions )
+    {
+        checkApplicationName( permissions );
+        Permissions newPermissions = ( Permissions ) clone();
+        newPermissions.permissions.keySet().removeAll(
+                permissions.permissions.keySet() );
+        return newPermissions;
+    }
+
+
+    /**
+     * Creates a new set of {@link Permission}s which contains elements which
+     * exists in both this set and the specified set (AND operation).  This
+     * operation never modifies this set.
+     * 
+     * @param permissions a set of permissions to retain.
+     * @return a new set
+     */
+    public Permissions retainAll( Permissions permissions )
+    {
+        checkApplicationName( permissions );
+        Permissions newPermissions = ( Permissions ) clone();
+        newPermissions.permissions.keySet().retainAll(
+                permissions.permissions.keySet() );
+        return newPermissions;
+    }
+
+
+    // ------------------------------------------------------------------------
+    // Object Overrides
+    // ------------------------------------------------------------------------
+
+
+    public Object clone()
+    {
+        Permission[] permissionArray = new Permission[ size() ];
+        permissionArray = ( Permission[] ) permissions.values().toArray( permissionArray );
+        return new Permissions( applicationName, permissionArray );
+    }
+
+
+    public int hashCode()
+    {
+        return applicationName.hashCode() ^ permissions.hashCode();
+    }
+    
+
+    public boolean equals( Object that )
+    {
+        if( this == that )
+        {
+            return true;
+        }
+        
+        if( that instanceof Permissions )
+        {
+            Permissions thatP = ( Permissions ) that;
+            // We don't compare application name because permissions already
+            // contain it.
+            return this.permissions.equals( thatP.permissions );
+        }
+        
+        return false;
+    }
+
+
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer();
+        buf.append( "Permissions(" );
+        buf.append( applicationName );
+        buf.append( ": " );
+
+        // Sort permissions by name
+        Set sortedPermissions = new TreeSet( permissions.values() );
+        Iterator i = sortedPermissions.iterator();
+        
+        // Add the first one
+        if( i.hasNext() )
+        {
+            Permission p = ( Permission ) i.next();
+            buf.append( p.getName() );
+            
+            // Add others
+            while( i.hasNext() )
+            {
+                p = ( Permission ) i.next();
+                buf.append( ", " );
+                buf.append( p.getName() );
+            }
+        }
+        else
+        {
+            buf.append( "empty" );
+        }
+        
+        buf.append( ')' );
+        
+        return buf.toString();
+    }
+
+
+    // ------------------------------------------------------------------------
+    // Private Methods
+    // ------------------------------------------------------------------------
+
+
+    /**
+     * Checks if the application name of the specified <tt>permissions</tt>
+     * equals to that of this set.
+     *  
+     * @param permissions the permissions to check the application name
+     * @throws IllegalArgumentException if mismatches
+     */
+    private void checkApplicationName( Permissions permissions )
+    {
+        if( !applicationName.equals( permissions.getApplicationName() ) )
+        {
+            throw new IllegalArgumentException( "Wrong application name: " + permissions.getApplicationName() );
+        }
+    }
+}

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/PolicyChangeAdapter.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/PolicyChangeAdapter.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/PolicyChangeAdapter.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/PolicyChangeAdapter.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,61 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+
+
+
+/**
+ * An do nothing convenience adapter for a PolicyChangeListener.
+ * 
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev$, $Date$
+ */
+public class PolicyChangeAdapter implements PolicyChangeListener
+{
+    public void roleChanged( ApplicationPolicy policy, Role role, ChangeType changeType )
+    {
+    }
+
+
+    public void roleRenamed( ApplicationPolicy policy, Role role, String oldName )
+    {
+    }
+
+
+    public void permissionChanged( ApplicationPolicy policy, Permission permission, ChangeType changeType )
+    {
+    }
+
+
+    public void permissionRenamed( ApplicationPolicy policy, Permission permission, String oldName )
+    {
+    }
+
+
+    public void profileChanged( ApplicationPolicy policy, Profile profile, ChangeType changeType )
+    {
+    }
+
+
+    public void profileRenamed( ApplicationPolicy policy, Profile profile, String oldName )
+    {
+    }
+}

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/PolicyChangeListener.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/PolicyChangeListener.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/PolicyChangeListener.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/PolicyChangeListener.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,90 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+
+
+
+/**
+ * A policy change listener interested in changes to an application's access 
+ * policy which is managed by TripleSec.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev$, $Date$
+ */
+public interface PolicyChangeListener
+{
+    /**
+     * Notification method called when a role is added, deleted, or modified.  
+     * Another overload is used to handle rename operations on objects.
+     * 
+     * @param policy the application policy containing the role
+     * @param role the role that is added, deleted or modified
+     * @param changeType the type of change: add, delete or modify.
+     */
+    void roleChanged( ApplicationPolicy policy, Role role, ChangeType changeType );
+    
+    /**
+     * Notification method called when a role is renamed.
+     * 
+     * @param policy the application policy containing the role
+     * @param role the role that was renamed and whose getName() returns the new name
+     * @param oldName the old name of the role
+     */
+    void roleRenamed( ApplicationPolicy policy, Role role, String oldName );
+
+    /**
+     * Notification method called when a permission is added, deleted, or modified.  
+     * Another overload is used to handle rename operations on objects.
+     * 
+     * @param policy the application policy containing the permission
+     * @param permission the permission that was changed
+     * @param changeType the type of change: add, delete or modify.
+     */
+    void permissionChanged( ApplicationPolicy policy, Permission permission, ChangeType changeType );
+    
+    /**
+     * Notification method called when a permission is renamed.
+     * 
+     * @param policy the application policy containing the permission
+     * @param permission the permission that was renamed
+     * @param oldName the old name of the permission
+     */
+    void permissionRenamed( ApplicationPolicy policy, Permission permission, String oldName );
+
+    /**
+     * Notification method called when a profile is added, deleted, or modified.  
+     * Another overload is used to handle rename operations on objects.
+     * 
+     * @param policy the application policy containing the profile
+     * @param profile the profile that changed
+     * @param changeType the type of change: add, delete or modify.
+     */
+    void profileChanged( ApplicationPolicy policy, Profile profile, ChangeType changeType );
+
+    /**
+     * Notification method called when a policy is renamed.
+     * 
+     * @param policy the application policy containing the profile
+     * @param profile the profile that was renamed
+     * @param oldName the old name of the profile
+     */
+    void profileRenamed( ApplicationPolicy policy, Profile profile, String oldName );
+}

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Profile.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Profile.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Profile.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Profile.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,473 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+
+import java.io.Serializable;
+import java.security.AccessControlException;
+import java.util.Iterator;
+
+
+/**
+ * <p>
+ * A user's application authorization profile.  Authorization policy is used
+ * to manage access controls for user profiles associated with applications.
+ * Profiles associate users with applications.  This class models that profile
+ * by linking the user with an application and allowing the assignment of an
+ * application specific {@link Role} set and {@link Permission} set to the 
+ * profile.
+ * </p>  
+ * <p>
+ * Profiles contain three sets of Permissions and a set of Roles used for 
+ * managing an authorization policy of a user.  A Role Based Access Control 
+ * (RBAC) model is used to easily manage the Profile.  The three Permission
+ * sets are: grants, denials and the effective calculated permissions for the 
+ * profile.  Roles assigned to the Profile lead to the inheritance of Permission
+ * granted to Role.  Besides Role based Permission inheritence, additional
+ * Permission may be granted or denied to influence the total effective Permission.  
+ * The grants Permissions set contains extra granted Permissions which may not be 
+ * inherited by assigned Roles.  The denials Permissions set contains
+ * {@link Permissions} that are denied whether they are inherited by assigned
+ * {@link Role}s or granted through the grants Permissions set.  Denials
+ * take precedence.  For more information take a look at the documentation here:
+ * </p>
+ * <ul>
+ *   <li><a href="http://guardian.safehaus.org/User%27s+Guide">Guardian User's Guide</a></li>
+ * </ul>
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @author Trustin Lee
+ * @version $Rev: 74 $, $Date: 2005-11-11 02:03:22 -0500 (Fri, 11 Nov 2005) $
+ */
+public class Profile implements Comparable, Cloneable, Serializable
+{
+    /** */
+    private static final long serialVersionUID = 1762844758784443519L;
+
+    /** the store this Profile is for */
+    private final ApplicationPolicy store;
+    /** the name of the User this Profile is for */
+    private final String userName;
+    /** the id of this Profile is for */
+    private final String profileId;
+    /** the roles assigned to this Profile */
+    private final Roles roles;
+    /** the permissions granted to this Profile */
+    private final Permissions grants;
+    /** the permissions denied by this Profile */
+    private final Permissions denials;
+    /** the effective calculated permissions for this Profile */
+    private final Permissions effectivePermissions;
+    /** a brief description of the Profile */
+    private final String description;
+    /** whether or not this profile is disabled */
+    private final boolean disabled;
+
+
+    /**
+     * Creates a default User Profile for an ApplicationPolicyStore.
+     *
+     * @param profileId the id of this Profile
+     * @param userName the name of the User this Profile is for
+     * @param store the store this Profile is for
+     * @param roles the roles assigned to this Profile
+     * @param grants the permissions granted to this Profile
+     * @param denials the permissions denied by this Profile
+     * @param disabled true if this Profile is disabled otherwise false
+     */
+    public Profile(
+            ApplicationPolicy store,
+            String profileId, String userName, Roles roles,
+            Permissions grants, Permissions denials, boolean disabled )
+    {
+        this ( store, profileId, userName, roles, grants, denials, null, disabled );
+    }
+
+
+    /**
+     * Creates a default User Profile for an ApplicationPolicyStore.
+     * 
+     * @param profileId the name of the User this Profile is for
+     * @param store the store this Profile is for
+     * @param roles the roles assigned to this Profile
+     * @param grants the permissions granted to this Profile
+     * @param denials the permissions denied by this Profile
+     * @param description a brief description for this Profile
+     * @param disabled true if this Profile is disabled otherwise false
+     */
+    public Profile(
+            ApplicationPolicy store,
+            String profileId, String userName, Roles roles,
+            Permissions grants, Permissions denials, String description, boolean disabled )
+    {
+        if( store == null )
+        {
+            throw new NullPointerException( "store" );
+        }
+        if( profileId == null )
+        {
+            throw new NullPointerException( "profileId" );
+        }
+        if( userName == null )
+        {
+            throw new NullPointerException( "userName" );
+        }
+        if( profileId.length() == 0 )
+        {
+            throw new IllegalArgumentException( "profileId is empty." );
+        }
+        if( roles == null )
+        {
+            roles = new Roles( store.getApplicationName(), null );
+        }
+        if( !store.getApplicationName().equals( roles.getApplicationName() ) )
+        {
+            throw new IllegalArgumentException( "Invalid applicationName in roles: " + roles.getApplicationName() );
+        }
+        if( grants == null )
+        {
+            grants = new Permissions( store.getApplicationName(), null );
+        }
+        if( !store.getApplicationName().equals( grants.getApplicationName() ) )
+        {
+            throw new IllegalArgumentException( "Invalid applicationName in grants: " + grants.getApplicationName() );
+        }
+        if( !store.getPermissions().containsAll( grants ) )
+        {
+            throw new IllegalArgumentException(
+                    "store doesn't provide all permissions specified: " +
+                    grants );
+        }
+        if( denials == null )
+        {
+            denials = new Permissions( store.getApplicationName(), null );
+        }
+        if( !store.getApplicationName().equals( denials.getApplicationName() ) )
+        {
+            throw new IllegalArgumentException( "Invalid applicationName in denials: " + denials.getApplicationName() );
+        }
+        if( !store.getPermissions().containsAll( denials ) )
+        {
+            throw new IllegalArgumentException(
+                    "store doesn't provide all permissions specified: " +
+                    denials );
+        }
+        
+        this.disabled = disabled;
+        this.store = store;
+        this.profileId = profileId;
+        this.userName = userName;
+        this.roles = roles;
+        this.grants = grants;
+        this.denials = denials;
+        this.description = description;
+
+        // Calculate effective permissions
+        Permissions effectivePermissions = new Permissions( store.getApplicationName(), null );
+        for( Iterator i = roles.iterator(); i.hasNext(); )
+        {
+            Role r = ( Role ) i.next();
+            effectivePermissions = effectivePermissions.addAll( r.getGrants() );
+        }
+        effectivePermissions = effectivePermissions.addAll( grants );
+        this.effectivePermissions = effectivePermissions.removeAll( denials );
+    }
+
+    
+    /**
+     * Checks whether or not this Profile has been disabled.
+     * 
+     * @return true if this Profile is disabled, false if enabled
+     */
+    public boolean isDisabled()
+    {
+        return disabled;
+    }
+    
+
+    /**
+     * Gets the id of the this Profile.
+     * 
+     * @return the id of this Profile
+     */
+    public String getProfileId()
+    {
+        return profileId;
+    }
+
+
+    /**
+     * Gets the name of the user who owns this Profile.
+     * 
+     * @return the name of the user associated with this Profile
+     */
+    public String getUserName()
+    {
+        return userName;
+    }
+
+
+    /**
+     * Gets a brief description for this Profile if one exists.
+     *
+     * @return a description for this Profile
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+
+    /**
+     * Gets the name of the application this Profile is associated with.
+     * 
+     * @return the name of the application this Profile is associated with
+     */
+    public String getApplicationName()
+    {
+        return store.getApplicationName();
+    }
+
+
+    /**
+     * Gets a set of {@link Role}s which are assigned to this Profile.
+     * 
+     * @return a container of {@link Role} objects which are assigned to this Profile
+     */
+    public Roles getRoles()
+    {
+        return roles;
+    }
+
+
+    /**
+     * Checks to see if the user according to this Profile is in a Role.  
+     *
+     * @param roleName the name of the Role to check for
+     * @return true if the user is in the Role, false otherwise
+     */
+    public boolean isInRole( String roleName )
+    {
+        return roles.contains( roleName );
+    }
+
+
+    /**
+     * Gets the set of {@link Permission}s granted to this Profile.
+     * 
+     * @return a container of granted {@link Permission} objects
+     */
+    public Permissions getGrants()
+    {
+        return grants;
+    }
+
+    /**
+     * Gets a set of permissions explicitly denied by this profile.
+     * This is the only time and place where negative permissions will ever be
+     * found.
+     * 
+     * @return a container of denied {@link Permission} objects
+     */
+    public Permissions getDenials()
+    {
+        return denials;
+    }
+
+
+    /**
+     * Gets the set of effective (net calculated) permissions for this Profile.
+     * An effective permission is calculated from the assigned {@link Role}s,
+     * granted {@link Permissions} and denied {@link Permissions} of this
+     * Profile.
+     * 
+     * @return a container of effective {@link Permission} objects for this profile.
+     */
+    public Permissions getEffectivePermissions()
+    {
+        return effectivePermissions;
+    }
+
+
+    /**
+     * Assertive check to test if this Profile has the effective {@link Permission}.
+     * 
+     * @param permissionName the permission name to check for
+     * @throws AccessControlException if the permission is not granted or
+     *      inherited from an assigned Role
+     */
+    public void checkPermission( String permissionName )
+    {
+        checkPermission(
+                permissionName,
+                "User '" + profileId + "' " +
+                "in application '" + getApplicationName() + '\'' +
+                "does not posess the permission '" + permissionName + "'." );
+    }
+
+
+    /**
+     * Get's whether or not this Profile has the permission.
+     *
+     * @param permission the permission to check for
+     * @return true if the permission is granted, false otherwise
+     */
+    public boolean hasPermission( Permission permission )
+    {
+        return effectivePermissions.contains( permission );
+    }
+
+
+    /**
+     * Get's whether or not this Profile has the permission.
+     *
+     * @param permissionName the permission to check for
+     * @return true if the permission is granted, false otherwise
+     */
+    public boolean hasPermission( String permissionName )
+    {
+        return effectivePermissions.get( permissionName ) != null;
+    }
+
+
+    /**
+     * Assertive permission check to test if this Profile has the effective 
+     * permission.
+     * 
+     * @param permission the permission to check for
+     * @throws AccessControlException if the permission is not granted or
+     *      inherited from an assigned Role
+     */
+    public void checkPermission( Permission permission )
+    {
+        checkPermission(
+                permission,
+                "User '" + profileId + "' " +
+                "in application '" + getApplicationName() + '\'' +
+                "does not posess the permission '" + permission.getName() + "'." );
+    }
+
+
+    /**
+     * Assertive permission check to test if this Profile has the effective 
+     * permission.
+     * 
+     * @param permissionName the permission name to check for
+     * @param message to use for AccessControlException if it is thrown
+     * @throws AccessControlException if the permission is not granted or
+     *      inherited from an assigned Role
+     */
+    public void checkPermission( String permissionName, String message )
+    {
+        if ( permissionName == null )
+        {
+            throw new NullPointerException( "permissionName" );    
+        }
+        
+        if ( !effectivePermissions.contains( permissionName ) )
+        {
+            throw new AccessControlException( message );
+        }
+    }
+
+
+    /**
+     * Assertive permission check to test if this Profile has the effective 
+     * permission.
+     * 
+     * @param permission the permission to check for
+     * @param message to use for AccessControlException if it is thrown
+     * @throws AccessControlException if the permission is not granted or
+     *      inherited from an assigned Role
+     */
+    public void checkPermission( Permission permission, String message )
+    {
+        if ( permission == null )
+        {
+            throw new NullPointerException( "permission" );    
+        }
+        
+        if ( !effectivePermissions.contains( permission ) )
+        {
+            throw new AccessControlException( message );
+        }
+    }
+
+
+    // ------------------------------------------------------------------------
+    // Object Overrides
+    // ------------------------------------------------------------------------
+
+
+    public int hashCode()
+    {
+        return getApplicationName().hashCode() ^ profileId.hashCode();
+    }
+
+
+    public boolean equals( Object that )
+    {
+        if( this == that )
+        {
+            return true;
+        }
+        
+        if( that instanceof Profile )
+        {
+            Profile thatP = ( Profile ) that;
+            return this.getApplicationName().equals( thatP.getApplicationName() ) &&
+                   this.getProfileId().equals( thatP.getProfileId() );
+        }
+        
+        return false;
+    }
+
+
+    public int compareTo( Object that )
+    {
+        Profile thatP = ( Profile ) that;
+        int ret = this.getApplicationName().compareTo( thatP.getApplicationName() );
+        if( ret != 0 )
+        {
+            return ret;
+        }
+        
+        return this.getProfileId().compareTo( thatP.getProfileId() );
+    }
+
+
+    public Object clone()
+    {
+        try
+        {
+            return super.clone();
+        }
+        catch( CloneNotSupportedException e )
+        {
+            throw new InternalError();
+        }
+    }
+
+
+    public String toString()
+    {
+        return "Profile(" + getProfileId() + ": " + effectivePermissions + ')';
+    }
+}

Added: directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Role.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Role.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Role.java (added)
+++ directory/trunks/triplesec/guardian-api/src/main/java/org/safehaus/triplesec/guardian/Role.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,322 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *  
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License. 
+ *  
+ */
+package org.safehaus.triplesec.guardian;
+
+
+import java.io.Serializable;
+import java.security.AccessControlException;
+
+
+/**
+ * An application role.  Roles are application specific and contain a set
+ * of permission grants.  Users assigned to these Roles inherit the set of 
+ * permission grants from their roles.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @author Trustin Lee
+ * @version $Rev: 74 $, $Date: 2005-11-11 02:03:22 -0500 (Fri, 11 Nov 2005) $
+ */
+public class Role implements Comparable, Cloneable, Serializable 
+{
+    private static final long serialVersionUID = 6190625586883412135L;
+
+    /** an empty byte array used as a placeholder for empty grants */
+    private static final Permission[] EMPTY_PERMISSION_ARRAY = new Permission[0];
+    
+    /** the name of this Role */
+    private final String name;
+    /** the store the Role is defined for */
+    private final ApplicationPolicy store;
+    /** the permissions granted for this role */
+    private final Permissions permissions;
+    /** a brief description of the Role */
+    private final String description;
+
+
+    /**
+     * Creates a new Role instance with a description.
+     * 
+     * @param store the parent store this role is defined for
+     * @param name the name of this role
+     * @param permissions a set of permissions granted for this role
+     * @param description a breif description of the role
+     */
+    public Role( ApplicationPolicy store, String name, Permissions permissions, String description )
+    {
+        if( store == null )
+        {
+            throw new NullPointerException( "store" );
+        }
+        if( name == null )
+        {
+            throw new NullPointerException( "name" );
+        }
+        if( name.length() == 0 )
+        {
+            throw new IllegalArgumentException( "name is empty." );
+        }
+        
+        if( permissions == null )
+        {
+            permissions = new Permissions(
+                    store.getApplicationName(), EMPTY_PERMISSION_ARRAY );
+        }
+        if( !store.getApplicationName().equals( permissions.getApplicationName() ) )
+        {
+            throw new IllegalArgumentException(
+                    "Invalid applicationName in permissions: " +
+                    permissions.getApplicationName() );
+        }
+        
+        if( !store.getPermissions().containsAll( permissions ) )
+        {
+            throw new IllegalArgumentException(
+                    "store doesn't provide all permissions specified: " +
+                    permissions );
+        }
+        
+        this.store = store;
+        this.name = name;
+        this.permissions = permissions;
+        this.description = description;
+    }
+
+
+    /**
+     * Creates a new Role instance.
+     *
+     * @param store the parent store this role is defined for
+     * @param name the name of this role
+     * @param permissions a set of permissions granted for this role
+     */
+    public Role( ApplicationPolicy store, String name, Permissions permissions )
+    {
+        this ( store, name, permissions, null );
+    }
+
+
+    /**
+     * Gets the name of this Role.
+     * 
+     * @return the name of this Role
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+
+    /**
+     * Gets a brief description for this Role if one exists.
+     *
+     * @return a description for this Role
+     */
+    public String getDescription()
+    {
+        return description;
+    }
+
+
+    /**
+     * Gets the application name this Role is defined for.
+     *  
+     * @return the name of the application this Role is defined for.
+     */
+    public String getApplicationName()
+    {
+        return store.getApplicationName();
+    }
+
+
+    /**
+     * Gets a set of permissions granted to this role.
+     * 
+     * @return a set of permissions granted to this role.
+     */
+    public Permissions getGrants()
+    {
+        return permissions;
+    }
+
+
+    /**
+     * Assertive permission check to test if this role has the effective
+     * permission.
+     *
+     * @param permission the permission to check for
+     * @throws AccessControlException if the permission is not granted
+     */
+    public void checkPermission( Permission permission )
+    {
+        checkPermission(
+                permission,
+                "Role '" + name + "' " +
+                "in application '" + getApplicationName() + '\'' +
+                "does not posess the permission '" + permission.getName() + "'." );
+    }
+
+
+    /**
+     * Get's whether or not this Role has the permission.
+     *
+     * @param permissionName the permission to check for
+     * @return true if the permission is granted,false otherwise
+     */
+    public boolean hasPermission( String permissionName )
+    {
+        return permissions.get( permissionName ) != null;
+    }
+
+
+    /**
+     * Get's whether or not this Role has the permission.
+     *
+     * @param permission the name of permission to check for
+     * @return true if the permission is granted,false otherwise
+     */
+    public boolean hasPermission( Permission permission )
+    {
+        return permissions.contains( permission );
+    }
+
+
+    /**
+     * Assertive permission check to test if this role has the effective 
+     * permission.
+     * 
+     * @param permissionName the name of the permission to check for
+     * @throws AccessControlException if the permission is not granted
+     */
+    public void checkPermission( String permissionName )
+    {
+        checkPermission(
+                permissionName,
+                "Role '" + name + "' " +
+                "in application '" + getApplicationName() + '\'' +
+                "does not posess the permission '" + permissionName + "'." );
+    }
+
+
+    /**
+     * Assertive permission check to test if this Role has the effective 
+     * permission.
+     * 
+     * @param permission the permission to check for
+     * @param message to use for AccessControlException if it is thrown
+     * @throws AccessControlException if the permission is not granted
+     */
+    public void checkPermission( Permission permission, String message )
+    {
+        if ( permission == null )
+        {
+            throw new NullPointerException( "permission" );    
+        }
+        
+        if ( !permissions.contains( permission ) )
+        {
+            throw new AccessControlException( message );
+        }
+    }
+
+
+    /**
+     * Assertive permission check to test if this role has the effective 
+     * permission.
+     * 
+     * @param permissionName the permission name to check for
+     * @param message to use for AccessControlException if it is thrown
+     * @throws AccessControlException if the permission is not granted
+     */
+    public void checkPermission( String permissionName, String message )
+    {
+        if ( permissionName == null )
+        {
+            throw new NullPointerException( "permissionName" );    
+        }
+        
+        if ( !permissions.contains( permissionName ) )
+        {
+            throw new AccessControlException( message );
+        }
+    }
+
+
+    // ------------------------------------------------------------------------
+    // Object Overrides
+    // ------------------------------------------------------------------------
+
+
+    public int hashCode()
+    {
+        return getApplicationName().hashCode() ^ name.hashCode(); 
+    }
+
+
+    public boolean equals( Object that )
+    {
+        if( this == that )
+        {
+            return true;
+        }
+        
+        if( that instanceof Role )
+        {
+            Role thatR = ( Role ) that;
+            return this.getApplicationName().equals( thatR.getApplicationName() ) &&
+                   this.getName().equals( thatR.getName() );
+        }
+        
+        return false;
+    }
+
+
+    public int compareTo( Object that )
+    {
+        Role thatR = ( Role ) that;
+        int ret = this.getApplicationName().compareTo( thatR.getApplicationName() );
+        if( ret != 0 )
+        {
+            return ret;
+        }
+        else
+        {
+            return this.getName().compareTo( thatR.getName() );
+        }
+    }
+
+
+    public Object clone()
+    {
+        try
+        {
+            return super.clone();
+        }
+        catch( CloneNotSupportedException e )
+        {
+            throw new InternalError();
+        }
+    }
+
+
+    public String toString()
+    {
+        return "Role(" + getName() + ": " + permissions + ')';
+    }
+}