directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From seelm...@apache.org
Subject svn commit: r1545951 - in /directory/shared/trunk/ldap/model/src: main/java/org/apache/directory/api/ldap/model/schema/ test/java/org/apache/directory/api/ldap/model/schema/
Date Wed, 27 Nov 2013 07:27:08 GMT
Author: seelmann
Date: Wed Nov 27 07:27:08 2013
New Revision: 1545951

URL: http://svn.apache.org/r1545951
Log:
DIRSTUDIO-959 (Exporting schemas as OpenLDAP files does not use proper escaping):
* Moved utilities to render ObjectClass and AttributeType to new SchemaObjectRenderer class
* Introduced two styles for rendering schema object: for usage in subschema subentry and for writing OpenLDAP like schema files
* Removed redundant schema object render implementations

Added:
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaObjectRenderer.java
    directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/AttributeTypeTest.java
    directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/SchemaObjectRendererTest.java
Modified:
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AttributeType.java
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DescriptionUtils.java
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/ObjectClass.java
    directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaUtils.java
    directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/ObjectClassTest.java

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AttributeType.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AttributeType.java?rev=1545951&r1=1545950&r2=1545951&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AttributeType.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/AttributeType.java Wed Nov 27 07:27:08 2013
@@ -531,7 +531,7 @@ public class AttributeType extends Abstr
      */
     public String toString()
     {
-        return objectType + " " + DescriptionUtils.getDescription( this );
+        return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this );
     }
 
 

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DescriptionUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DescriptionUtils.java?rev=1545951&r1=1545950&r2=1545951&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DescriptionUtils.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/DescriptionUtils.java Wed Nov 27 07:27:08 2013
@@ -56,131 +56,6 @@ public final class DescriptionUtils
 
 
     /**
-     * Generates the description using the AttributeTypeDescription as defined
-     * by the syntax: 1.3.6.1.4.1.1466.115.121.1.3. Only the right hand side of
-     * the description starting at the opening parenthesis is generated: that
-     * is 'AttributeTypeDescription = ' is not generated.
-     * 
-     * <pre>
-     *  AttributeTypeDescription = &quot;(&quot; whsp
-     *     numericoid whsp                ; AttributeType identifier
-     *     [ &quot;NAME&quot; qdescrs ]             ; name used in AttributeType
-     *     [ &quot;DESC&quot; qdstring ]            ; description
-     *     [ &quot;OBSOLETE&quot; whsp ]
-     *     [ &quot;SUP&quot; woid ]                 ; derived from parent AttributeType
-     *     [ &quot;EQUALITY&quot; woid              ; Matching Rule name
-     *     [ &quot;ORDERING&quot; woid              ; Matching Rule name
-     *     [ &quot;SUBSTR&quot; woid ]              ; Matching Rule name
-     *     [ &quot;SYNTAX&quot; whsp noidlen whsp ] ; see section 4.3 RFC 2252
-     *     [ &quot;SINGLE-VALUE&quot; whsp ]        ; default multi-valued
-     *     [ &quot;COLLECTIVE&quot; whsp ]          ; default not collective
-     *     [ &quot;NO-USER-MODIFICATION&quot; whsp ]; default user modifiable
-     *     [ &quot;USAGE&quot; whsp AttributeUsage ]; default userApplications
-     *     whsp &quot;)&quot;
-     * </pre>
-     * 
-     * @param attributeType
-     *            the attributeType to generate a description for
-     * @return the AttributeTypeDescription Syntax for the attributeType in a
-     *         pretty formated string
-     */
-    public static String getDescription( AttributeType attributeType )
-    {
-        StringBuilder buf = new StringBuilder( "( " );
-        buf.append( attributeType.getOid() );
-        buf.append( '\n' );
-
-        if ( attributeType.getNames().size() != 0 )
-        {
-            buf.append( " NAME " );
-            getQDescrs( buf, attributeType.getNames() );
-        }
-
-        if ( attributeType.getDescription() != null )
-        {
-            buf.append( " DESC " );
-            buf.append( attributeType.getDescription() );
-            buf.append( '\n' );
-        }
-
-        if ( attributeType.isObsolete() )
-        {
-            buf.append( " OBSOLETE\n" );
-        }
-
-        if ( attributeType.getSuperior() != null )
-        {
-            buf.append( " SUP " );
-            buf.append( attributeType.getSuperiorName() );
-            buf.append( '\n' );
-        }
-
-        if ( attributeType.getEquality() != null )
-        {
-            buf.append( " EQUALITY " );
-            buf.append( attributeType.getEqualityName() );
-            buf.append( '\n' );
-        }
-
-        if ( attributeType.getOrdering() != null )
-        {
-            buf.append( " ORDERING " );
-            buf.append( attributeType.getOrderingName() );
-            buf.append( '\n' );
-        }
-
-        if ( attributeType.getSubstring() != null )
-        {
-            buf.append( " SUBSTR " );
-            buf.append( attributeType.getSubstringName() );
-            buf.append( '\n' );
-        }
-
-        if ( attributeType.getSyntax() != null )
-        {
-            buf.append( " SYNTAX " );
-
-            buf.append( attributeType.getSyntaxName() );
-
-            if ( attributeType.getSyntaxLength() > 0 )
-            {
-                buf.append( '{' ).append( attributeType.getSyntaxLength() ).append( '}' );
-            }
-
-            buf.append( '\n' );
-        }
-
-        if ( attributeType.isSingleValued() )
-        {
-            buf.append( " SINGLE-VALUE\n" );
-        }
-
-        if ( attributeType.isCollective() )
-        {
-            buf.append( " COLLECTIVE\n" );
-        }
-
-        if ( !attributeType.isUserModifiable() )
-        {
-            buf.append( " NO-USER-MODIFICATION\n" );
-        }
-
-        buf.append( " USAGE " );
-        buf.append( UsageEnum.render( attributeType.getUsage() ) );
-        buf.append( '\n' );
-
-        if ( attributeType.getExtensions() != null )
-        {
-            getExtensions( buf, attributeType.getExtensions() );
-        }
-
-        buf.append( " )\n" );
-
-        return buf.toString();
-    }
-
-
-    /**
      * Generates the ComparatorDescription for a LdapComparator. Only the right 
      * hand side of the description starting at the opening parenthesis is 
      * generated: that is 'ComparatorDescription = ' is not generated.
@@ -640,96 +515,6 @@ public final class DescriptionUtils
 
 
     /**
-     * Generates the ObjectClassDescription for an ObjectClass as defined by the
-     * syntax: 1.3.6.1.4.1.1466.115.121.1.37. Only the right hand side of the
-     * description starting at the opening parenthesis is generated: that is
-     * 'ObjectClassDescription = ' is not generated.
-     * 
-     * <pre>
-     *  ObjectClassDescription = &quot;(&quot; whsp
-     *      numericoid whsp     ; ObjectClass identifier
-     *      [ &quot;NAME&quot; qdescrs ]
-     *      [ &quot;DESC&quot; qdstring ]
-     *      [ &quot;OBSOLETE&quot; whsp ]
-     *      [ &quot;SUP&quot; oids ]      ; Superior ObjectClasses
-     *      [ ( &quot;ABSTRACT&quot; / &quot;STRUCTURAL&quot; / &quot;AUXILIARY&quot; ) whsp ]
-     *                          ; default structural
-     *      [ &quot;MUST&quot; oids ]     ; AttributeTypes
-     *      [ &quot;MAY&quot; oids ]      ; AttributeTypes
-     *  whsp &quot;)&quot;
-     * </pre>
-     * 
-     * @param objectClass
-     *            the ObjectClass to generate a description for
-     * @return the description in the ObjectClassDescription syntax
-     */
-    public static String getDescription( ObjectClass objectClass )
-    {
-        StringBuilder buf = new StringBuilder( "( " );
-        buf.append( objectClass.getOid() );
-        buf.append( '\n' );
-
-        if ( ( objectClass.getNames() != null ) && ( objectClass.getNames().size() != 0 ) )
-        {
-            buf.append( " NAME " );
-            getQDescrs( buf, objectClass.getNames() );
-        }
-
-        if ( objectClass.getDescription() != null )
-        {
-            buf.append( " DESC " );
-            buf.append( objectClass.getDescription() );
-            buf.append( '\n' );
-        }
-
-        if ( objectClass.isObsolete() )
-        {
-            buf.append( " OBSOLETE\n" );
-        }
-
-        List<ObjectClass> sups = objectClass.getSuperiors();
-
-        if ( ( sups != null ) && ( sups.size() > 0 ) )
-        {
-            buf.append( " SUP " );
-            getQDStrings( buf, sups );
-        }
-
-        if ( objectClass.getType() != null )
-        {
-            buf.append( ' ' );
-            buf.append( objectClass.getType() );
-            buf.append( '\n' );
-        }
-
-        List<AttributeType> must = objectClass.getMustAttributeTypes();
-
-        if ( ( must != null ) && ( must.size() > 0 ) )
-        {
-            buf.append( " MUST " );
-            getQDStrings( buf, must );
-        }
-
-        List<AttributeType> may = objectClass.getMayAttributeTypes();
-
-        if ( ( may != null ) && ( may.size() > 0 ) )
-        {
-            buf.append( " MAY " );
-            getQDStrings( buf, may );
-        }
-
-        if ( objectClass.getExtensions() != null )
-        {
-            getExtensions( buf, objectClass.getExtensions() );
-        }
-
-        buf.append( " )\n" );
-
-        return buf.toString();
-    }
-
-
-    /**
      * Generates the SyntaxDescription for a Syntax as defined by the syntax:
      * 1.3.6.1.4.1.1466.115.121.1.54. Only the right hand side of the
      * description starting at the opening parenthesis is generated: that is

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/ObjectClass.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/ObjectClass.java?rev=1545951&r1=1545950&r2=1545951&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/ObjectClass.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/ObjectClass.java Wed Nov 27 07:27:08 2013
@@ -216,11 +216,11 @@ public class ObjectClass extends Abstrac
 
 
     /**
-     * @see Object#toString()
+     * {@inheritDoc}
      */
     public String toString()
     {
-        return objectType + " " + DescriptionUtils.getDescription( this );
+        return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this );
     }
 
 

Added: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaObjectRenderer.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaObjectRenderer.java?rev=1545951&view=auto
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaObjectRenderer.java (added)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaObjectRenderer.java Wed Nov 27 07:27:08 2013
@@ -0,0 +1,539 @@
+/*
+ *  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.api.ldap.model.schema;
+
+
+import java.util.List;
+
+import org.apache.directory.api.ldap.model.exception.LdapException;
+
+
+/**
+ * Renderer for schema objects.
+ * 
+ * Currently the following preconfigured renderers exist: 
+ * <ol>
+ * <li> {@link SchemaObjectRenderer#SUBSCHEMA_SUBENTRY_RENDERER}: renders the schema object 
+ *      without line break and with X-SCHEMA extension. To be used for building subschema subentry.
+ * <li> {@link SchemaObjectRenderer#OPEN_LDAP_SCHEMA_RENDERER}: renders the schema object in OpenLDAP schema  
+ *      format. That means is starts with schema type and contains line breaks for easier readability.
+ * </ol>
+ * <p>
+ * TODO: currently only {@link ObjectClass} and {@link AttributeType} are supported, implement other schema object types.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class SchemaObjectRenderer
+{
+    /**
+     * Preconfigured {@link SchemaObjectRenderer} that renders the schema object without line break and with
+     * X-SCHEMA extension. To be used for building subschema subentry.
+     */
+    public static final SchemaObjectRenderer SUBSCHEMA_SUBENTRY_RENDERER = new SchemaObjectRenderer(
+        Style.SUBSCHEMA_SUBENTRY_WITH_SCHEMA_NAME );
+
+    /**
+     * Preconfigured {@link SchemaObjectRenderer} that renders the schema object in OpenLDAP schema format. 
+     * That means is starts with schema type and contains line breaks for easier readability.
+     */
+    public static final SchemaObjectRenderer OPEN_LDAP_SCHEMA_RENDERER = new SchemaObjectRenderer(
+        Style.OPENLDAP_SCHEMA_PRETTY_PRINTED );
+
+    private enum Style
+    {
+        SUBSCHEMA_SUBENTRY_WITH_SCHEMA_NAME(false, false, true),
+
+        OPENLDAP_SCHEMA_PRETTY_PRINTED(true, true, false);
+
+        final boolean startWithSchemaType;
+        final boolean prettyPrint;
+        final boolean printSchemaName;
+
+
+        private Style( boolean startWithSchemaType, boolean prettyPrint, boolean printSchemaName )
+        {
+            this.startWithSchemaType = startWithSchemaType;
+            this.prettyPrint = prettyPrint;
+            this.printSchemaName = printSchemaName;
+        }
+    }
+
+    private final Style style;
+
+
+    private SchemaObjectRenderer( Style style )
+    {
+        this.style = style;
+    }
+
+
+    /**
+     * Renders an objectClass according to the Object Class 
+     * Description Syntax 1.3.6.1.4.1.1466.115.121.1.37. The syntax is
+     * described in detail within section 4.1.1. of 
+     * <a href="https://tools.ietf.org/rfc/rfc4512.txt">RFC 4512</a>
+     * which is replicated here for convenience:
+     * 
+     * <pre>
+     *  4.1.1. Object Class Definitions
+     * 
+     *   Object Class definitions are written according to the ABNF:
+     * 
+     *     ObjectClassDescription = LPAREN WSP
+     *         numericoid                 ; object identifier
+     *         [ SP &quot;NAME&quot; SP qdescrs ]   ; short names (descriptors)
+     *         [ SP &quot;DESC&quot; SP qdstring ]  ; description
+     *         [ SP &quot;OBSOLETE&quot; ]          ; not active
+     *         [ SP &quot;SUP&quot; SP oids ]       ; superior object classes
+     *         [ SP kind ]                ; kind of class
+     *         [ SP &quot;MUST&quot; SP oids ]      ; attribute types
+     *         [ SP &quot;MAY&quot; SP oids ]       ; attribute types
+     *         extensions WSP RPAREN
+     * 
+     *     kind = &quot;ABSTRACT&quot; / &quot;STRUCTURAL&quot; / &quot;AUXILIARY&quot;
+     * 
+     *   where:
+     *     &lt;numericoid&gt; is object identifier assigned to this object class;
+     *     NAME &lt;qdescrs&gt; are short names (descriptors) identifying this object
+     *         class;
+     *     DESC &lt;qdstring&gt; is a short descriptive string;
+     *     OBSOLETE indicates this object class is not active;
+     *     SUP &lt;oids&gt; specifies the direct superclasses of this object class;
+     *     the kind of object class is indicated by one of ABSTRACT,
+     *         STRUCTURAL, or AUXILIARY, default is STRUCTURAL;
+     *     MUST and MAY specify the sets of required and allowed attribute
+     *         types, respectively; and
+     *     &lt;extensions&gt; describe extensions.
+     * </pre>
+     * @param oc the ObjectClass to render the description of
+     * @return the string form of the Object Class description
+     */
+    public String render( ObjectClass oc )
+    {
+        StringBuilder buf = renderStartOidNamesDescObsolete( oc, "objectclass" );
+
+        List<String> superiorOids = oc.getSuperiorOids();
+
+        if ( ( superiorOids != null ) && ( superiorOids.size() > 0 ) )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "SUP " );
+            renderOids( buf, superiorOids );
+            prettyPrintNewLine( buf );
+        }
+
+        if ( oc.getType() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( oc.getType() );
+            prettyPrintNewLine( buf );
+        }
+
+        List<String> must = oc.getMustAttributeTypeOids();
+
+        if ( ( must != null ) && ( must.size() > 0 ) )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "MUST " );
+            renderOids( buf, must );
+            prettyPrintNewLine( buf );
+        }
+
+        List<String> may = oc.getMayAttributeTypeOids();
+
+        if ( ( may != null ) && ( may.size() > 0 ) )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "MAY " );
+            renderOids( buf, may );
+            prettyPrintNewLine( buf );
+        }
+
+        renderXSchemaName( oc, buf );
+
+        // @todo extensions are not presently supported and skipped
+        // the extensions would go here before closing off the description
+
+        buf.append( ")" );
+
+        return buf.toString();
+    }
+
+
+    /**
+     * Renders an attributeType according to the
+     * Attribute Type Description Syntax 1.3.6.1.4.1.1466.115.121.1.3. The
+     * syntax is described in detail within section 4.1.2. of 
+     * <a href="https://tools.ietf.org/rfc/rfc4512.txt">RFC 4512</a>
+     * which is replicated here for convenience:
+     * 
+     * <pre>
+     *  4.1.2. Attribute Types
+     * 
+     *   Attribute Type definitions are written according to the ABNF:
+     * 
+     *   AttributeTypeDescription = LPAREN WSP
+     *         numericoid                    ; object identifier
+     *         [ SP &quot;NAME&quot; SP qdescrs ]      ; short names (descriptors)
+     *         [ SP &quot;DESC&quot; SP qdstring ]     ; description
+     *         [ SP &quot;OBSOLETE&quot; ]             ; not active
+     *         [ SP &quot;SUP&quot; SP oid ]           ; supertype
+     *         [ SP &quot;EQUALITY&quot; SP oid ]      ; equality matching rule
+     *         [ SP &quot;ORDERING&quot; SP oid ]      ; ordering matching rule
+     *         [ SP &quot;SUBSTR&quot; SP oid ]        ; substrings matching rule
+     *         [ SP &quot;SYNTAX&quot; SP noidlen ]    ; value syntax
+     *         [ SP &quot;SINGLE-VALUE&quot; ]         ; single-value
+     *         [ SP &quot;COLLECTIVE&quot; ]           ; collective
+     *         [ SP &quot;NO-USER-MODIFICATION&quot; ] ; not user modifiable
+     *         [ SP &quot;USAGE&quot; SP usage ]       ; usage
+     *         extensions WSP RPAREN         ; extensions
+     * 
+     *     usage = &quot;userApplications&quot;     /  ; user
+     *             &quot;directoryOperation&quot;   /  ; directory operational
+     *             &quot;distributedOperation&quot; /  ; DSA-shared operational
+     *             &quot;dSAOperation&quot;            ; DSA-specific operational
+     * 
+     *   where:
+     *     &lt;numericoid&gt; is object identifier assigned to this attribute type;
+     *     NAME &lt;qdescrs&gt; are short names (descriptors) identifying this
+     *         attribute type;
+     *     DESC &lt;qdstring&gt; is a short descriptive string;
+     *     OBSOLETE indicates this attribute type is not active;
+     *     SUP oid specifies the direct supertype of this type;
+     *     EQUALITY, ORDERING, SUBSTR provide the oid of the equality,
+     *         ordering, and substrings matching rules, respectively;
+     *     SYNTAX identifies value syntax by object identifier and may suggest
+     *         a minimum upper bound;
+     *     SINGLE-VALUE indicates attributes of this type are restricted to a
+     *         single value;
+     *     COLLECTIVE indicates this attribute type is collective
+     *         [X.501][RFC3671];
+     *     NO-USER-MODIFICATION indicates this attribute type is not user
+     *         modifiable;
+     *     USAGE indicates the application of this attribute type; and
+     *     &lt;extensions&gt; describe extensions.
+     * </pre>
+     * @param at the AttributeType to render the description for
+     * @return the StringBuffer containing the rendered attributeType description
+     * @throws LdapException if there are problems accessing the objects
+     * associated with the attribute type.
+     */
+    public String render( AttributeType at )
+    {
+        StringBuilder buf = renderStartOidNamesDescObsolete( at, "attributetype" );
+
+        /*
+         *  TODO: Check for getSuperior(), getEquality(), getOrdering(), and getSubstring() should not be necessary. 
+         *  The getXyzOid() methods should return a name but return a numeric OID currently.
+         */
+
+        if ( at.getSuperior() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "SUP " ).append( at.getSuperior().getName() );
+            prettyPrintNewLine( buf );
+        }
+        else if ( at.getSuperiorOid() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "SUP " ).append( at.getSuperiorOid() );
+            prettyPrintNewLine( buf );
+        }
+
+        if ( at.getEquality() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "EQUALITY " ).append( at.getEquality().getName() );
+            prettyPrintNewLine( buf );
+        }
+        else if ( at.getEqualityOid() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "EQUALITY " ).append( at.getEqualityOid() );
+            prettyPrintNewLine( buf );
+        }
+
+        if ( at.getOrdering() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "ORDERING " ).append( at.getOrdering().getName() );
+            prettyPrintNewLine( buf );
+        }
+        else if ( at.getOrderingOid() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "ORDERING " ).append( at.getOrderingOid() );
+            prettyPrintNewLine( buf );
+        }
+
+        if ( at.getSubstring() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "SUBSTR " ).append( at.getSubstring().getName() );
+            prettyPrintNewLine( buf );
+        }
+        else if ( at.getSubstringOid() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "SUBSTR " ).append( at.getSubstringOid() );
+            prettyPrintNewLine( buf );
+        }
+
+        if ( at.getSyntaxOid() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "SYNTAX " ).append( at.getSyntaxOid() );
+
+            if ( at.getSyntaxLength() > 0 )
+            {
+                buf.append( "{" ).append( at.getSyntaxLength() ).append( "}" );
+            }
+            prettyPrintNewLine( buf );
+        }
+
+        if ( at.isSingleValued() )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "SINGLE-VALUE" );
+            prettyPrintNewLine( buf );
+        }
+
+        if ( at.isCollective() )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "COLLECTIVE" );
+            prettyPrintNewLine( buf );
+        }
+
+        if ( !at.isUserModifiable() )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "NO-USER-MODIFICATION" );
+            prettyPrintNewLine( buf );
+        }
+
+        if ( at.getUsage() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "USAGE " ).append( UsageEnum.render( at.getUsage() ) );
+            prettyPrintNewLine( buf );
+        }
+
+        renderXSchemaName( at, buf );
+
+        // @todo extensions are not presently supported and skipped
+        // the extensions would go here before closing off the description
+
+        buf.append( ")" );
+
+        return buf.toString();
+    }
+
+
+    private StringBuilder renderStartOidNamesDescObsolete( SchemaObject so, String schemaObjectType )
+    {
+        StringBuilder buf = new StringBuilder();
+
+        if ( style.startWithSchemaType )
+        {
+            buf.append( schemaObjectType ).append( ' ' );
+        }
+
+        buf.append( "( " ).append( so.getOid() );
+
+        List<String> names = so.getNames();
+
+        if ( ( names != null ) && ( names.size() > 0 ) )
+        {
+            buf.append( " NAME " );
+            renderQDescrs( buf, names );
+            prettyPrintNewLine( buf );
+        }
+        else
+        {
+            prettyPrintNewLine( buf );
+        }
+
+        if ( so.getDescription() != null )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "DESC " );
+            renderQDString( buf, so.getDescription() );
+            prettyPrintNewLine( buf );
+        }
+
+        if ( so.isObsolete() )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "OBSOLETE" );
+            prettyPrintNewLine( buf );
+        }
+        return buf;
+    }
+
+
+    private void prettyPrintNewLine( StringBuilder buf )
+    {
+        if ( style.prettyPrint )
+        {
+            buf.append( '\n' );
+        }
+        else
+        {
+            buf.append( " " );
+        }
+    }
+
+
+    private void prettyPrintIndent( StringBuilder buf )
+    {
+        if ( style.prettyPrint )
+        {
+            buf.append( "\t" );
+        }
+    }
+
+
+    /**
+     * Renders qdescrs into a new buffer.<br>
+     * <pre>
+     * descrs ::= qdescr | '(' WSP qdescrlist WSP ')'
+     * qdescrlist ::= [ qdescr ( SP qdescr )* ]
+     * qdescr     ::= SQUOTE descr SQUOTE
+     * </pre>
+     * @param qdescrs the quoted description strings to render
+     * @return the string buffer the qdescrs are rendered into
+     */
+    private StringBuilder renderQDescrs( StringBuilder buf, List<String> qdescrs )
+    {
+        if ( ( qdescrs == null ) || ( qdescrs.size() == 0 ) )
+        {
+            return buf;
+        }
+
+        if ( qdescrs.size() == 1 )
+        {
+            buf.append( '\'' ).append( qdescrs.get( 0 ) ).append( '\'' );
+        }
+        else
+        {
+            buf.append( "( " );
+
+            for ( String qdescr : qdescrs )
+            {
+                buf.append( '\'' ).append( qdescr ).append( "' " );
+            }
+
+            buf.append( ")" );
+        }
+
+        return buf;
+    }
+
+
+    /**
+     * Renders oids into a new buffer.<br>
+     * <pre>
+     * oids    ::= oid | '(' WSP oidlist WSP ')'
+     * oidlist ::= oid ( WSP '$' WSP oid )*
+     * </pre>
+     * 
+     * @param qdescrs the quoted description strings to render
+     * @return the string buffer the qdescrs are rendered into
+     */
+    private StringBuilder renderOids( StringBuilder buf, List<String> oids )
+    {
+        if ( oids.size() == 1 )
+        {
+            buf.append( oids.get( 0 ) );
+        }
+        else
+        {
+            buf.append( "( " );
+
+            boolean isFirst = true;
+
+            for ( String oid : oids )
+            {
+                if ( isFirst )
+                {
+                    isFirst = false;
+                }
+                else
+                {
+                    buf.append( " $ " );
+                }
+
+                buf.append( oid );
+            }
+
+            buf.append( " )" );
+        }
+
+        return buf;
+    }
+
+
+    /**
+     * Renders QDString into a new buffer.<br>
+     * 
+     * @param qdescrs the quoted description strings to render
+     * @return the string buffer the qdescrs are rendered into
+     */
+    private StringBuilder renderQDString( StringBuilder buf, String qdString )
+    {
+        buf.append( '\'' );
+
+        for ( char c : qdString.toCharArray() )
+        {
+            switch ( c )
+            {
+                case 0x27:
+                    buf.append( "\\27" );
+                    break;
+
+                case 0x5C:
+                    buf.append( "\\5C" );
+                    break;
+
+                default:
+                    buf.append( c );
+                    break;
+            }
+        }
+
+        buf.append( '\'' );
+
+        return buf;
+    }
+
+
+    private void renderXSchemaName( SchemaObject oc, StringBuilder buf )
+    {
+        if ( style.printSchemaName )
+        {
+            prettyPrintIndent( buf );
+            buf.append( "X-SCHEMA '" );
+            buf.append( oc.getSchemaName() );
+            buf.append( "'" );
+            prettyPrintNewLine( buf );
+        }
+    }
+}

Modified: directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaUtils.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaUtils.java?rev=1545951&r1=1545950&r2=1545951&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaUtils.java (original)
+++ directory/shared/trunk/ldap/model/src/main/java/org/apache/directory/api/ldap/model/schema/SchemaUtils.java Wed Nov 27 07:27:08 2013
@@ -407,258 +407,6 @@ public final class SchemaUtils
     // schema object rendering operations
     // ------------------------------------------------------------------------
 
-    /**
-     * Renders an objectClass into a new StringBuffer according to the Object
-     * Class Description Syntax 1.3.6.1.4.1.1466.115.121.1.37. The syntax is
-     * described in detail within section 4.1.1. of LDAPBIS [<a
-     * href="http://ietf.org/internet-drafts/draft-ietf-ldapbis-models-12.txt">MODELS</a>]
-     * which is replicated here for convenience:
-     * 
-     * <pre>
-     *  4.1.1. Object Class Definitions
-     * 
-     *   Object Class definitions are written according to the ABNF:
-     * 
-     *     ObjectClassDescription = LPAREN WSP
-     *         numericoid                 ; object identifier
-     *         [ SP &quot;NAME&quot; SP qdescrs ]   ; short names (descriptors)
-     *         [ SP &quot;DESC&quot; SP qdstring ]  ; description
-     *         [ SP &quot;OBSOLETE&quot; ]          ; not active
-     *         [ SP &quot;SUP&quot; SP oids ]       ; superior object classes
-     *         [ SP kind ]                ; kind of class
-     *         [ SP &quot;MUST&quot; SP oids ]      ; attribute types
-     *         [ SP &quot;MAY&quot; SP oids ]       ; attribute types
-     *         extensions WSP RPAREN
-     * 
-     *     kind = &quot;ABSTRACT&quot; / &quot;STRUCTURAL&quot; / &quot;AUXILIARY&quot;
-     * 
-     *   where:
-     *     &lt;numericoid&gt; is object identifier assigned to this object class;
-     *     NAME &lt;qdescrs&gt; are short names (descriptors) identifying this object
-     *         class;
-     *     DESC &lt;qdstring&gt; is a short descriptive string;
-     *     OBSOLETE indicates this object class is not active;
-     *     SUP &lt;oids&gt; specifies the direct superclasses of this object class;
-     *     the kind of object class is indicated by one of ABSTRACT,
-     *         STRUCTURAL, or AUXILIARY, default is STRUCTURAL;
-     *     MUST and MAY specify the sets of required and allowed attribute
-     *         types, respectively; and
-     *     &lt;extensions&gt; describe extensions.
-     * </pre>
-     * @param oc the objectClass to render the description of
-     * @return the buffer containing the objectClass description
-     * @throws LdapException if there are any problems accessing objectClass
-     * information
-     */
-    public static StringBuffer render( ObjectClass oc ) throws LdapException
-    {
-        StringBuffer buf = new StringBuffer();
-        buf.append( "( " ).append( oc.getOid() );
-
-        List<String> names = oc.getNames();
-
-        if ( ( names != null ) && ( names.size() > 0 ) )
-        {
-            buf.append( " NAME " );
-            renderQDescrs( buf, names );
-        }
-
-        if ( oc.getDescription() != null )
-        {
-            buf.append( " DESC " );
-            renderQDString( buf, oc.getDescription() );
-        }
-
-        if ( oc.isObsolete() )
-        {
-            buf.append( " OBSOLETE" );
-        }
-
-        List<String> superiorOids = oc.getSuperiorOids();
-
-        if ( ( superiorOids != null ) && ( superiorOids.size() > 0 ) )
-        {
-            buf.append( " SUP " );
-            renderOids( buf, superiorOids );
-        }
-
-        if ( oc.getType() != null )
-        {
-            buf.append( " " ).append( oc.getType() );
-        }
-
-        List<String> must = oc.getMustAttributeTypeOids();
-
-        if ( ( must != null ) && ( must.size() > 0 ) )
-        {
-            buf.append( " MUST " );
-            renderOids( buf, must );
-        }
-
-        List<String> may = oc.getMayAttributeTypeOids();
-
-        if ( ( may != null ) && ( may.size() > 0 ) )
-        {
-            buf.append( " MAY " );
-            renderOids( buf, may );
-        }
-
-        buf.append( " X-SCHEMA '" );
-        buf.append( oc.getSchemaName() );
-        buf.append( "'" );
-
-        // @todo extensions are not presently supported and skipped
-        // the extensions would go here before closing off the description
-
-        buf.append( " )" );
-
-        return buf;
-    }
-
-
-    /**
-     * Renders an attributeType into a new StringBuffer according to the
-     * Attribute Type Description Syntax 1.3.6.1.4.1.1466.115.121.1.3. The
-     * syntax is described in detail within section 4.1.2. of LDAPBIS [<a
-     * href="http://ietf.org/internet-drafts/draft-ietf-ldapbis-models-12.txt">MODELS</a>]
-     * which is replicated here for convenience:
-     * 
-     * <pre>
-     *  4.1.2. Attribute Types
-     * 
-     *   Attribute Type definitions are written according to the ABNF:
-     * 
-     *   AttributeTypeDescription = LPAREN WSP
-     *         numericoid                    ; object identifier
-     *         [ SP &quot;NAME&quot; SP qdescrs ]      ; short names (descriptors)
-     *         [ SP &quot;DESC&quot; SP qdstring ]     ; description
-     *         [ SP &quot;OBSOLETE&quot; ]             ; not active
-     *         [ SP &quot;SUP&quot; SP oid ]           ; supertype
-     *         [ SP &quot;EQUALITY&quot; SP oid ]      ; equality matching rule
-     *         [ SP &quot;ORDERING&quot; SP oid ]      ; ordering matching rule
-     *         [ SP &quot;SUBSTR&quot; SP oid ]        ; substrings matching rule
-     *         [ SP &quot;SYNTAX&quot; SP noidlen ]    ; value syntax
-     *         [ SP &quot;SINGLE-VALUE&quot; ]         ; single-value
-     *         [ SP &quot;COLLECTIVE&quot; ]           ; collective
-     *         [ SP &quot;NO-USER-MODIFICATION&quot; ] ; not user modifiable
-     *         [ SP &quot;USAGE&quot; SP usage ]       ; usage
-     *         extensions WSP RPAREN         ; extensions
-     * 
-     *     usage = &quot;userApplications&quot;     /  ; user
-     *             &quot;directoryOperation&quot;   /  ; directory operational
-     *             &quot;distributedOperation&quot; /  ; DSA-shared operational
-     *             &quot;dSAOperation&quot;            ; DSA-specific operational
-     * 
-     *   where:
-     *     &lt;numericoid&gt; is object identifier assigned to this attribute type;
-     *     NAME &lt;qdescrs&gt; are short names (descriptors) identifying this
-     *         attribute type;
-     *     DESC &lt;qdstring&gt; is a short descriptive string;
-     *     OBSOLETE indicates this attribute type is not active;
-     *     SUP oid specifies the direct supertype of this type;
-     *     EQUALITY, ORDERING, SUBSTR provide the oid of the equality,
-     *         ordering, and substrings matching rules, respectively;
-     *     SYNTAX identifies value syntax by object identifier and may suggest
-     *         a minimum upper bound;
-     *     SINGLE-VALUE indicates attributes of this type are restricted to a
-     *         single value;
-     *     COLLECTIVE indicates this attribute type is collective
-     *         [X.501][RFC3671];
-     *     NO-USER-MODIFICATION indicates this attribute type is not user
-     *         modifiable;
-     *     USAGE indicates the application of this attribute type; and
-     *     &lt;extensions&gt; describe extensions.
-     * </pre>
-     * @param at the AttributeType to render the description for
-     * @return the StringBuffer containing the rendered attributeType description
-     * @throws LdapException if there are problems accessing the objects
-     * associated with the attribute type.
-     */
-    public static StringBuffer render( AttributeType at ) throws LdapException
-    {
-        StringBuffer buf = new StringBuffer();
-        buf.append( "( " ).append( at.getOid() );
-        List<String> names = at.getNames();
-
-        if ( ( names != null ) && ( names.size() > 0 ) )
-        {
-            buf.append( " NAME " );
-            renderQDescrs( buf, names );
-        }
-
-        if ( at.getDescription() != null )
-        {
-            buf.append( " DESC " );
-            renderQDString( buf, at.getDescription() );
-        }
-
-        if ( at.isObsolete() )
-        {
-            buf.append( " OBSOLETE" );
-        }
-
-        if ( at.getSuperior() != null )
-        {
-            buf.append( " SUP " ).append( at.getSuperior().getName() );
-        }
-
-        if ( at.getEquality() != null )
-        {
-            buf.append( " EQUALITY " ).append( at.getEquality().getName() );
-        }
-
-        if ( at.getOrdering() != null )
-        {
-            buf.append( " ORDERING " ).append( at.getOrdering().getName() );
-        }
-
-        if ( at.getSubstring() != null )
-        {
-            buf.append( " SUBSTR " ).append( at.getSubstring().getName() );
-        }
-
-        if ( at.getSyntax() != null )
-        {
-            buf.append( " SYNTAX " ).append( at.getSyntax().getOid() );
-
-            if ( at.getSyntaxLength() > 0 )
-            {
-                buf.append( "{" ).append( at.getSyntaxLength() ).append( "}" );
-            }
-        }
-
-        if ( at.isSingleValued() )
-        {
-            buf.append( " SINGLE-VALUE" );
-        }
-
-        if ( at.isCollective() )
-        {
-            buf.append( " COLLECTIVE" );
-        }
-
-        if ( !at.isUserModifiable() )
-        {
-            buf.append( " NO-USER-MODIFICATION" );
-        }
-
-        if ( at.getUsage() != null )
-        {
-            buf.append( " USAGE " ).append( UsageEnum.render( at.getUsage() ) );
-        }
-
-        buf.append( " X-SCHEMA '" );
-        buf.append( at.getSchemaName() );
-        buf.append( "'" );
-
-        // @todo extensions are not presently supported and skipped
-        // the extensions would go here before closing off the description
-
-        buf.append( " )" );
-
-        return buf;
-    }
-
 
     /**
      * Renders the schema extensions into a new StringBuffer.

Added: directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/AttributeTypeTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/AttributeTypeTest.java?rev=1545951&view=auto
==============================================================================
--- directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/AttributeTypeTest.java (added)
+++ directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/AttributeTypeTest.java Wed Nov 27 07:27:08 2013
@@ -0,0 +1,74 @@
+/*
+ *  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.api.ldap.model.schema;
+
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.mycila.junit.concurrent.Concurrency;
+import com.mycila.junit.concurrent.ConcurrentJunitRunner;
+
+
+/**
+ * Unit tests class AttributeType.
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+@RunWith(ConcurrentJunitRunner.class)
+@Concurrency()
+public class AttributeTypeTest
+{
+    private MutableAttributeType attributeType;
+
+
+    /**
+     * Initialize attribute type instances
+     */
+    @Before
+    public void initAttributeTypes() throws Exception
+    {
+        attributeType = new MutableAttributeType( "1.2.3.4" );
+        attributeType.setNames( "name1", "name2" );
+        attributeType.setDescription( "description" );
+        attributeType.setObsolete( false );
+        attributeType.setEqualityOid( "caseIgnoreMatch" );
+        attributeType.setSuperiorOid( "2.3.4.5" );
+    }
+
+
+    @Test
+    public void testToString() throws Exception
+    {
+        String string1 = attributeType.toString();
+        System.out.println( string1 );
+
+        assertNotNull( string1 );
+        assertTrue( string1.startsWith( "attributetype (" ) );
+        assertTrue( string1.contains( " NAME " ) );
+        assertTrue( string1.contains( "\n\tDESC " ) );
+        assertTrue( string1.contains( "\n\tSUP " ) );
+        assertTrue( string1.contains( "\n\tUSAGE" ) );
+    }
+}

Modified: directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/ObjectClassTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/ObjectClassTest.java?rev=1545951&r1=1545950&r2=1545951&view=diff
==============================================================================
--- directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/ObjectClassTest.java (original)
+++ directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/ObjectClassTest.java Wed Nov 27 07:27:08 2013
@@ -22,15 +22,19 @@ package org.apache.directory.api.ldap.mo
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
-import com.mycila.junit.concurrent.Concurrency;
-import com.mycila.junit.concurrent.ConcurrentJunitRunner;
+import java.util.Arrays;
+import java.util.Collections;
 
-import org.apache.directory.api.ldap.model.schema.ObjectClass;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import com.mycila.junit.concurrent.Concurrency;
+import com.mycila.junit.concurrent.ConcurrentJunitRunner;
+
 
 /**
  * Unit tests class ObjectClass.
@@ -41,23 +45,33 @@ import org.junit.runner.RunWith;
 @Concurrency()
 public class ObjectClassTest
 {
-    ObjectClass objectClassA;
-    ObjectClass objectClassACopy;
-    ObjectClass objectClassB;
-    ObjectClass objectClassC;
+    private ObjectClass objectClassA;
+    private ObjectClass objectClassACopy;
+    private ObjectClass objectClassB;
+    private ObjectClass objectClassC;
+    private MutableObjectClass objectClass;
 
 
     /**
-     * Initialize name instances
+     * Initialize object class instances
      */
     @Before
-    public void initNames() throws Exception
+    public void initObjectClasses() throws Exception
     {
         // TODO Create ObjectClasses with more meaningful constructor arguments
         objectClassA = new ObjectClass( "aa" );
         objectClassACopy = new ObjectClass( "aa" );
         objectClassB = new ObjectClass( "aa" );
         objectClassC = new ObjectClass( "cc" );
+
+        objectClass = new MutableObjectClass( "1.2.3.4" );
+        objectClass.setNames( "name1", "name2" );
+        objectClass.setDescription( "description" );
+        objectClass.setObsolete( false );
+        objectClass.setSuperiorOids( Collections.singletonList( "1.3.5.7" ) );
+        objectClass.setType( ObjectClassTypeEnum.STRUCTURAL );
+        objectClass.setMustAttributeTypeOids( Arrays.asList( "att1", "att2" ) );
+        objectClass.setMayAttributeTypeOids( Arrays.asList( "att3", "att4" ) );
     }
 
 
@@ -122,4 +136,21 @@ public class ObjectClassTest
         assertFalse( objectClassA.equals( objectClassC ) );
         assertFalse( objectClassC.equals( objectClassA ) );
     }
+
+
+    @Test
+    public void testToString() throws Exception
+    {
+        String string1 = objectClass.toString();
+
+        assertNotNull( string1 );
+        assertTrue( string1.startsWith( "objectclass (" ) );
+        assertTrue( string1.contains( " NAME " ) );
+        assertTrue( string1.contains( "\n\tDESC " ) );
+        assertTrue( string1.contains( "\n\tSUP " ) );
+        assertTrue( string1.contains( "\n\tSTRUCTURAL" ) );
+        assertTrue( string1.contains( "\n\tMUST" ) );
+        assertTrue( string1.contains( "\n\tMAY" ) );
+        assertTrue( string1.endsWith( "\n)" ) );
+    }
 }

Added: directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/SchemaObjectRendererTest.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/SchemaObjectRendererTest.java?rev=1545951&view=auto
==============================================================================
--- directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/SchemaObjectRendererTest.java (added)
+++ directory/shared/trunk/ldap/model/src/test/java/org/apache/directory/api/ldap/model/schema/SchemaObjectRendererTest.java Wed Nov 27 07:27:08 2013
@@ -0,0 +1,284 @@
+/*
+ *  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.api.ldap.model.schema;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.text.ParseException;
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.apache.directory.api.ldap.model.schema.parsers.AttributeTypeDescriptionSchemaParser;
+import org.apache.directory.api.ldap.model.schema.parsers.ObjectClassDescriptionSchemaParser;
+import org.apache.directory.api.ldap.model.schema.parsers.OpenLdapSchemaParser;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * 
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class SchemaObjectRendererTest
+{
+
+    private MutableObjectClass objectClassSimple;
+    private MutableObjectClass objectClassComplex;
+
+    private MutableAttributeType attributeTypeSimple;
+    private MutableAttributeType attributeTypeComplex;
+
+
+    @Before
+    public void setUp()
+    {
+        objectClassSimple = new MutableObjectClass( "1.2.3.4" );
+        objectClassSimple.setNames( "name0" );
+        objectClassSimple.setMustAttributeTypeOids( Arrays.asList( "att0" ) );
+        objectClassSimple.setSchemaName( "dummy" );
+
+        objectClassComplex = new MutableObjectClass( "1.2.3.4" );
+        objectClassComplex.setNames( "name1", "name2" );
+        objectClassComplex.setDescription( "description with 'quotes'" );
+        objectClassComplex.setObsolete( true );
+        objectClassComplex.setSuperiorOids( Collections.singletonList( "1.3.5.7" ) );
+        objectClassComplex.setType( ObjectClassTypeEnum.AUXILIARY );
+        objectClassComplex.setMustAttributeTypeOids( Arrays.asList( "att1", "att2" ) );
+        objectClassComplex.setMayAttributeTypeOids( Arrays.asList( "att3", "att4" ) );
+        objectClassComplex.setSchemaName( "dummy" );
+
+        attributeTypeSimple = new MutableAttributeType( "1.2.3.4" );
+        attributeTypeSimple.setNames( "name0" );
+        attributeTypeSimple.setEqualityOid( "matchingRule0" );
+        attributeTypeSimple.setSyntaxOid( "2.3.4.5" );
+        attributeTypeSimple.setSyntaxLength( 512 );
+        attributeTypeSimple.setCollective( true );
+        attributeTypeSimple.setSchemaName( "dummy" );
+
+        attributeTypeComplex = new MutableAttributeType( "1.2.3.4" );
+        attributeTypeComplex.setNames( "name1", "name2" );
+        attributeTypeComplex.setDescription( "description with 'quotes'" );
+        attributeTypeComplex.setObsolete( true );
+        attributeTypeComplex.setSuperiorOid( "superAttr" );
+        attributeTypeComplex.setEqualityOid( "matchingRule1" );
+        attributeTypeComplex.setOrderingOid( "matchingRule2" );
+        attributeTypeComplex.setSubstringOid( "matchingRule3" );
+        attributeTypeComplex.setSingleValued( true );
+        attributeTypeComplex.setUserModifiable( false );
+        attributeTypeComplex.setUsage( UsageEnum.DIRECTORY_OPERATION );
+        attributeTypeComplex.setSchemaName( "dummy" );
+    }
+
+
+    @Test
+    public void testOpenLdapSchemaRendererObjectClassMinimal()
+    {
+        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( new ObjectClass( "1.2.3" ) );
+        String expected = "objectclass ( 1.2.3\n\tSTRUCTURAL\n)";
+        assertEquals( expected, actual );
+    }
+
+
+    @Test
+    public void testOpenLdapSchemaRendererObjectClassSimple()
+    {
+        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( objectClassSimple );
+        String expected = "objectclass ( 1.2.3.4 NAME 'name0'\n\tSTRUCTURAL\n\tMUST att0\n)";
+        assertEquals( expected, actual );
+    }
+
+
+    @Test
+    public void testOpenLdapSchemaRendererObjectClassComplex()
+    {
+        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( objectClassComplex );
+        String expected = "objectclass ( 1.2.3.4 NAME ( 'name1' 'name2' )\n\tDESC 'description with \\27quotes\\27'\n\tOBSOLETE\n\tSUP 1.3.5.7\n\tAUXILIARY\n\tMUST ( att1 $ att2 )\n\tMAY ( att3 $ att4 )\n)";
+        assertEquals( expected, actual );
+    }
+
+
+    @Test
+    public void testOpenLdapSchemaRendererAndParserRoundtripObjectClassSimple() throws Exception
+    {
+        testOpenLdapSchemaRendererAndParserRountrip( objectClassSimple );
+    }
+
+
+    @Test
+    public void testOpenLdapSchemaRendererAndParserRoundtripObjectClassComplex() throws Exception
+    {
+        testOpenLdapSchemaRendererAndParserRountrip( objectClassComplex );
+    }
+
+
+    private void testOpenLdapSchemaRendererAndParserRountrip( ObjectClass original ) throws Exception
+    {
+        // must unset schema name because OpenLdapSchemaParser doesn't know about schema name
+        original.setSchemaName( null );
+
+        String renderedOriginal = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( original );
+        ObjectClass parsed = ( ObjectClass ) new OpenLdapSchemaParser().parse( renderedOriginal );
+        String renderedParsed = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( parsed );
+
+        assertTrue( original.equals( parsed ) );
+        assertTrue( renderedOriginal.equals( renderedParsed ) );
+    }
+
+
+    @Test
+    public void testSubschemSubentryRendererObjectClassMinimal()
+    {
+        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( new ObjectClass( "1.2.3" ) );
+        String expected = "( 1.2.3 STRUCTURAL X-SCHEMA 'null' )";
+        assertEquals( expected, actual );
+    }
+
+
+    @Test
+    public void testSubschemSubentryRendererObjectClassSimple()
+    {
+        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( objectClassSimple );
+        String expected = "( 1.2.3.4 NAME 'name0' STRUCTURAL MUST att0 X-SCHEMA 'dummy' )";
+        assertEquals( expected, actual );
+    }
+
+
+    @Test
+    public void testSubschemSubentryRendererObjectClassComplex()
+    {
+        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( objectClassComplex );
+        String expected = "( 1.2.3.4 NAME ( 'name1' 'name2' ) DESC 'description with \\27quotes\\27' OBSOLETE SUP 1.3.5.7 AUXILIARY MUST ( att1 $ att2 ) MAY ( att3 $ att4 ) X-SCHEMA 'dummy' )";
+        assertEquals( expected, actual );
+    }
+
+
+    @Test
+    public void testSubschemSubentryRendererAndParserRoundtripObjectClassSimple() throws ParseException
+    {
+        testSubschemSubentryRendererAndParserRoundtrip( objectClassSimple );
+    }
+
+
+    @Test
+    public void testSubschemSubentryRendererAndParserRoundtripObjectClassComplex() throws ParseException
+    {
+        testSubschemSubentryRendererAndParserRoundtrip( objectClassComplex );
+    }
+
+
+    private void testSubschemSubentryRendererAndParserRoundtrip( ObjectClass original ) throws ParseException
+    {
+        String renderedOriginal = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( original );
+        ObjectClass parsed = new ObjectClassDescriptionSchemaParser().parse( renderedOriginal );
+        String renderedParsed = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( parsed );
+
+        assertTrue( original.equals( parsed ) );
+        assertTrue( renderedOriginal.equals( renderedParsed ) );
+    }
+
+
+    @Test
+    public void testOpenLdapSchemaRendererAttributeTypeSimple()
+    {
+        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( attributeTypeSimple );
+        String expected = "attributetype ( 1.2.3.4 NAME 'name0'\n\tEQUALITY matchingRule0\n\tSYNTAX 2.3.4.5{512}\n\tCOLLECTIVE\n\tUSAGE userApplications\n)";
+        assertEquals( expected, actual );
+    }
+
+
+    @Test
+    public void testOpenLdapSchemaRendererAttributeTypeComplex()
+    {
+        String actual = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( attributeTypeComplex );
+        String expected = "attributetype ( 1.2.3.4 NAME ( 'name1' 'name2' )\n\tDESC 'description with \\27quotes\\27'\n\tOBSOLETE\n\tSUP superAttr\n\tEQUALITY matchingRule1\n\tORDERING matchingRule2\n\tSUBSTR matchingRule3\n\tSINGLE-VALUE\n\tNO-USER-MODIFICATION\n\tUSAGE directoryOperation\n)";
+        assertEquals( expected, actual );
+    }
+
+
+    @Test
+    public void testOpenLdapSchemaRendererAndParserRoundtripAttributeTypeSimple() throws Exception
+    {
+        testOpenLdapSchemaRendererAndParserRountrip( attributeTypeSimple );
+    }
+
+
+    @Test
+    public void testOpenLdapSchemaRendererAndParserRoundtripAttributeTypeComplex() throws Exception
+    {
+        testOpenLdapSchemaRendererAndParserRountrip( attributeTypeComplex );
+    }
+
+
+    private void testOpenLdapSchemaRendererAndParserRountrip( AttributeType original ) throws Exception
+    {
+        // must unset schema name because OpenLdapSchemaParser doesn't know about schema name
+        original.setSchemaName( null );
+
+        String renderedOriginal = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( original );
+        AttributeType parsed = ( AttributeType ) new OpenLdapSchemaParser().parse( renderedOriginal );
+        String renderedParsed = SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( parsed );
+
+        assertTrue( original.equals( parsed ) );
+        assertTrue( renderedOriginal.equals( renderedParsed ) );
+    }
+
+
+    @Test
+    public void testSubschemSubentryRendererAttributeTypeSimple()
+    {
+        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( attributeTypeSimple );
+        String expected = "( 1.2.3.4 NAME 'name0' EQUALITY matchingRule0 SYNTAX 2.3.4.5{512} COLLECTIVE USAGE userApplications X-SCHEMA 'dummy' )";
+        assertEquals( expected, actual );
+    }
+
+
+    @Test
+    public void testSubschemSubentryRendererAttributeTypeComplex()
+    {
+        String actual = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( attributeTypeComplex );
+        String expected = "( 1.2.3.4 NAME ( 'name1' 'name2' ) DESC 'description with \\27quotes\\27' OBSOLETE SUP superAttr EQUALITY matchingRule1 ORDERING matchingRule2 SUBSTR matchingRule3 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-SCHEMA 'dummy' )";
+        assertEquals( expected, actual );
+    }
+
+
+    @Test
+    public void testSubschemSubentryRendererAndParserRoundtripAttributeTypeSimple() throws ParseException
+    {
+        testSubschemSubentryRendererAndParserRoundtrip( attributeTypeSimple );
+    }
+
+
+    @Test
+    public void testSubschemSubentryRendererAndParserRoundtripAttributeTypeComplex() throws ParseException
+    {
+        testSubschemSubentryRendererAndParserRoundtrip( attributeTypeComplex );
+    }
+
+
+    private void testSubschemSubentryRendererAndParserRoundtrip( AttributeType original ) throws ParseException
+    {
+        String renderedOriginal = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( original );
+        AttributeType parsed = new AttributeTypeDescriptionSchemaParser().parse( renderedOriginal );
+        String renderedParsed = SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( parsed );
+
+        assertTrue( original.equals( parsed ) );
+        assertTrue( renderedOriginal.equals( renderedParsed ) );
+    }
+}



Mime
View raw message