⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dxattributes.java

📁 JAVA开源LDAP浏览器jxplorer的源码!
💻 JAVA
📖 第 1 页 / 共 4 页
字号:



    /**
     *    <p>Returns the set of attributes that are in the newSet, but
     *    not in the old set, excluding the rdnclass).</p>
     *
     *    <p>It also returns partial attributes that contain values that
     *    are in the newSet but not in the oldSet, when either a)
     *    either attribute has a size larger than one, or b) the attribute has
     *    a distinguished value.</p>
     *
     *    <p>The logic for case a) is that we can use adds and deletes on
     *    individual attributes to simulate a 'replace' operation, but we
     *    need to avoid doing this for single valued attributes (for which
     *    we *always* use replace).  So if Attribute A has values {1,2,3},
     *    and is changed to A' {1,3,5,6}, this method returns an 'add' {5,6}.</p>
     *
     *    <p>The logic for case b) is that we cannot use 'replace' on an
     *    attribute with a naming value in it, so we *must* use adds and
     *    deletes - and we'll have to take our chances that it is not
     *    single valued. (Possibly later on we can check this from schema).
     *    This method cannot change the distinguished value, but produces an
     *    'add' for any other changed.  So if, for entry cn=fred, Attribute cn
     *    has values {fred,erik}
     *    and cn' has values {fred, nigel], this method produces an 'add' {nigel}.</p>
     *
     *
     *    @param newRDN the new RDN of the entry that is being created
     *           (usually this is the same as the RDN of the original entry)
     *           May be null if it is not to be checked.
     *    @param oldSet the set of already existing attributes
     *    @param newSet the set of new attributes to test
     *    @return attributes that must be added to the object.
     */

    public static DXAttributes getAdditionSet(RDN newRDN, Attributes oldSet, Attributes newSet)
		throws NamingException
    {
        DXAttributes additionSet = new DXAttributes();
        NamingEnumeration listOfNewAttributes = newSet.getAll();

        while (listOfNewAttributes.hasMore())
        {
            Attribute newAtt = (Attribute)listOfNewAttributes.next();

            String attributeName = newAtt.getID();

            boolean isNamingAttribute = newRDN.contains(attributeName);

            Attribute oldAtt = oldSet.get(attributeName);

            if (! emptyAtt(newAtt))            // don't add empty atts!
            {
                /*
                 *    Check for simple "whole attribute" adds
				 *    if the old Att is null, or only had null values add it.
				 *    (It was probably created by the browser,
				 *     and doesn't exist in the database)
                 */

                if ((isNamingAttribute == false) && (oldAtt == null || emptyAtt(oldAtt)))
				{
                    additionSet.put(newAtt);
				}

                /*
                 *   Check for attribute values that have been changed in attributes
                 *   that are larger than 1, or that are naming attributes
                 */
// TODO: - clean this up for DSML etc. ...

                else if (isNamingAttribute || (oldAtt.size() > 1 || newAtt.size() > 1 ))
                {
                    DXNamingEnumeration valuesToAdd = getMissingValues(oldAtt.getAll(), newAtt.getAll());

                    // check for distinguished value, and ignore it...
                    if (isNamingAttribute)
                    	removeAnyDistinguishedValues(newRDN, attributeName, valuesToAdd);

                    if (valuesToAdd.size()>0)
                        additionSet.put(new DXAttribute(attributeName, valuesToAdd));
                }
            }
        }
        return additionSet;
    }



    /**
     *    <p>Returns all single valued attributes whose values have changed -
     *    that is, exist in both the new set and the old set, but have different values.
     *    Note that this function ignores the naming attribute.</p>
     *
	 *    <p>We need this function to cope with mandatory single valued attributes
	 *       (otherwise we could just use add and delete).</p>
	 *
     *    <p>All other attribute combinations are handled by attribute value adds and
     *    deletes. (This is slightly more efficient, and is required to modify
     *    non-distinguished values of the naming attribute anyway).</p>
     *
     *    @param newRDN the RDN of the newer entry.
     *           (usually this is the same as the RDN of the original entry)
     *           May be null if it is not to be checked.
     *    @param oldSet the set of already existing attributes
     *    @param newSet the set of new attributes to test

     *    @return attributes that require updating
     */

	// LOGIC NOTE - only replace attributes that are single valued (old & new) and NOT naming values.

    public static DXAttributes getReplacementSet(RDN newRDN, Attributes oldSet, Attributes newSet)
        throws NamingException
    {
        DXAttributes replacementSet = new DXAttributes();

        NamingEnumeration listOfNewAttributes = newSet.getAll();

        while (listOfNewAttributes.hasMore())                                // find changed attributes
        {
            Attribute newAtt = (Attribute)listOfNewAttributes.next();

			if (newAtt != null && newAtt.size() == 1)  // only consider a single valued new attribute
			{
	            String attributeName = newAtt.getID();

	            if (newRDN.contains(attributeName) == false) // skip any naming attributes
				{
		            Attribute oldAtt = oldSet.get(attributeName);

		            if (oldAtt != null && oldAtt.size() == 1)	// only look at changed single valued attributes.
		            {
		                // if  a single valued attribute has changed, make it a 'replace' op.
		                if (attributesEqual(newAtt, oldAtt)==false)
		                    replacementSet.put(newAtt);
		            }
	            }
			}
        }
        return replacementSet;
    }



    /**
     *    <p>Returns the set of attributes that are in the oldSet, but
     *    not in the new set, and thus must be deleted. </p>
     *
     *    <p>It also returns the set of attribute *values* that are in
     *    the old set, but not in the new set.  E.g. if attribute A
     *    has values {1,2,3,4}, and the new attribute A' has {1,4,6,7},
     *    this returns {2,3} for deletion.</p>
     *
	 *    <p>This method will ignore naming values, but will correctly
	 *    handle other values of the naming attribute.</p>
	 *
	 *    @param newRDN the RDN of the newer entry.
     *           (usually this is the same as the RDN of the original entry).
     *           May be null if it is not to be checked.
     *    @param oldSet the set of already existing attributes
     *    @param newSet the set of new attributes to test
     */

    public static DXAttributes getDeletionSet(RDN newRDN, Attributes oldSet, Attributes newSet)
		throws NamingException
    {
        DXAttributes deletionSet = new DXAttributes();

        NamingEnumeration listOfOldAttributes = oldSet.getAll();

        while (listOfOldAttributes.hasMore())
        {
            Attribute oldAtt = (Attribute)listOfOldAttributes.next();

            if (! emptyAtt(oldAtt))            // don't delete empty atts!
            {
	            String attributeName = oldAtt.getID();

	            boolean isNamingAttribute = newRDN.contains(attributeName);

	            Attribute newAtt = newSet.get(attributeName);

                if (newAtt == null)
               		newAtt = new DXAttribute(attributeName);

                /*
                 *    Check for simple "whole attribute" deletes
                 */

                if (emptyAtt(newAtt) && !isNamingAttribute)
                {
                    deletionSet.put(newAtt);
                }

                /*
                 *   Check for attribute values that have been dropped, in attributes
                 *   that are larger than 1
                 */

                else if (isNamingAttribute || oldAtt.size() > 1 || newAtt.size() > 1 )
                {
                    DXNamingEnumeration valuesToDelete = getMissingValues(newAtt.getAll(), oldAtt.getAll());
                    // check for distinguished value, and ignore it...
                    if (isNamingAttribute)
                    	removeAnyDistinguishedValues(newRDN, attributeName, valuesToDelete);

                    if (valuesToDelete.size()>0)
                        deletionSet.put(new DXAttribute(attributeName, valuesToDelete));
                }
            }
        }
        return deletionSet;
    }



	/**
	 *    Checks two 'Attribute' objects for equality.
     *    XXX - should this be moved to DXAttribute?
	 */

	private static boolean attributesEqual(Attribute a, Attribute b)
	    throws NamingException
	{
	    // sanity checks...
	    if (a == null && b == null) return true;
	    if (a == null || b == null) return false;
	    if (a.size() == 0 && b.size() == 0) return true;
	    if (a.size() != b.size()) return false;
	    if (a.get() == null && b.get() == null) return true;
	    if (a.get() == null || b.get() == null) return false;
	    if (a.getID().equalsIgnoreCase(b.getID())==false) return false;


	    try
	    {
	        Object[] A = CBArray.enumerationToArray(a.getAll());
	        Object[] B = CBArray.enumerationToArray(b.getAll());
	        return CBArray.isUnorderedEqual(A,B);
	    }
	    catch (NamingException e)
	    {
	        log.log(Level.WARNING, "Naming Exception testing attributes " + a.getID() + " & " + b.getID() + " in DXAttributes:attributesEqual()", e);
	    }
	    return false; // only here if error occurred.
	}

	/**
	 *    Checks whether two 'Attributes' objects are equivalent (including naming attributes, if any).
	 */

	public static boolean attributesEqual(Attributes a, Attributes b)
	{
        if (a == null && b == null) return true;
        if (a == null || b == null) return false;
        return a.equals(b);
    }

    public boolean equals(Object o)
    {
        if (o == null) return false;

        try
        {
            if (o instanceof Attributes)
                return this.equals((Attributes) o);
        }
        catch (NamingException e)
        {
            return false;  // suppress exception :-(...
        }

        return false;
    }

    public boolean equals(Attributes atts) throws NamingException
    {
        // some quick and simple equality checks
        if (atts == null) return false;
        if (size() == 0 && atts.size() == 0) return true;
        if (size() != atts.size()) return false;

        // at this stage, we have equality candidates - two equally sized attributes...

        NamingEnumeration testAtts = getAll();
        while (testAtts.hasMore())                                // find changed attributes
        {
            Attribute testAtt = (Attribute)testAtts.next();
            String ID = testAtt.getID();

            Attribute bAtt = atts.get(ID);

            if ( emptyAtt(bAtt) ^ emptyAtt(testAtt) ) return false;

            if (attributesEqual(testAtt, bAtt) == false) return false;
        }

        // if we're here, the attributes must be equal!

        return true;
    }

    /**
	 *	Checks the naming enumeration and removes any distinguished values that
	 *  occur in the RDN.
	 *  @param newRDN the rdn to check for values in
	 *  @param attributeName the name of the attribute (potentially) in the RDN
	 *  @param values the list of values to potentially remove the distinguished value from
	 */

    private static void removeAnyDistinguishedValues(RDN newRDN, String attributeName, DXNamingEnumeration values)
    {
        String distinguishedValue = newRDN.getRawVal(attributeName);
        values.remove(distinguishedValue);  // remove dist. val. (if it is there)
    }


    /**
     *    Returns all the values in B that are missing in A.  (i.e. return B minus (B union A)).
     *    @param A the list of values to exclude.
     *    @param B the list of values to include.
     *    @return all elements of B not found in A.
     */

    static private DXNamingEnumeration getMissingValues(NamingEnumeration A, NamingEnumeration B)
        throws NamingException
    {
        DXNamingEnumeration ret = new DXNamingEnumeration(B);

        if (A == null) return ret;

        while (A.hasMore())
        {
            ret.remove(A.next());
        }
        return ret;
    }

//    public DirContext getSchema() { return schema; }

    public String[] toIDStringArray()
    {
        DXNamingEnumeration ret = new DXNamingEnumeration(getIDs());
        return ret.toStringArray();
    }

    /**
     *    A quick test - do we have any numeric OIDs
     *
     */
    public boolean hasOIDs()
    {
        return (attOIDs.size()>0);
    }

    /**
     *    Utility ftn: checks that an attribute is not null and has at least
     *    one non-null value.
     */
    public static boolean emptyAtt(Attribute att)
    {
         return DXAttribute.isEmpty(att);
    }



}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -