directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From smckin...@apache.org
Subject [41/75] [abbrv] [partial] directory-fortress-core git commit: FC-109 - rename rbac package to impl
Date Tue, 09 Jun 2015 03:15:47 GMT
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/ba64d26a/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitDAO.java b/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitDAO.java
new file mode 100755
index 0000000..c238c18
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitDAO.java
@@ -0,0 +1,722 @@
+/*
+ *   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.apache.directory.fortress.core.impl;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.cursor.CursorException;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.DefaultModification;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Modification;
+import org.apache.directory.api.ldap.model.entry.ModificationOperation;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
+import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.util.Strings;
+import org.apache.directory.fortress.core.model.Graphable;
+import org.apache.directory.fortress.core.model.OrgUnit;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.model.ObjectFactory;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+
+
+/**
+ * This class provides dataaccess to the OrgUnit datasets in LDAP.
+ * <p/>
+ * The OrgUnitDAO maintains the following structural and aux object classes:
+ * <h4>1. organizationalUnit Structural Object Class is used to store basic attributes
like ou and description</h4>
+ * <ul>
+ * <li>  ------------------------------------------
+ * <li> <code>objectclass ( 2.5.6.5 NAME 'organizationalUnit'</code>
+ * <li> <code>DESC 'RFC2256: an organizational unit'</code>
+ * <li> <code>SUP top STRUCTURAL</code>
+ * <li> <code>MUST ou</code>
+ * <li> <code>MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $</code>
+ * <li> <code>x121Address $ registeredAddress $ destinationIndicator $</code>
+ * <li> <code>preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier
$</code>
+ * <li> <code>telephoneNumber $ internationaliSDNNumber $</code>
+ * <li> <code>facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode
$</code>
+ * <li> <code>postalAddress $ physicalDeliveryOfficeName $ st $ l $ description
) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>2. ftOrgUnit Structural objectclass is used to store the OrgUnit internal id</h4>
+ * <ul>                                                              org.apache.directory.fortress.arbac.
+ * <li>  ------------------------------------------
+ * <li> <code> objectclass    ( 1.3.6.1.4.1.38088.2.6</code>
+ * <li> <code>NAME 'ftOrgUnit'</code>
+ * <li> <code>DESC 'Fortress OrgUnit Class'</code>
+ * <li> <code>SUP organizationalunit</code>
+ * <li> <code>STRUCTURAL</code>
+ * <li> <code>MUST ( ftId ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <h4>3. ftMods AUXILIARY Object Class is used to store Fortress audit variables on
target entity</h4>
+ * <ul>
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.4</code>
+ * <li> <code>NAME 'ftMods'</code>
+ * <li> <code>DESC 'Fortress Modifiers AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MAY (</code>
+ * <li> <code>ftModifier $</code>
+ * <li> <code>ftModCode $</code>
+ * <li> <code>ftModId ) )</code>
+ * <li>  ------------------------------------------
+ * </ul>
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ * @created September 18, 2010
+ */
+final class OrgUnitDAO extends ApacheDsDataProvider
+{
+    private static final String CLS_NM = OrgUnitDAO.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+    private static final String ORGUNIT_OBJECT_CLASS_NM = "ftOrgUnit";
+
+    private static final String ORGUNIT_OBJ_CLASS[] =
+        {
+            SchemaConstants.TOP_OC, ORGUNIT_OBJECT_CLASS_NM, GlobalIds.FT_MODIFIER_AUX_OBJECT_CLASS_NAME
+    };
+    private static final String[] ORGUNIT_ATRS =
+        {
+            GlobalIds.FT_IID, SchemaConstants.OU_AT, SchemaConstants.DESCRIPTION_AT, GlobalIds.PARENT_NODES
+    };
+
+    private static final String[] ORGUNIT_ATR =
+        {
+            SchemaConstants.OU_AT
+    };
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.CreateException
+     *
+     */
+    OrgUnit create( OrgUnit entity ) throws CreateException
+    {
+        LdapConnection ld = null;
+        Dn dn = getDn( entity );
+
+        try
+        {
+            Entry entry = new DefaultEntry( dn );
+            entry.add( SchemaConstants.OBJECT_CLASS_AT, ORGUNIT_OBJ_CLASS );
+            entity.setId();
+            entry.add( GlobalIds.FT_IID, entity.getId() );
+
+            String description = entity.getDescription();
+
+            if ( !Strings.isEmpty( description ) )
+            {
+                entry.add( SchemaConstants.DESCRIPTION_AT, description );
+            }
+
+            // organizational name requires OU attribute:
+            entry.add( SchemaConstants.OU_AT, entity.getName() );
+
+            // These multi-valued attributes are optional.  The utility function will return
quietly if no items are loaded into collection:
+            loadAttrs( entity.getParents(), entry, GlobalIds.PARENT_NODES );
+
+            ld = getAdminConnection();
+            add( ld, entry, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "create orgUnit name [" + entity.getName() + "] type [" + entity.getType()
+                + "] root [" + dn + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_ADD_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_ADD_FAILED_USER;
+
+            }
+
+            throw new CreateException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    OrgUnit update( OrgUnit entity ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        Dn dn = getDn( entity );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+
+            if ( entity.getDescription() != null && entity.getDescription().length()
> 0 )
+            {
+                mods.add( new DefaultModification(
+                    ModificationOperation.REPLACE_ATTRIBUTE, SchemaConstants.DESCRIPTION_AT,
entity.getDescription() ) );
+            }
+
+            loadAttrs( entity.getParents(), mods, GlobalIds.PARENT_NODES );
+
+            if ( mods.size() > 0 )
+            {
+                ld = getAdminConnection();
+                modify( ld, dn, mods, entity );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "update orgUnit name [" + entity.getName() + "] type [" + entity.getType()
+                + "] root [" + dn + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_UPDATE_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_UPDATE_FAILED_USER;
+            }
+
+            throw new UpdateException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @throws org.apache.directory.fortress.core.UpdateException
+     *
+     */
+    void deleteParent( OrgUnit entity ) throws UpdateException
+    {
+        LdapConnection ld = null;
+        Dn dn = getDn( entity );
+
+        try
+        {
+            List<Modification> mods = new ArrayList<Modification>();
+            mods.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, GlobalIds.PARENT_NODES
) );
+            ld = getAdminConnection();
+            modify( ld, dn, mods, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "deleteParent orgUnit name [" + entity.getName() + "] type ["
+ entity.getType()
+                + "] root [" + dn + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_REMOVE_PARENT_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_REMOVE_PARENT_FAILED_USER;
+            }
+
+            throw new UpdateException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws org.apache.directory.fortress.core.RemoveException
+     *
+     */
+    OrgUnit remove( OrgUnit entity ) throws RemoveException
+    {
+        LdapConnection ld = null;
+        Dn dn = getDn( entity );
+
+        try
+        {
+            ld = getAdminConnection();
+            delete( ld, dn, entity );
+        }
+        catch ( LdapException e )
+        {
+            String error = "remove orgUnit name [" + entity.getName() + "] type [" + entity.getType()
+                + "] root [" + dn + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_DELETE_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_DELETE_FAILED_USER;
+            }
+
+            throw new RemoveException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * @param entity
+     * @return
+     * @throws FinderException
+     *
+     */
+    OrgUnit findByKey( OrgUnit entity ) throws FinderException
+    {
+        OrgUnit oe = null;
+        LdapConnection ld = null;
+        Dn dn = getDn( entity );
+
+        try
+        {
+            ld = getAdminConnection();
+            Entry findEntry = read( ld, dn, ORGUNIT_ATRS );
+
+            if ( findEntry == null )
+            {
+                String warning = "findByKey orgUnit name [" + entity.getName() + "] type
["
+                    + entity.getType() + "] COULD NOT FIND ENTRY for dn [" + dn + "]";
+                int errCode;
+
+                if ( entity.getType() == OrgUnit.Type.PERM )
+                {
+                    errCode = GlobalErrIds.ORG_NOT_FOUND_PERM;
+                }
+                else
+                {
+                    errCode = GlobalErrIds.ORG_NOT_FOUND_USER;
+                }
+
+                throw new FinderException( errCode, warning );
+            }
+
+            oe = getEntityFromLdapEntry( findEntry, 0, entity.getContextId() );
+        }
+        catch ( LdapNoSuchObjectException e )
+        {
+            String warning = "findByKey orgUnit name [" + entity.getName() + "] type ["
+                + entity.getType() + "] COULD NOT FIND ENTRY for dn [" + dn + "]";
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_NOT_FOUND_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_NOT_FOUND_USER;
+            }
+            throw new FinderException( errCode, warning );
+        }
+        catch ( LdapException e )
+        {
+            String error = "findByKey orgUnitName [" + entity.getName() + "] type [" + entity.getType()
+                + "] dn [" + dn + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_READ_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_READ_FAILED_USER;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return oe;
+    }
+
+
+    /**
+     * @param orgUnit
+     * @return
+     * @throws org.apache.directory.fortress.core.FinderException
+     *
+     */
+    List<OrgUnit> findOrgs( OrgUnit orgUnit ) throws FinderException
+    {
+        List<OrgUnit> orgUnitList = new ArrayList<>();
+        LdapConnection ld = null;
+        String orgUnitRoot = getOrgRoot( orgUnit );
+
+        try
+        {
+            String searchVal = encodeSafeText( orgUnit.getName(), GlobalIds.ROLE_LEN );
+            String filter = GlobalIds.FILTER_PREFIX + ORGUNIT_OBJECT_CLASS_NM + ")("
+                + SchemaConstants.OU_AT + "=" + searchVal + "*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, orgUnitRoot,
+                SearchScope.ONELEVEL, filter, ORGUNIT_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                orgUnitList
+                    .add( getEntityFromLdapEntry( searchResults.getEntry(), sequence++, orgUnit.getContextId()
) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "findOrgs search val [" + orgUnit.getName() + "] type [" + orgUnit.getType()
+                + "] root [" + orgUnitRoot + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( orgUnit.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_SEARCH_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_SEARCH_FAILED_USER;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "findOrgs search val [" + orgUnit.getName() + "] type [" + orgUnit.getType()
+                + "] root [" + orgUnitRoot + "] caught CursorException=" + e;
+            int errCode;
+
+            if ( orgUnit.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_SEARCH_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_SEARCH_FAILED_USER;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return orgUnitList;
+    }
+
+
+    /**
+     *
+     * @param orgUnit
+     * @return
+     * @throws FinderException
+     */
+    Set<String> getOrgs( OrgUnit orgUnit ) throws FinderException
+    {
+        Set<String> ouSet = new TreeSet<String>( String.CASE_INSENSITIVE_ORDER
);
+        LdapConnection ld = null;
+        String orgUnitRoot = getOrgRoot( orgUnit );
+
+        try
+        {
+            String filter = "(objectclass=" + ORGUNIT_OBJECT_CLASS_NM + ")";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, orgUnitRoot,
+                SearchScope.ONELEVEL, filter, ORGUNIT_ATR, false, GlobalIds.BATCH_SIZE );
+
+            while ( searchResults.next() )
+            {
+                ouSet.add( getAttribute( searchResults.getEntry(), SchemaConstants.OU_AT
) );
+            }
+
+            searchResults.close();
+        }
+        catch ( LdapException e )
+        {
+            String error = "getOrgs type [" + orgUnit.getType() + "] root [" + orgUnitRoot
+                + "] caught LdapException=" + e;
+            int errCode;
+
+            if ( orgUnit.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_GET_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_GET_FAILED_USER;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "getOrgs type [" + orgUnit.getType() + "] root [" + orgUnitRoot
+                + "] caught CursorException=" + e;
+            int errCode;
+
+            if ( orgUnit.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_GET_FAILED_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_GET_FAILED_USER;
+            }
+
+            throw new FinderException( errCode, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return ouSet;
+    }
+
+
+    /**
+      *
+      * @param orgUnit
+      * @return
+      * @throws FinderException
+      */
+    List<Graphable> getAllDescendants( OrgUnit orgUnit ) throws FinderException
+    {
+        String orgUnitRoot = getOrgRoot( orgUnit );
+        String[] DESC_ATRS =
+            { SchemaConstants.OU_AT, GlobalIds.PARENT_NODES };
+        List<Graphable> descendants = new ArrayList<>();
+        LdapConnection ld = null;
+        String filter = null;
+
+        try
+        {
+            filter = GlobalIds.FILTER_PREFIX + ORGUNIT_OBJECT_CLASS_NM + ")("
+                + GlobalIds.PARENT_NODES + "=*))";
+            ld = getAdminConnection();
+            SearchCursor searchResults = search( ld, orgUnitRoot,
+                SearchScope.ONELEVEL, filter, DESC_ATRS, false, GlobalIds.BATCH_SIZE );
+            long sequence = 0;
+
+            while ( searchResults.next() )
+            {
+                descendants.add( unloadDescendants( searchResults.getEntry(), sequence++,
orgUnit.getContextId() ) );
+            }
+        }
+        catch ( LdapException e )
+        {
+            String error = "getAllDescendants filter [" + filter + "] caught LdapException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        catch ( CursorException e )
+        {
+            String error = "getAllDescendants filter [" + filter + "] caught CursorException="
+                + e.getMessage();
+            throw new FinderException( GlobalErrIds.ARLE_SEARCH_FAILED, error, e );
+        }
+        finally
+        {
+            closeAdminConnection( ld );
+        }
+
+        return descendants;
+    }
+
+
+    /**
+     * Creates a new Dn for the given orgUnit
+     *  
+     * @param orgUnit The orgUnit
+     * @return A Dn
+     * @throws LdapInvalidDnException If the DN is invalid 
+     */
+    private Dn getDn( OrgUnit orgUnit )
+    {
+        Dn dn = null;
+
+        try
+        {
+            switch ( orgUnit.type )
+            {
+                case USER:
+                    dn = new Dn( SchemaConstants.OU_AT + "=" + orgUnit.getName(), getRootDn(
orgUnit.getContextId(),
+                        GlobalIds.OSU_ROOT ) );
+                    break;
+
+                case PERM:
+                    dn = new Dn( SchemaConstants.OU_AT + "=" + orgUnit.getName(), getRootDn(
orgUnit.getContextId(),
+                        GlobalIds.PSU_ROOT ) );
+                    break;
+
+                default:
+                    String warning = "getDn invalid type";
+                    LOG.warn( warning );
+                    break;
+            }
+
+            return dn;
+        }
+        catch ( LdapInvalidDnException lide )
+        {
+            LOG.error( lide.getMessage() );
+            throw new RuntimeException( lide.getMessage() );
+        }
+    }
+
+
+    /**
+     *
+     * @param orgUnit
+     * @return
+     */
+    private String getOrgRoot( OrgUnit orgUnit )
+    {
+        String dn = null;
+
+        switch ( orgUnit.type )
+        {
+            case USER:
+                dn = getRootDn( orgUnit.getContextId(), GlobalIds.OSU_ROOT );
+                break;
+
+            case PERM:
+                dn = getRootDn( orgUnit.getContextId(), GlobalIds.PSU_ROOT );
+                break;
+
+            default:
+                String warning = "getOrgRootDn invalid type";
+                LOG.warn( warning );
+                break;
+        }
+
+        return dn;
+    }
+
+
+    /**
+    *
+    * @param le
+    * @param sequence
+    * @param contextId
+    * @return
+     * @throws LdapInvalidAttributeValueException 
+    * @throws LdapException
+    */
+    private Graphable unloadDescendants( Entry le, long sequence, String contextId )
+        throws LdapInvalidAttributeValueException
+    {
+        OrgUnit entity = new ObjectFactory().createOrgUnit();
+        entity.setSequenceId( sequence );
+        entity.setName( getAttribute( le, SchemaConstants.OU_AT ) );
+        entity.setParents( getAttributeSet( le, GlobalIds.PARENT_NODES ) );
+
+        return entity;
+    }
+
+
+    /**
+     *
+     * @param le
+     * @param sequence
+     * @param contextId
+     * @return
+     * @throws LdapInvalidAttributeValueException 
+     * @throws LdapException
+     */
+    private OrgUnit getEntityFromLdapEntry( Entry le, long sequence, String contextId )
+        throws LdapInvalidAttributeValueException
+    {
+        OrgUnit entity = new ObjectFactory().createOrgUnit();
+        entity.setSequenceId( sequence );
+        entity.setId( getAttribute( le, GlobalIds.FT_IID ) );
+        entity.setName( getAttribute( le, SchemaConstants.OU_AT ) );
+        entity.setDescription( getAttribute( le, SchemaConstants.DESCRIPTION_AT ) );
+        String dn = le.getDn().getName();
+
+        if ( dn.contains( getRootDn( contextId, GlobalIds.PSU_ROOT ) ) )
+        {
+            entity.setType( OrgUnit.Type.PERM );
+            //entity.setParents(PsoUtil.getParents(entity.getName().toUpperCase(), contextId));
+            entity.setChildren( PsoUtil.getChildren( entity.getName().toUpperCase(), contextId
) );
+        }
+        else if ( dn.contains( getRootDn( contextId, GlobalIds.OSU_ROOT ) ) )
+        {
+            entity.setType( OrgUnit.Type.USER );
+            //entity.setParents(UsoUtil.getParents(entity.getName().toUpperCase(), contextId));
+            entity.setChildren( UsoUtil.getChildren( entity.getName().toUpperCase(), contextId
) );
+        }
+
+        entity.setParents( getAttributeSet( le, GlobalIds.PARENT_NODES ) );
+
+        return entity;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/ba64d26a/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitP.java b/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitP.java
new file mode 100755
index 0000000..424dfa0
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/impl/OrgUnitP.java
@@ -0,0 +1,470 @@
+/*
+ *   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.apache.directory.fortress.core.impl;
+
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.directory.fortress.core.model.Graphable;
+import org.apache.directory.fortress.core.model.OrgUnit;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.model.VUtil;
+import org.apache.directory.fortress.core.util.cache.Cache;
+import org.apache.directory.fortress.core.util.cache.CacheMgr;
+
+
+/**
+ * Process module for the OrgUnit entity. The Fortress OrgUnit data set can be associated
with two entities:
+ * {@link org.apache.directory.fortress.core.model.User} class or {@link org.apache.directory.fortress.core.model.PermObj}
class.  The OrgUnit entity itself is stored in two separate locations in the ldap tree one
+ * for each entity listed above.  The type of OU entity is set via the enum attribute {@link
org.apache.directory.fortress.core.model.OrgUnit.Type} which is equal to 'PERM' or 'USER'.
+ * This class performs data validations.  The methods of this class are called by internal
Fortress manager impl classes
+ * {@link DelAdminMgrImpl} and {@link DelReviewMgrImpl} but is also called by {@link org.apache.directory.fortress.core.impl.PermP#validate}
method and {@link org.apache.directory.fortress.core.impl.UserP#validate} functions
+ * which ensure the entities are related to valid OU entries. This class is not intended
to be called external
+ * to Fortress Core itself.  This class will accept Fortress entity {@link org.apache.directory.fortress.core.model.OrgUnit},
validate its contents and forward on to it's
+ * corresponding DAO class {@link OrgUnitDAO} for data access.
+ * <p>
+ * Class will throw {@link SecurityException} to caller in the event of security policy,
data constraint violation or system
+ * error internal to DAO object. This class will forward DAO exceptions ({@link org.apache.directory.fortress.core.FinderException},
+ * {@link org.apache.directory.fortress.core.CreateException},{@link org.apache.directory.fortress.core.UpdateException},{@link
org.apache.directory.fortress.core.RemoveException}),
+ *  or {@link org.apache.directory.fortress.core.ValidationException} as {@link SecurityException}s
with appropriate
+ * error id from {@link GlobalErrIds}.
+ * <p>
+ * This class uses synchronized data sets ({@link #ouCache} but is thread safe.
+ * <p/>
+
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public final class OrgUnitP
+{
+    // init the logger:
+    private static final String CLS_NM = OrgUnitP.class.getName();
+    private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+    // these fields are used to synchronize access to the above static pools:
+    private static final ReadWriteLock userPoolLock = new ReentrantReadWriteLock();
+    private static final ReadWriteLock permPoolLock = new ReentrantReadWriteLock();
+    private static Cache ouCache;
+
+    // DAO class for OU data sets must be initializer before the other statics:
+    private static final OrgUnitDAO oDao = new OrgUnitDAO();
+    private static final String USER_OUS = "user.ous";
+    private static final String PERM_OUS = "perm.ous";
+    private static final String FORTRESS_OUS = "fortress.ous";
+
+    static
+    {
+        CacheMgr cacheMgr = CacheMgr.getInstance();
+        OrgUnitP.ouCache = cacheMgr.getCache( FORTRESS_OUS );
+    }
+
+
+    /**
+     * Package private constructor.
+     */
+    OrgUnitP()
+    {
+    }
+
+
+    /**
+     * This function uses a case insensitive search.
+     * @param entity
+     * @return true if valid, false otherwise.
+     */
+    /* No Qualifier */boolean isValid( OrgUnit entity )
+    {
+        boolean result = false;
+
+        if ( entity.type == OrgUnit.Type.USER )
+        {
+            try
+            {
+                userPoolLock.readLock().lock();
+                Set<String> userPool = getUserSet( entity );
+
+                if ( userPool != null )
+                {
+                    result = userPool.contains( entity.getName() );
+                }
+            }
+            finally
+            {
+                userPoolLock.readLock().unlock();
+            }
+        }
+        else
+        {
+            try
+            {
+                permPoolLock.readLock().lock();
+                Set<String> permPool = getPermSet( entity );
+
+                if ( permPool != null )
+                {
+                    result = permPool.contains( entity.getName() );
+                }
+            }
+            finally
+            {
+                permPoolLock.readLock().unlock();
+            }
+        }
+
+        return result;
+    }
+
+
+    /**
+     * Loads the User set for an orgUnit
+     * @param orgUnit The orgUnit
+     * @return The set of associated User
+     */
+    private static Set<String> loadUserSet( OrgUnit orgUnit )
+    {
+        Set<String> ouUserSet = null;
+
+        try
+        {
+            ouUserSet = oDao.getOrgs( orgUnit );
+        }
+        catch ( SecurityException se )
+        {
+            String warning = "loadOrgSet static initializer caught SecurityException=" +
se;
+            LOG.info( warning, se );
+        }
+
+        ouCache.put( getKey( USER_OUS, orgUnit.getContextId() ), ouUserSet );
+
+        return ouUserSet;
+    }
+
+
+    /**
+     * Loads the Perm set for an orgUnit
+     * @param orgUnit The orgUnit
+     * @return The set of associated Perms
+     */
+    private static Set<String> loadPermSet( OrgUnit orgUnit )
+    {
+        Set<String> ouPermSet = null;
+
+        try
+        {
+            ouPermSet = oDao.getOrgs( orgUnit );
+        }
+        catch ( SecurityException se )
+        {
+            String warning = "loadOrgSet static initializer caught SecurityException=" +
se;
+            LOG.info( warning, se );
+        }
+
+        ouCache.put( getKey( PERM_OUS, orgUnit.getContextId() ), ouPermSet );
+
+        return ouPermSet;
+    }
+
+
+    /**
+     *
+     * @param orgUnit will be a Perm OU.
+     * @return Set containing the OU mapping to a Perm type and tenant.
+     */
+    private static Set<String> getPermSet( OrgUnit orgUnit )
+    {
+        @SuppressWarnings("unchecked")
+        Set<String> permSet = ( Set<String> ) ouCache.get( getKey( PERM_OUS,
orgUnit.getContextId() ) );
+
+        if ( permSet == null )
+        {
+            permSet = loadPermSet( orgUnit );
+        }
+
+        return permSet;
+    }
+
+
+    /**
+     *
+     * @param orgUnit will be a User OU
+     * @return Set containing the OU mapping to the user type and tenant.
+     */
+    private static Set<String> getUserSet( OrgUnit orgUnit )
+    {
+        @SuppressWarnings("unchecked")
+        Set<String> userSet = ( Set<String> ) ouCache.get( getKey( USER_OUS,
orgUnit.getContextId() ) );
+
+        if ( userSet == null )
+        {
+            userSet = loadUserSet( orgUnit );
+        }
+
+        return userSet;
+    }
+
+
+    /**
+     * Return a fully populated OrgUnit entity for a given Perm or User orgUnitId.  If matching
record not found a
+     * SecurityException will be thrown.
+     *
+     * @param entity contains full orgUnit name used for User or Perm OU data sets in directory.
+     * @return OrgUnit entity containing all attributes associated with ou in directory.
+     * @throws SecurityException in the event OrgUnit not found or DAO search error.
+     */
+    OrgUnit read( OrgUnit entity ) throws SecurityException
+    {
+        validate( entity, false );
+
+        return oDao.findByKey( entity );
+    }
+
+
+    /**
+     * Will search either User or Perm OrgUnit data sets depending on which type is passed.
+     * The search string that contains full or partial OrgUnit name associated with OU node
in directory.
+     *
+     * @param orgUnit contains full or partial OU name.
+     * @return List of type OrgUnit containing fully populated matching OU entities.  If
no records found this will be empty.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    List<OrgUnit> search( OrgUnit orgUnit ) throws SecurityException
+    {
+        // Call the finder.
+        return oDao.findOrgs( orgUnit );
+    }
+
+
+    /**
+     * Adds a new OrgUnit to directory. The OrgUnit type enum will determine which data set
insertion will
+     * occur - User or Perm.  The OrgUnit entity input will be validated to ensure that:
+     * orgUnit name is present and type is specified, and reasonability checks on all of
the other populated values.
+     *
+     * @param entity OrgUnit contains data targeted for insertion.
+     * @return OrgUnit entity copy of input + additional attributes (internalId) that were
added by op.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    OrgUnit add( OrgUnit entity ) throws SecurityException
+    {
+        validate( entity, false );
+        OrgUnit oe = oDao.create( entity );
+
+        if ( entity.getType() == OrgUnit.Type.USER )
+        {
+            try
+            {
+                userPoolLock.writeLock().lock();
+
+                Set<String> userPool = getUserSet( entity );
+
+                if ( userPool != null )
+                {
+                    userPool.add( entity.getName() );
+                }
+            }
+            finally
+            {
+                userPoolLock.writeLock().unlock();
+            }
+        }
+        else
+        {
+            try
+            {
+                permPoolLock.writeLock().lock();
+
+                Set<String> permPool = getPermSet( entity );
+
+                if ( permPool != null )
+                {
+                    permPool.add( entity.getName() );
+                }
+            }
+            finally
+            {
+                permPoolLock.writeLock().unlock();
+            }
+        }
+
+        return oe;
+    }
+
+
+    /**
+     * Updates existing OrgUnit in directory. The OrgUnit type enum will determine which
data set insertion will
+     * occur - User or Perm.  The OrgUnit entity input will be validated to ensure that:
+     * orgUnit name is present, and reasonability checks on all of the other populated values.
+     * Null or empty attributes are ignored.
+     *
+     * @param entity OrgUnit contains data targeted for updating.  Null attributes ignored.
+     * @return OrgUnit entity copy of input + additional attributes (internalId) that were
updated by op.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    OrgUnit update( OrgUnit entity ) throws SecurityException
+    {
+        validate( entity, false );
+
+        return oDao.update( entity );
+    }
+
+
+    /**
+     * Remove the parent attribute from the OrgUnit entry in directory. The OrgUnit type
enum will determine which data set insertion will
+     * occur - User or Perm.  The OrgUnit entity input will be validated to ensure that:
+     * orgUnit name is present.
+     *
+     * @param entity OrgUnit contains data targeted for updating.  Null attributes ignored.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    void deleteParent( OrgUnit entity ) throws SecurityException
+    {
+        validate( entity, false );
+        oDao.deleteParent( entity );
+    }
+
+
+    /**
+     * This method performs a "hard" delete.  It completely the OrgUnit node from the ldap
directory.
+     * The OrgUnit type enum will determine where deletion will occur - User or Perm OU data
sets.
+     * OrgUnit entity must exist in directory prior to making this call else exception will
be thrown.
+     *
+     * @param entity Contains the name of the OrgUnit node targeted for deletion.
+     * @return OrgUnit entity copy of input.
+     * @throws SecurityException in the event of data validation or DAO system error.
+     */
+    OrgUnit delete( OrgUnit entity ) throws SecurityException
+    {
+        oDao.remove( entity );
+
+        if ( entity.getType() == OrgUnit.Type.USER )
+        {
+            try
+            {
+                userPoolLock.writeLock().lock();
+                Set<String> userPool = getUserSet( entity );
+
+                if ( userPool != null )
+                {
+                    userPool.remove( entity.getName() );
+                }
+            }
+            finally
+            {
+                userPoolLock.writeLock().unlock();
+            }
+        }
+        else
+        {
+            try
+            {
+                permPoolLock.writeLock().lock();
+                Set<String> permPool = getPermSet( entity );
+
+                if ( permPool != null )
+                {
+                    permPool.remove( entity.getName() );
+                }
+            }
+            finally
+            {
+                permPoolLock.writeLock().unlock();
+            }
+        }
+
+        return entity;
+    }
+
+
+    /**
+     * Return all OrgUnits that have a parent assignment.  This used for hierarchical processing.
+     *
+     * @param orgUnit will either be a User or Perm OU.
+     * @return List of type OrgUnit containing {@link OrgUnit#name} and {@link OrgUnit#parents}
populated.
+     * @throws SecurityException in the event of DAO search error.
+     */
+    List<Graphable> getAllDescendants( OrgUnit orgUnit ) throws SecurityException
+    {
+        return oDao.getAllDescendants( orgUnit );
+    }
+
+
+    /**
+     * Method will perform simple validations to ensure the integrity of the OrgUnit entity
targeted for insertion
+     * or updating in directory.  This method will ensure the name and type enum are specified.
 It will also perform
+     * reasonability check on description if set.
+     *
+     * @param entity   contains the enum type to validate
+     * @param isUpdate not used at this time.
+     * @throws SecurityException thrown in the event the attribute is null.
+     */
+    private void validate( OrgUnit entity, boolean isUpdate )
+        throws SecurityException
+    {
+        VUtil.safeText( entity.getName(), GlobalIds.OU_LEN );
+
+        if ( StringUtils.isNotEmpty( entity.getDescription() ) )
+        {
+            VUtil.description( entity.getDescription() );
+        }
+
+        if ( entity.getType() == null )
+        {
+            String error = "validate null or empty org unit type";
+            int errCode;
+
+            if ( entity.getType() == OrgUnit.Type.PERM )
+            {
+                errCode = GlobalErrIds.ORG_TYPE_NULL_PERM;
+            }
+            else
+            {
+                errCode = GlobalErrIds.ORG_TYPE_NULL_USER;
+            }
+
+            throw new SecurityException( errCode, error );
+        }
+    }
+
+
+    /**
+     * Build a key that is composed of the OU type ({@link #USER_OUS} or {@link #PERM_OUS})
and the contextId which is the id of tenant.
+     *
+     * @param type either {@link #USER_OUS} or {@link #PERM_OUS}.
+     * @param contextId maps to sub-tree in DIT, for example ou=contextId, dc=jts, dc = com.
+     * @return key mapping to this tenant's cache entry.
+     */
+    private static String getKey( String type, String contextId )
+    {
+        String key = type;
+
+        if ( StringUtils.isNotEmpty( contextId ) && !contextId.equalsIgnoreCase(
GlobalIds.NULL ) )
+        {
+            key += ":" + contextId;
+        }
+
+        return key;
+    }
+}
\ No newline at end of file


Mime
View raw message