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 [2/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/ ad...

Added: directory/trunks/triplesec/LICENSE.txt
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/LICENSE.txt?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/LICENSE.txt (added)
+++ directory/trunks/triplesec/LICENSE.txt Tue Dec 12 07:23:31 2006
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.

Added: directory/trunks/triplesec/NOTICE.txt
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/NOTICE.txt?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/NOTICE.txt (added)
+++ directory/trunks/triplesec/NOTICE.txt Tue Dec 12 07:23:31 2006
@@ -0,0 +1,2 @@
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).

Added: directory/trunks/triplesec/admin-api/pom.xml
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/pom.xml?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/pom.xml (added)
+++ directory/trunks/triplesec/admin-api/pom.xml Tue Dec 12 07:23:31 2006
@@ -0,0 +1,140 @@
+<?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-admin-api</artifactId>
+  <name>Triplesec Admin API</name>
+  <description>
+    Administrative API used to manage triplesec server operational parameters,
+    the authorization store, user creation and deletion etc.
+  </description>
+  <packaging>jar</packaging>  
+  <dependencies>
+    <!-- 
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>triplesec-guardian-api</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.directory.server</groupId>
+      <artifactId>apacheds-server-integration</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <scope>test</scope>
+    </dependency>
+     -->
+
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>triplesec-guardian-api</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>triplesec-integration</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <systemProperties>
+            <property>
+              <name>org.safehaus.triplesec.integration.resourcesDirectory</name>
+              <value>${basedir}/src/test/resources</value>
+            </property>
+          </systemProperties>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>no-integration-tests</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+      <build>
+        <plugins>
+           <plugin>
+              <artifactId>maven-surefire-plugin</artifactId>
+              <configuration>
+                <systemProperties>
+                  <property>
+                    <name>org.safehaus.triplesec.integration.resourcesDirectory</name>
+                    <value>${basedir}/src/test/resources</value>
+                  </property>
+                </systemProperties>
+
+                <excludes>
+                  <exclude>**/*ITest.java</exclude>
+                  <exclude>**/*IntegrationTest.java</exclude>
+                </excludes>
+              </configuration>
+            </plugin>
+            <plugin>
+              <artifactId>maven-antrun-plugin</artifactId>
+              <executions>
+                <execution>
+                  <phase>validate</phase>
+                  <configuration>
+                    <tasks>
+                      <echo>
+=================================================================
+                          W A R N I N G
+                          -------------
+
+Integration tests have been disabled.  To enable integration
+tests run maven with the -Dintegration switch.
+=================================================================
+                      </echo>
+                    </tasks>
+                  </configuration>
+                  <goals>
+                    <goal>run</goal>
+                  </goals>
+                </execution>
+              </executions>
+            </plugin>
+         </plugins>
+       </build>
+    </profile>
+    <profile>
+      <id>integration</id>
+      <activation>
+        <property><name>integration</name></property>
+      </activation>
+    </profile>
+  </profiles>
+
+</project>

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/AdministeredEntity.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/AdministeredEntity.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/AdministeredEntity.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/AdministeredEntity.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,71 @@
+/*
+ *  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.admin;
+
+
+import java.util.Date;
+
+
+public abstract class AdministeredEntity
+{
+    private final String creatorsName;
+    private final String modifiersName;
+    private final Date createTimestamp;
+    private final Date modifyTimestamp;
+    
+    
+    protected AdministeredEntity( String creatorsName, Date creationTimestamp )
+    {
+        this( creatorsName, creationTimestamp, null, null );
+    }
+    
+    
+    protected AdministeredEntity( String creatorsName, Date createTimestamp, String modifiersName, Date modifyTimestamp )
+    {
+        this.creatorsName = creatorsName;
+        this.createTimestamp = createTimestamp;
+        this.modifiersName = modifiersName;
+        this.modifyTimestamp = modifyTimestamp;
+    }
+    
+    
+    public String getCreatorsName()
+    {
+        return creatorsName;
+    }
+
+
+    public String getModifiersName()
+    {
+        return modifiersName;
+    }
+
+
+    public Date getCreateTimestamp()
+    {
+        return createTimestamp;
+    }
+
+
+    public Date getModifyTimestamp()
+    {
+        return modifyTimestamp;
+    }
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Application.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Application.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Application.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Application.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.admin;
+
+
+import java.util.Date;
+import java.util.Iterator;
+
+import org.safehaus.triplesec.admin.dao.ApplicationDao;
+import org.safehaus.triplesec.admin.dao.PermissionDao;
+import org.safehaus.triplesec.admin.dao.ProfileDao;
+import org.safehaus.triplesec.admin.dao.RoleDao;
+
+
+public class Application extends AdministeredEntity
+{
+    private final RoleDao roleDao;
+    private final ProfileDao profileDao;
+    private final PermissionDao permissionDao;
+    private final String name;
+    private final String description;
+    private final String password;
+    private final ApplicationDao dao;
+    
+    
+    public Application( String creatorsName, Date creationTimestamp, ApplicationDao dao, String name, 
+        String description, String password, PermissionDao permissionDao, RoleDao roleDao, ProfileDao profileDao )
+    {
+        this( creatorsName, creationTimestamp, null, null, dao, name, description, password,
+            permissionDao, roleDao, profileDao );
+    }
+    
+    
+    public Application( String creatorsName, Date creationTimestamp, String modifiersName, Date modifyTimestamp, 
+        ApplicationDao dao, String name, String description, String userPassword, PermissionDao permissionDao, 
+        RoleDao roleDao, ProfileDao profileDao )
+    {
+        super( creatorsName, creationTimestamp, modifiersName, modifyTimestamp );
+        this.name = name;
+        this.dao = dao;
+        this.description = description;
+        this.permissionDao = permissionDao;
+        this.profileDao = profileDao;
+        this.roleDao = roleDao;
+        this.password = userPassword;
+    }
+    
+    
+    // -----------------------------------------------------------------------
+    // Package friendly dao accessors
+    // -----------------------------------------------------------------------
+    
+    
+    PermissionDao getPermissionDao()
+    {
+        return permissionDao;
+    }
+    
+    
+    RoleDao getRoleDao()
+    {
+        return roleDao;
+    }
+    
+    
+    ProfileDao getProfileDao()
+    {
+        return profileDao;
+    }
+    
+    
+    // -----------------------------------------------------------------------
+    // Property accessors
+    // -----------------------------------------------------------------------
+    
+    
+    public String getName()
+    {
+        return name;
+    }
+    
+    
+    public String getDescription()
+    {
+        return description;
+    }
+    
+    
+    public String getPassword()
+    {
+        return password;
+    }
+    
+    
+    // -----------------------------------------------------------------------
+    // Accessors to contained entities
+    // -----------------------------------------------------------------------
+    
+    
+    public Permission getPermission( String permName ) throws DataAccessException
+    {
+        return permissionDao.load( name, permName );
+    }
+    
+    
+    public Role getRole( String roleName ) throws DataAccessException
+    {
+        return roleDao.load( name, roleName );
+    }
+    
+    
+    public Profile getProfile( String profileId ) throws DataAccessException
+    {
+        return profileDao.load( name, profileId );
+    }
+    
+    
+    // -----------------------------------------------------------------------
+    // ReadOnly Iterator methods
+    // -----------------------------------------------------------------------
+    
+    
+    public Iterator permissionIterator() throws DataAccessException
+    {
+        return new ReadOnlyIterator( permissionDao.permissionIterator( name ) );
+    }
+    
+    
+    public Iterator roleIterator() throws DataAccessException
+    {
+        return new ReadOnlyIterator( roleDao.roleIterator( name ) );
+    }
+    
+    
+    public Iterator profileIterator() throws DataAccessException
+    {
+        return new ReadOnlyIterator( profileDao.profileIterator( name ) );
+    }
+    
+    
+    public Iterator profileIterator( String user) throws DataAccessException
+    {
+        return new ReadOnlyIterator( profileDao.profileIterator( name, user ) );
+    }
+    
+    
+    // -----------------------------------------------------------------------
+    // Modifier factory methods
+    // -----------------------------------------------------------------------
+    
+    
+    public ApplicationModifier modifier()
+    {
+        return new ApplicationModifier( dao, this );
+    }
+    
+    
+    public String toString()
+    {
+        return name;
+    }
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ApplicationModifier.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ApplicationModifier.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ApplicationModifier.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ApplicationModifier.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,292 @@
+/*
+ *  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.admin;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.naming.directory.ModificationItem;
+
+import org.safehaus.triplesec.admin.dao.ApplicationDao;
+import org.safehaus.triplesec.admin.dao.PermissionDao;
+import org.safehaus.triplesec.admin.dao.ProfileDao;
+import org.safehaus.triplesec.admin.dao.RoleDao;
+
+
+public class ApplicationModifier implements Constants
+{
+    private final String name;
+    private final SingleValuedField description;
+    private final SingleValuedField password;
+    private final PermissionDao permissionDao;
+    private final RoleDao roleDao;
+    private final ProfileDao profileDao;
+    private final ApplicationDao dao;
+    private final Application archetype;
+    
+    private boolean persisted;
+    
+    
+    // -----------------------------------------------------------------------
+    // Constructors
+    // -----------------------------------------------------------------------
+    
+    
+    ApplicationModifier( ApplicationDao dao, String name, PermissionDao permissionDao, 
+        RoleDao roleDao, ProfileDao profileDao )
+    {
+        this.name = name;
+        this.dao = dao;
+        this.archetype = null;
+        this.permissionDao = permissionDao;
+        this.roleDao = roleDao;
+        this.profileDao = profileDao;
+        this.password = new SingleValuedField( PASSWORD_ID, null );
+        this.description = new SingleValuedField( DESCRIPTION_ID, null );
+    }
+    
+    
+    ApplicationModifier( ApplicationDao dao, Application archetype )
+    {
+        this.name = archetype.getName();
+        this.dao = dao;
+        this.archetype = archetype;
+        this.permissionDao = archetype.getPermissionDao();
+        this.roleDao = archetype.getRoleDao();
+        this.profileDao = archetype.getProfileDao();
+        this.password = new SingleValuedField( PASSWORD_ID, archetype.getPassword() );
+        this.description = new SingleValuedField( DESCRIPTION_ID, archetype.getDescription() );
+    }
+    
+    
+    // -----------------------------------------------------------------------
+    // Property mutators
+    // -----------------------------------------------------------------------
+    
+    
+    public ApplicationModifier setDescription( String description )
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( "This modifier has persisted changes and is no longer valid." );
+        }
+        this.description.setValue( description );
+        return this;
+    }
+
+    
+    public ApplicationModifier setPassword( String userPassword )
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( "This modifier has persisted changes and is no longer valid." );
+        }
+        this.password.setValue( userPassword );
+        return this;
+    }
+    
+    
+    public PermissionModifier newPermission( String permName ) 
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( "This modifier has persisted changes and is no longer valid." );
+        }
+        return new PermissionModifier( permissionDao, name, permName );
+    }
+    
+    
+    public RoleModifier newRole( String roleName ) 
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( "This modifier has persisted changes and is no longer valid." );
+        }
+        return new RoleModifier( roleDao, name, roleName );
+    }
+    
+    
+    public ProfileModifier newProfile( String profileId, String user ) 
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( "This modifier has persisted changes and is no longer valid." );
+        }
+        return new ProfileModifier( profileDao, name, profileId, user );
+    }
+    
+    
+    // -----------------------------------------------------------------------
+    // Mutable Iterator access methods
+    // -----------------------------------------------------------------------
+    
+    
+    public Iterator permissionIterator() throws DataAccessException
+    {
+        return permissionDao.permissionIterator( name );
+    }
+    
+    
+    public Iterator roleIterator() throws DataAccessException
+    {
+        return roleDao.roleIterator( name );
+    }
+    
+    
+    public Iterator profileIterator() throws DataAccessException
+    {
+        return profileDao.profileIterator( name );
+    }
+    
+    
+    public Application getArchetype()
+    {
+        return archetype;
+    }
+    
+    
+    public boolean isNewEntry()
+    {
+        return archetype == null;
+    }
+
+
+    public boolean isUpdatableEntry()
+    {
+        return archetype != null;
+    }
+    
+    
+    public boolean isUpdateNeeded()
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( "This modifier has persisted changes and is no longer valid." );
+        }
+        return description.isUpdateNeeded() || password.isUpdateNeeded();
+    }
+    
+    
+    public boolean isValid()
+    {
+        return !persisted;
+    }
+    
+    
+    private ModificationItem[] getModificationItems()
+    {
+        if ( ! isUpdateNeeded() )
+        {
+            return EMPTY_MODS;
+        }
+        
+        List mods = new ArrayList();
+        if ( password.isUpdateNeeded() )
+        {
+            mods.add( password.getModificationItem() );
+        }
+        if ( description.isUpdateNeeded() )
+        {
+            mods.add( description.getModificationItem() );
+        }
+        
+        return ( ModificationItem[] ) mods.toArray( EMPTY_MODS );
+    }
+
+
+    public Application modify() throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( "This modifier has persisted changes and is no longer valid." );
+        }
+        
+        if ( isNewEntry() )
+        {
+            throw new IllegalStateException( "This modifier cannot be used to modify an Application" );
+        }
+
+        Application app = dao.modify( archetype.getName(), getModificationItems() );
+        persisted = true;
+        return app;
+    }   
+
+
+    public void delete() throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( "This modifier has persisted changes and is no longer valid." );
+        }
+        
+        if ( isNewEntry() )
+        {
+            throw new IllegalStateException( "This modifier cannot be used to delete an Application" );
+        }
+
+        dao.delete( archetype );
+        persisted = true;
+    }   
+
+
+    public Application add() throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( "This modifier has persisted changes and is no longer valid." );
+        }
+        
+        if ( isUpdatableEntry() )
+        {
+            throw new IllegalStateException( "This modifier cannot create/add a new Application" );
+        }
+
+        Application app = dao.add( name, description.getCurrentValue(), password.getCurrentValue() );
+        persisted = true;
+        return app;
+    }
+    
+    
+    public Application rename( String newName ) throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( "This modifier has persisted changes and is no longer valid." );
+        }
+        
+        if ( isNewEntry() )
+        {
+            throw new IllegalStateException( "This modifier cannot be used to rename " +
+                    "a new Application before an add operation" );
+        }
+
+        if ( isUpdateNeeded() )
+        {
+            throw new ModificationLossException( name + " has been modified. " +
+                    "A rename operation will result in the loss of these modifications." );
+        }
+        
+        Application app = dao.rename( archetype, newName );
+        persisted = true;
+        return app;
+    }
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ConfigurationException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ConfigurationException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ConfigurationException.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ConfigurationException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,32 @@
+/*
+ *  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.admin;
+
+
+public class ConfigurationException extends RuntimeException
+{
+    private static final long serialVersionUID = 2367225722077035743L;
+    
+    
+    public ConfigurationException( String message )
+    {
+        super( message );
+    }
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Constants.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Constants.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Constants.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Constants.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,96 @@
+/*
+ *  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.admin;
+
+
+import javax.naming.directory.ModificationItem;
+
+
+public interface Constants
+{
+    String POLICY_PROFILE_OC = "policyProfile";
+    String POLICY_PERMISSION_OC = "policyPermission";
+    String POLICY_ROLE_OC = "policyRole";
+    String SAFEHAUS_PROFILE_OC = "safehausProfile";
+    String GROUP_OF_UNIQUE_NAMES_OC = "groupOfUniqueNames";
+    String UID_OBJECT_OC = "uidObject";
+    String EXTENSIBLE_OBJECT_OC = "extensibleObject";
+    String ORGANIZATIONAL_PERSON_OC = "organizationalPerson";
+    String PERSON_OC = "person";
+    String INET_ORG_PERSON_OC = "inetOrgPerson";
+    String KRB5PRINCIPAL_OC = "krb5Principal";
+    String KRB5KDCENTRY_OC = "krb5KDCEntry";
+    String REFERRAL_OC = "referral";
+    
+    String SAFEHAUS_RESYNCH_COUNT_ID = "safehausResynchCount";
+    String SAFEHAUS_DISABLED_ID = "safehausDisabled";
+    String KRB5_DISABLED_ID = "krb5AccountDisabled";
+    String KRB5ENCRYPTION_TYPE_ID = "krb5EncryptionType";
+    String KRB5KEY_VERSION_NUMBER_ID = "krb5KeyVersionNumber";
+    String KRB5KEY_ID = "krb5Key";
+    String KRB5PRINCIPAL_REALM_ID = "krb5PrincipalRealm";
+    String KRB5PRINCIPAL_NAME_ID = "krb5PrincipalName";
+    String APACHE_SAM_TYPE_ID = "apacheSamType";
+    String STREET_ID = "street";
+    String POSTAL_ADDRESS_ID = "postalAddress";
+    String LOCALITY_NAME_ID = "l";
+    String STATE_PROVINCE_ID = "st";
+    String ZIP_POSTAL_CODE_ID = "postalCode";
+    String COUNTRY_ID = "c";
+    String ORGANIZATION_ID = "o";
+    String COMMON_NAME_ID = "cn";
+    String OBJECT_CLASS_ID = "objectClass";
+    String UID_ID = "uid";
+    String GIVENNAME_ID = "givenName";
+    String SURNAME_ID = "sn";
+    String PASSWORD_ID = "userPassword";
+    String DESCRIPTION_ID = "description";
+    String MOBILE_ID = "mobile";
+    String EMAIL_ID = "mail";
+    String NOTIFY_BY_ID = "safehausNotifyBy";
+    String MOBILE_CARRIER_ID = "safehausMobileCarrier";
+    String TOKEN_PIN_ID = "safehausTokenPin";
+    String MIDLE_NAME_ID = "safehausMidletName";
+    String FAILURES_IN_EPOCH_ID = "safehausFailuresInEpoch";
+    String ACTIVATION_KEY_ID = "safehausActivationKey";
+    String REALM_ID = "safehausRealm";
+    String SECRET_ID = "safehausSecret";
+    String LABEL_ID = "safehausLabel";
+    String MOVING_FACTOR_ID = "safehausFactor";
+    String UNIQUE_MEMBER_ID = "uniqueMember";
+    String REF_ID = "ref";
+    String GRANTS_ID = "grants";
+    String DENIALS_ID = "denials";
+    String ROLES_ID = "roles";
+    String USER_ID = "user";
+    String DOMAIN_COMPONENT_ID = "dc";
+    String CREATE_TIMESTAMP_ID = "createTimestamp";
+    String MODIFY_TIMESTAMP_ID = "modifyTimestamp";
+    String MODIFIERS_NAME_ID = "modifiersName";
+    String APP_NAME_ID = "appName";
+    String PERM_NAME_ID = "permName";
+    String ROLE_NAME_ID = "roleName";
+    String PROFILEID_ID = "profileId";
+    String SAFEHAUS_ID = "safehausUid";
+    String CREATORS_NAME_ID = "creatorsName";
+
+    ModificationItem[] EMPTY_MODS = new ModificationItem[0];
+    String INVALID_MSG = "This modifier has persisted changes and is no longer valid.";
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ConstraintViolationException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ConstraintViolationException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ConstraintViolationException.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ConstraintViolationException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,38 @@
+/*
+ *  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.admin;
+
+
+public class ConstraintViolationException extends DataAccessException
+{
+    private static final long serialVersionUID = 2970896053000775404L;
+
+    
+    public ConstraintViolationException()
+    {
+        super();
+    }
+    
+    
+    public ConstraintViolationException( String msg )
+    {
+        super( msg );
+    }
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/DataAccessException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/DataAccessException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/DataAccessException.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/DataAccessException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,38 @@
+/*
+ *  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.admin;
+
+
+public class DataAccessException extends Exception
+{
+    private static final long serialVersionUID = 6075112153857180792L;
+
+    
+    public DataAccessException()
+    {
+        super();
+    }
+    
+    
+    public DataAccessException( String msg )
+    {
+        super( msg );
+    }
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/EntryAlreadyExistsException.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/EntryAlreadyExistsException.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/EntryAlreadyExistsException.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/EntryAlreadyExistsException.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,38 @@
+/*
+ *  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.admin;
+
+
+public class EntryAlreadyExistsException extends ConstraintViolationException
+{
+    private static final long serialVersionUID = -8548066197124969705L;
+
+
+    public EntryAlreadyExistsException()
+    {
+        super();
+    }
+    
+    
+    public EntryAlreadyExistsException( String msg )
+    {
+        super( msg );
+    }
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ExternalUser.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ExternalUser.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ExternalUser.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ExternalUser.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.admin;
+
+
+import java.util.Date;
+
+import org.safehaus.triplesec.admin.dao.ExternalUserDao;
+
+
+public class ExternalUser extends User
+{
+    private final String referral;
+    private final ExternalUserDao dao;
+    
+    public ExternalUser( String creatorsName, Date createTimestamp, String modifiersName, 
+        Date modifyTimestamp, ExternalUserDao dao, String id, String description, String referral, boolean disabled )
+    {
+        super( creatorsName, createTimestamp, modifiersName, modifyTimestamp, id, description, disabled );
+        this.dao = dao;
+        this.referral = referral;
+    }
+
+
+    public ExternalUser( String creatorsName, Date createTimestamp, ExternalUserDao dao, String id, 
+        String description, String referral )
+    {
+        super( creatorsName, createTimestamp, id, description, false );
+        this.dao = dao;
+        this.referral = referral;
+    }
+
+
+    public ExternalUserModifier modifier()
+    {
+        return new ExternalUserModifier( dao, this );
+    }
+
+
+    public String getReferral()
+    {
+        return referral;
+    }
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ExternalUserModifier.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ExternalUserModifier.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ExternalUserModifier.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/ExternalUserModifier.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,237 @@
+/*
+ *  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.admin;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.naming.directory.ModificationItem;
+
+import org.safehaus.triplesec.admin.dao.ExternalUserDao;
+
+
+public class ExternalUserModifier implements Constants
+{
+    private SingleValuedField referral;
+    private final SingleValuedField disabled;
+    
+    private final ExternalUserDao dao;
+    private final String id;
+    private final ExternalUser archetype;
+    private final SingleValuedField description;
+    private boolean persisted = false;
+    
+    
+    // -----------------------------------------------------------------------
+    // Constructors
+    // -----------------------------------------------------------------------
+
+    
+    public ExternalUserModifier( ExternalUserDao dao, ExternalUser archetype )
+    {
+        this.id = archetype.getId();
+        this.dao = dao;
+        this.archetype = archetype;
+        this.referral = new SingleValuedField( REF_ID, archetype.getReferral() );
+        this.description = new SingleValuedField( DESCRIPTION_ID, archetype.getDescription() );
+        this.disabled = new SingleValuedField( KRB5_DISABLED_ID, String.valueOf( archetype.isDisabled() ).toUpperCase() );
+    }
+
+
+    public ExternalUserModifier( ExternalUserDao dao, String id, String referral )
+    {
+        this.id = id;
+        this.dao = dao;
+        this.archetype = null;
+        this.referral = new SingleValuedField( REF_ID, referral );
+        this.description = new SingleValuedField( DESCRIPTION_ID, null );
+        this.disabled = new SingleValuedField( KRB5_DISABLED_ID, null );
+    }
+    
+    
+    // -----------------------------------------------------------------------
+    // Mutators
+    // -----------------------------------------------------------------------
+
+    
+    public ExternalUserModifier setDisabled( boolean disabled )
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+        this.disabled.setValue( String.valueOf( disabled ).toUpperCase() );
+        return this;
+    }
+    
+    
+    public ExternalUserModifier setReferral( String referral )
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+        this.referral.setValue( referral );
+        return this;
+    }
+    
+   
+    public ExternalUserModifier setDescription( String description )
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+        this.description.setValue( description );
+        return this;
+    }
+
+
+    // -----------------------------------------------------------------------
+    // Modifier Check Methods
+    // -----------------------------------------------------------------------
+
+    
+    public boolean isUpdateNeeded()
+    {
+        return description.isUpdateNeeded() || referral.isUpdateNeeded() || disabled.isUpdateNeeded();
+    }
+
+
+    public boolean isNewEntry()
+    {
+        return archetype == null;
+    }
+
+
+    public boolean isUpdatableEntry()
+    {
+        return archetype != null;
+    }
+    
+    
+    public boolean isValid()
+    {
+        return ! persisted;
+    }
+    
+    
+    // -----------------------------------------------------------------------
+    // Modifier Methods
+    // -----------------------------------------------------------------------
+
+    
+    public ExternalUser add() throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+        ExternalUser user = dao.add( id, description.getCurrentValue(), referral.getCurrentValue() );
+        persisted = true;
+        return user;
+    }
+    
+    
+    public ExternalUser rename( String newName ) throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+
+        if ( isUpdateNeeded() )
+        {
+            throw new ModificationLossException( id + " has been modified. " +
+                    "A rename operation will result in the loss of these modifications." );
+        }
+        
+        ExternalUser user = dao.rename( newName, archetype );
+        persisted = true;
+        return user;
+    }
+    
+    
+    public ExternalUser modify() throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+        ExternalUser user = dao.modify( archetype.getCreatorsName(), archetype.getCreateTimestamp(), id, 
+            description.getCurrentValue(), referral.getCurrentValue(), 
+            parseBoolean( disabled.getCurrentValue().toLowerCase() ), getModificationItems() );
+        persisted = true;
+        return user;
+    }
+    
+    
+    public void delete() throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+        dao.delete( id );
+        persisted = true;
+    }
+
+    
+    private ModificationItem[] getModificationItems()
+    {
+        // new entries do not generate modification items
+        if ( isNewEntry() )
+        {
+            return EMPTY_MODS;
+        }
+
+        if ( isUpdateNeeded() )
+        {
+            List mods = new ArrayList();
+            if ( description.isUpdateNeeded() )
+            {
+                mods.add( description.getModificationItem() );
+            }
+            if ( referral.isUpdateNeeded() )
+            {
+                mods.add( referral.getModificationItem() );
+            }
+            if ( disabled.isUpdateNeeded() )
+            {
+                mods.add( disabled.getModificationItem() );
+            }
+            ModificationItem[] modArray = new ModificationItem[mods.size()];
+            return ( ModificationItem[] ) mods.toArray( modArray );
+        }
+        return EMPTY_MODS;
+    }
+
+
+    private static boolean parseBoolean( String bool )
+    {
+        if ( bool.equals( "true" ) )
+        {
+            return true;
+        }
+        
+        return false;
+    }
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Group.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Group.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Group.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/Group.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.admin;
+
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.safehaus.triplesec.admin.dao.GroupDao;
+
+
+public class Group extends AdministeredEntity
+{
+    private final GroupDao dao;
+    private final String name;
+    private final Set members;
+    
+    
+    public Group( String creatorsName, Date createTimestamp, GroupDao dao, String name, Set members )
+    {
+        this( creatorsName, createTimestamp, null, null, dao, name, members );
+    }
+    
+    
+    public Group( String creatorsName, Date createTimestamp, String modifiersName, 
+        Date modifyTimestamp, GroupDao dao, String name, Set members )
+    {
+        super( creatorsName, createTimestamp, modifiersName, modifyTimestamp );
+        this.dao = dao;
+        this.name = name;
+        this.members = new HashSet( members );
+    }
+
+
+    public String getName()
+    {
+        return name;
+    }
+
+
+    public Set getMembers()
+    {
+        return Collections.unmodifiableSet( members );
+    }
+    
+    
+    public GroupModifier modifier()
+    {
+        return new GroupModifier( dao, this );
+    }
+    
+    
+    public String toString()
+    {
+        return name;
+    }
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/GroupModifier.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/GroupModifier.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/GroupModifier.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/GroupModifier.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,175 @@
+/*
+ *  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.admin;
+
+
+import java.util.Set;
+
+import javax.naming.directory.ModificationItem;
+
+import org.safehaus.triplesec.admin.dao.GroupDao;
+
+
+public class GroupModifier implements Constants
+{
+    private final GroupDao dao;
+    private final String name;
+    private final Group archetype;
+    private final MultiValuedField members;
+    private boolean persisted = false;
+
+
+    public GroupModifier( GroupDao dao, Group archetype )
+    {
+        this.dao = dao;
+        this.archetype = archetype;
+        this.name = archetype.getName();
+        this.members = new MultiValuedField( UNIQUE_MEMBER_ID, archetype.getMembers() );
+    }
+    
+    
+    public GroupModifier( GroupDao dao, String name, Set members )
+    {
+        this.dao = dao;
+        this.name = name;
+        this.members = new MultiValuedField( UNIQUE_MEMBER_ID, members );
+        this.archetype = null;
+    }
+
+
+    private ModificationItem[] getModificationItems()
+    {
+        // new entries do not generate modification items
+        if ( isNewEntry() )
+        {
+            return EMPTY_MODS;
+        }
+        
+        if ( members.isUpdateNeeded() )
+        {
+            return new ModificationItem[] { members.getModificationItem() };
+        }
+        
+        return EMPTY_MODS;
+    }
+
+
+    public boolean isNewEntry()
+    {
+        return archetype == null;
+    }
+
+
+    public boolean isUpdatableEntry()
+    {
+        return archetype != null;
+    }
+    
+    
+    public boolean isUpdateNeeded()
+    {
+        return members.isUpdateNeeded();
+    }
+    
+    
+    public boolean isValid()
+    {
+        return ! persisted;
+    }
+    
+    
+    public GroupModifier addMember( String member )
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+        
+        members.addValue( member );
+        return this;
+    }
+    
+    
+    public GroupModifier removeMember( String member )
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+
+        members.removeValue( member );
+        return this;
+    }
+    
+    
+    public Group add() throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+        Group group = dao.add( name, members.getCurrentValues() );
+        persisted = true;
+        return group;
+    }
+    
+    
+    public Group rename( String newName ) throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+
+        if ( isUpdateNeeded() )
+        {
+            throw new ModificationLossException( name + " has been modified. " +
+                    "A rename operation will result in the loss of these modifications." );
+        }
+        
+        Group group = dao.rename( newName, archetype );
+        persisted = true;
+        return group;
+    }
+    
+    
+    public Group modify() throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+        Group group = dao.modify( archetype.getCreatorsName(), archetype.getCreateTimestamp(), name, 
+            members.getCurrentValues(), getModificationItems() );
+        persisted = true;
+        return group;
+    }
+    
+    
+    public void delete() throws DataAccessException
+    {
+        if ( persisted )
+        {
+            throw new IllegalStateException( INVALID_MSG );
+        }
+        dao.delete( name );
+        persisted = true;
+    }
+}

Added: directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/HauskeysUser.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/HauskeysUser.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/HauskeysUser.java (added)
+++ directory/trunks/triplesec/admin-api/src/main/java/org/safehaus/triplesec/admin/HauskeysUser.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,240 @@
+/*
+ *  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.admin;
+
+
+import java.util.Date;
+
+import org.safehaus.triplesec.admin.dao.HauskeysUserDao;
+
+
+public class HauskeysUser extends User
+{
+    private final HauskeysUserDao dao;
+    private final String firstName;
+    private final String lastName;
+    private final String password;
+    private final String mobile;
+    private final String email;
+    private final String notifyBy;
+    private final String mobileCarrier;
+    private final String tokenPin;
+    private final String midletName;
+    private final String failuresInEpoch;
+    private final String activationKey;
+    private final String realm;
+    private final String secret;
+    private final String label;
+    private final String movingFactor;
+    private final String address1;
+    private final String address2;
+    private final String city;
+    private final String stateProvRegion;
+    private final String zipPostalCode;
+    private final String country;
+    private final String company;
+    
+    
+    public HauskeysUser( String creatorsName, Date createTimestamp, String modifiersName, 
+        Date modifyTimestamp, HauskeysUserDao dao, String id, String description, String firstName, 
+        String lastName, String password, String mobile, String email, String notifyBy, 
+        String mobileCarrier, String tokenPin, String midletName, String failuresInEpoch, 
+        String activationKey, String realm, String secret, String label, String movingFactor, 
+        String address1, String address2, String city, String stateProvRegion, 
+        String zipPostalCode, String country, String company, boolean disabled )
+    {
+        super( creatorsName, createTimestamp, modifiersName, modifyTimestamp, id, description, disabled );
+        this.dao = dao;
+        this.firstName = firstName;
+        this.lastName = lastName;
+        this.password = password;
+        this.mobile = mobile;
+        this.email = email;
+        this.notifyBy = notifyBy;
+        this.mobileCarrier = mobileCarrier;
+        this.tokenPin = tokenPin;
+        this.midletName = midletName;
+        this.failuresInEpoch = failuresInEpoch;
+        this.activationKey = activationKey;
+        this.realm = realm;
+        this.secret = secret;
+        this.label = label;
+        this.movingFactor = movingFactor;
+        this.address1 = address1;
+        this.address2 = address2;
+        this.city = city;
+        this.stateProvRegion = stateProvRegion;
+        this.zipPostalCode = zipPostalCode;
+        this.country = country;
+        this.company = company;
+    }
+
+
+    public HauskeysUser( String creatorsName, Date createTimestamp, HauskeysUserDao dao, String id, 
+        String description, String firstName, String lastName, String password, String mobile, 
+        String email, String notifyBy, String mobileCarrier, String tokenPin, String midletName, 
+        String failuresInEpoch, String activationKey, String realm, String secret, String label, 
+        String movingFactor, String address1, String address2, String city, String stateProvRegion, 
+        String zipPostalCode, String country, String company, boolean disabled )
+    {
+        this( creatorsName, createTimestamp, null, null, dao, id, description, firstName, lastName, 
+            password, mobile, email, notifyBy, mobileCarrier, tokenPin, midletName, failuresInEpoch, 
+            activationKey, realm, secret, label, movingFactor, address1, address2, city, stateProvRegion, 
+            zipPostalCode, country, company, disabled );
+    }
+
+
+    public String getMobile()
+    {
+        return mobile;
+    }
+
+
+    public String getEmail()
+    {
+        return email;
+    }
+
+
+    public String getNotifyBy()
+    {
+        return notifyBy;
+    }
+
+
+    public String getMobileCarrier()
+    {
+        return mobileCarrier;
+    }
+
+
+    public String getTokenPin()
+    {
+        return tokenPin;
+    }
+
+
+    public String getMidletName()
+    {
+        return midletName;
+    }
+
+
+    public String getFailuresInEpoch()
+    {
+        return failuresInEpoch;
+    }
+
+
+    public String getActivationKey()
+    {
+        return activationKey;
+    }
+
+
+    public String getRealm()
+    {
+        return realm;
+    }
+
+
+    public String getSecret()
+    {
+        return secret;
+    }
+
+
+    public String getLabel()
+    {
+        return label;
+    }
+
+
+    public String getMovingFactor()
+    {
+        return movingFactor;
+    }
+    
+    
+    public String getFirstName()
+    {
+        return firstName;
+    }
+
+
+    public String getLastName()
+    {
+        return lastName;
+    }
+
+
+    public String getPassword()
+    {
+        return password;
+    }
+
+
+    public String getAddress1()
+    {
+        return address1;
+    }
+
+
+    public String getAddress2()
+    {
+        return address2;
+    }
+
+
+    public String getCity()
+    {
+        return city;
+    }
+
+
+    public String getStateProvRegion()
+    {
+        return stateProvRegion;
+    }
+
+
+    public String getZipPostalCode()
+    {
+        return zipPostalCode;
+    }
+
+
+    public String getCountry()
+    {
+        return country;
+    }
+
+
+    public String getCompany()
+    {
+        return company;
+    }
+
+    
+    public HauskeysUserModifier modifier()
+    {
+        return new HauskeysUserModifier( dao, this );
+    }
+}
\ No newline at end of file