From a0e29bcfe05d737bb1b644d282b2383ee6126bad Mon Sep 17 00:00:00 2001
From: sin <sin@localhost>
Date: Wed, 29 Apr 2009 15:43:23 +0000
Subject: [PATCH] issue 3444:Only a single name form allowed per structural object class

---
 opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java                                   |   10 
 opendj-sdk/opends/src/server/org/opends/server/types/DirectoryConfig.java                                  |   19 +-
 opendj-sdk/opends/src/server/org/opends/server/types/Schema.java                                           |  108 ++++++++++-----
 opendj-sdk/opends/src/server/org/opends/server/types/Entry.java                                            |  194 ++++++++++++++++-----------
 opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java                                 |   49 +++---
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java |   10 
 6 files changed, 232 insertions(+), 158 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java b/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
index 541eb36..6ffe7f1 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/SchemaBackend.java
@@ -1846,14 +1846,19 @@
 
     // Make sure that the attribute type isn't used as a required or optional
     // attribute type in any name form.
-    for (NameForm nf : schema.getNameFormsByObjectClass().values())
+    for (List<NameForm> mappedForms :
+                      schema.getNameFormsByObjectClass().values())
     {
-      if (nf.getRequiredAttributes().contains(removeType) ||
-          nf.getOptionalAttributes().contains(removeType))
+      for(NameForm nf : mappedForms)
       {
-        Message message = ERR_SCHEMA_MODIFY_REMOVE_AT_IN_NF.get(
-            removeType.getNameOrOID(), nf.getNameOrOID());
-        throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
+        if (nf.getRequiredAttributes().contains(removeType) ||
+            nf.getOptionalAttributes().contains(removeType))
+        {
+          Message message = ERR_SCHEMA_MODIFY_REMOVE_AT_IN_NF.get(
+              removeType.getNameOrOID(), nf.getNameOrOID());
+          throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+                  message);
+        }
       }
     }
 
@@ -2158,11 +2163,17 @@
 
     // Make sure that the objectclass isn't used as the structural class for
     // any name form.
-    NameForm nf = schema.getNameForm(removeClass);
-    if (nf != null)
+    List<NameForm> mappedForms = schema.getNameForm(removeClass);
+    if (mappedForms != null)
     {
+      StringBuilder buffer = new StringBuilder();
+      for(NameForm nf : mappedForms)
+      {
+        buffer.append(nf.getNameOrOID());
+        buffer.append("\t");
+      }
       Message message = ERR_SCHEMA_MODIFY_REMOVE_OC_IN_NF.get(
-          removeClass.getNameOrOID(), nf.getNameOrOID());
+          removeClass.getNameOrOID(), buffer.toString());
       throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
     }
 
@@ -2267,15 +2278,6 @@
       throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
     }
 
-    NameForm existingNFForClass = schema.getNameForm(structuralClass);
-    if ((existingNFForClass != null) && (existingNFForClass != existingNF))
-    {
-      Message message = ERR_SCHEMA_MODIFY_STRUCTURAL_OC_CONFLICT_FOR_ADD_NF.
-          get(nameForm.getNameOrOID(), structuralClass.getNameOrOID(),
-              existingNFForClass.getNameOrOID());
-      throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
-    }
-
     for (AttributeType at : nameForm.getRequiredAttributes())
     {
       if (! schema.hasAttributeType(at.getOID()))
@@ -3345,12 +3347,15 @@
     // is no hierarchical relationship between name forms, we don't need to
     // worry about ordering.
     values = new LinkedHashSet<AttributeValue>();
-    for (NameForm nf : schema.getNameFormsByObjectClass().values())
+    for (List<NameForm> forms : schema.getNameFormsByObjectClass().values())
     {
-      if (schemaFile.equals(nf.getSchemaFile()))
+      for(NameForm nf : forms)
       {
-        values.add(AttributeValues.create(
-            nameFormsType, nf.getDefinition()));
+        if (schemaFile.equals(nf.getSchemaFile()))
+        {
+          values.add(AttributeValues.create(
+              nameFormsType, nf.getDefinition()));
+        }
       }
     }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
index 2c09046..4e3dd7f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -4435,7 +4435,7 @@
    *
    * @return  The set of name forms defined in the Directory Server.
    */
-  public static ConcurrentHashMap<ObjectClass,NameForm> getNameForms()
+  public static ConcurrentHashMap<ObjectClass,List<NameForm>> getNameForms()
   {
     return directoryServer.schema.getNameFormsByObjectClass();
   }
@@ -4457,15 +4457,15 @@
 
 
   /**
-   * Retrieves the name form associated with the specified objectclass.
+   * Retrieves the name forms associated with the specified objectclass.
    *
    * @param  objectClass  The objectclass for which to retrieve the associated
    *                      name form.
    *
-   * @return  The requested name form, or <CODE>null</CODE> if no such name form
-   *          is defined in the schema.
+   * @return  The requested name forms, or <CODE>null</CODE> if no such name
+   *           form is defined in the schema.
    */
-  public static NameForm getNameForm(ObjectClass objectClass)
+  public static List<NameForm> getNameForm(ObjectClass objectClass)
   {
     return directoryServer.schema.getNameForm(objectClass);
   }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/DirectoryConfig.java b/opendj-sdk/opends/src/server/org/opends/server/types/DirectoryConfig.java
index e8bf2ea..96407c4 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/DirectoryConfig.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/DirectoryConfig.java
@@ -22,9 +22,10 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.types;
+import java.util.List;
 import org.opends.messages.Message;
 
 
@@ -658,12 +659,12 @@
   /**
    * Retrieves the set of name forms defined in the Directory Server.
    * The mapping will be between the structural objectclass and its
-   * corresponding name form.  The returned map must not be altered by
-   * the caller.
+   * corresponding name forms.  The returned map must not be altered
+   * by the caller.
    *
    * @return  The set of name forms defined in the Directory Server.
    */
-  public static Map<ObjectClass,NameForm> getNameForms()
+  public static Map<ObjectClass,List<NameForm>> getNameForms()
   {
     return DirectoryServer.getNameForms();
   }
@@ -671,16 +672,16 @@
 
 
   /**
-   * Retrieves the name form associated with the specified structural
-   * objectclass.
+   * Retrieves the list of name forms associated with the specified
+   * structural objectclass.
    *
    * @param  objectClass  The structural objectclass for which to
    *                      retrieve the  associated name form.
    *
-   * @return  The requested name form, or <CODE>null</CODE> if no such
-   *          name form is defined in the schema.
+   * @return  The list of requested name forms, or <CODE>null</CODE>
+   *           if no such name form is defined in the schema.
    */
-  public static NameForm getNameForm(ObjectClass objectClass)
+  public static List<NameForm> getNameForm(ObjectClass objectClass)
   {
     return DirectoryServer.getNameForm(objectClass);
   }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java b/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
index c8a22b7..3829f3a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/Entry.java
@@ -2052,14 +2052,60 @@
         ditContentRule = null;
       }
 
+
+      if (! checkAttributesAndObjectClasses(ditContentRule,
+                 structuralPolicy, invalidReason))
+      {
+        return false;
+      }
+
       if (validateNameForms)
       {
-        nameForm = DirectoryServer.getNameForm(structuralClass);
-        if ((nameForm != null) && nameForm.isObsolete())
+        /**
+         * There may be multiple nameforms registered with this
+         * structural objectclass.However, we need to select only one
+         * of the nameforms and its corresponding DITstructure rule.
+         * We will iterate over all the nameforms and see if atleast
+         * one is acceptable before rejecting the entry.
+         * DITStructureRules corresponding to other non-acceptable
+         * nameforms are not applied.
+         */
+        List<NameForm> listForms =
+                DirectoryServer.getNameForm(structuralClass);
+        if(listForms != null)
         {
-          nameForm = null;
+          boolean matchFound = false;
+          boolean obsolete = true;
+          for(int index=0; index <listForms.size(); index++)
+          {
+            NameForm nf = listForms.get(index);
+            if(!nf.isObsolete())
+            {
+              obsolete = false;
+              matchFound = checkNameForm(nf,
+                      structuralPolicy, invalidReason);
+
+              if(matchFound)
+              {
+                nameForm = nf;
+                break;
+              }
+
+              if(index != listForms.size()-1)
+              {
+                invalidReason.append(",");
+              }
+            }
+          }
+          if(! obsolete && !matchFound)
+          {
+            //We couldn't match this entry against any of the
+            // nameforms.
+            return false;
+          }
         }
 
+
         if (validateStructureRules && (nameForm != null))
         {
           ditStructureRule =
@@ -2074,24 +2120,6 @@
     }
 
 
-    if (! checkAttributesAndObjectClasses(ditContentRule,
-               structuralPolicy, invalidReason))
-    {
-      return false;
-    }
-
-
-    // If there is a name form for this entry, then make sure that the
-    // RDN for the entry is in compliance with it.
-    if (nameForm != null)
-    {
-      if (! checkNameForm(nameForm, structuralPolicy, invalidReason))
-      {
-        return false;
-      }
-    }
-
-
     // If there is a DIT content rule for this entry, then make sure
     // that the entry is in compliance with it.
     if (ditContentRule != null)
@@ -2304,54 +2332,54 @@
     RDN rdn = dn.getRDN();
     if (rdn != null)
     {
-      // Make sure that all the required attributes are present.
-      for (AttributeType t : nameForm.getRequiredAttributes())
-      {
-        if (! rdn.hasAttributeType(t))
+        // Make sure that all the required attributes are present.
+        for (AttributeType t : nameForm.getRequiredAttributes())
         {
-          Message message =
-                  ERR_ENTRY_SCHEMA_RDN_MISSING_REQUIRED_ATTR.get(
-                    String.valueOf(dn),
-                    t.getNameOrOID(),
-                    nameForm.getNameOrOID());
+          if (! rdn.hasAttributeType(t))
+          {
+            Message message =
+                    ERR_ENTRY_SCHEMA_RDN_MISSING_REQUIRED_ATTR.get(
+                      String.valueOf(dn),
+                      t.getNameOrOID(),
+                      nameForm.getNameOrOID());
 
-          if (structuralPolicy == AcceptRejectWarn.REJECT)
-          {
-            invalidReason.append(message);
-            return false;
+            if (structuralPolicy == AcceptRejectWarn.REJECT)
+            {
+                invalidReason.append(message);
+              return false;
+            }
+            else if (structuralPolicy == AcceptRejectWarn.WARN)
+            {
+                logError(message);
+              }
+            }
           }
-          else if (structuralPolicy == AcceptRejectWarn.WARN)
-          {
-            logError(message);
-          }
-        }
-      }
 
-      // Make sure that all attributes in the RDN are allowed.
-      int numAVAs = rdn.getNumValues();
-      for (int i = 0; i < numAVAs; i++)
-      {
-        AttributeType t = rdn.getAttributeType(i);
-        if (! nameForm.isRequiredOrOptional(t))
-        {
-          Message message =
-                  ERR_ENTRY_SCHEMA_RDN_DISALLOWED_ATTR.get(
-                    String.valueOf(dn),
-                    t.getNameOrOID(),
-                    nameForm.getNameOrOID());
+          // Make sure that all attributes in the RDN are allowed.
+          int numAVAs = rdn.getNumValues();
+          for (int i = 0; i < numAVAs; i++)
+          {
+            AttributeType t = rdn.getAttributeType(i);
+            if (! nameForm.isRequiredOrOptional(t))
+            {
+              Message message =
+                      ERR_ENTRY_SCHEMA_RDN_DISALLOWED_ATTR.get(
+                        String.valueOf(dn),
+                        t.getNameOrOID(),
+                        nameForm.getNameOrOID());
 
-          if (structuralPolicy == AcceptRejectWarn.REJECT)
-          {
-            invalidReason.append(message);
-            return false;
+              if (structuralPolicy == AcceptRejectWarn.REJECT)
+              {
+                  invalidReason.append(message);
+                return false;
+              }
+              else if (structuralPolicy == AcceptRejectWarn.WARN)
+              {
+                  logError(message);
+                }
+              }
+            }
           }
-          else if (structuralPolicy == AcceptRejectWarn.WARN)
-          {
-            logError(message);
-          }
-        }
-      }
-    }
 
     // If we've gotten here, then things are OK.
     return true;
@@ -2707,27 +2735,33 @@
         }
         else
         {
-          NameForm parentNF =
+          List<NameForm> allNFs =
                DirectoryServer.getNameForm(parentStructuralClass);
-          if ((parentNF != null) && (! parentNF.isObsolete()))
+          if(allNFs != null)
           {
-            DITStructureRule parentDSR =
-                 DirectoryServer.getDITStructureRule(parentNF);
-            if ((parentDSR != null) && (! parentDSR.isObsolete()))
+            for(NameForm parentNF : allNFs)
             {
-              Message message =
-                   ERR_ENTRY_SCHEMA_VIOLATES_PARENT_DSR.get(
-                           String.valueOf(dn),
-                           String.valueOf(parentEntry.getDN()));
+              if ((parentNF != null) && (! parentNF.isObsolete()))
+              {
+                DITStructureRule parentDSR =
+                     DirectoryServer.getDITStructureRule(parentNF);
+                if ((parentDSR != null) && (! parentDSR.isObsolete()))
+                {
+                  Message message =
+                       ERR_ENTRY_SCHEMA_VIOLATES_PARENT_DSR.get(
+                               String.valueOf(dn),
+                               String.valueOf(parentEntry.getDN()));
 
-              if (structuralPolicy == AcceptRejectWarn.REJECT)
-              {
-                invalidReason.append(message);
-                return false;
-              }
-              else if (structuralPolicy == AcceptRejectWarn.WARN)
-              {
-                logError(message);
+                  if (structuralPolicy == AcceptRejectWarn.REJECT)
+                  {
+                    invalidReason.append(message);
+                    return false;
+                  }
+                  else if (structuralPolicy == AcceptRejectWarn.WARN)
+                  {
+                    logError(message);
+                  }
+                }
               }
             }
           }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/Schema.java b/opendj-sdk/opends/src/server/org/opends/server/types/Schema.java
index 39a448f..fcca6a4 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/Schema.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/Schema.java
@@ -34,6 +34,7 @@
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
@@ -180,9 +181,10 @@
                ditStructureRulesByNameForm;
 
   // The set of name forms for this schema, mapped between the
-  // structural objectclass for the definition and the name form
-  // itself.
-  private ConcurrentHashMap<ObjectClass,NameForm> nameFormsByOC;
+  // structural objectclass for the definition and the list of name
+  // forms
+  private ConcurrentHashMap<ObjectClass,List<NameForm>>
+          nameFormsByOC;
 
   // The set of name forms for this schema, mapped between the
   // names/OID and the name form itself.
@@ -258,7 +260,8 @@
          new ConcurrentHashMap<Integer,DITStructureRule>();
     ditStructureRulesByNameForm =
          new ConcurrentHashMap<NameForm,DITStructureRule>();
-    nameFormsByOC = new ConcurrentHashMap<ObjectClass,NameForm>();
+    nameFormsByOC =
+            new ConcurrentHashMap<ObjectClass,List<NameForm>>();
     nameFormsByName = new ConcurrentHashMap<String,NameForm>();
     subordinateTypes =
          new ConcurrentHashMap<AttributeType,List<AttributeType>>();
@@ -2590,14 +2593,12 @@
 
   /**
    * Retrieves the name form definitions for this schema, as a mapping
-   * between the objectclass for the name form and the name form
-   * itself.  Each name form should only be present once, since its
-   * only key is its objectclass.  The contents of the returned
-   * mapping must not be altered.
+   * between the objectclass for the name forms and the name forms
+   * themselves.
    *
    * @return  The name form definitions for this schema.
    */
-  public ConcurrentHashMap<ObjectClass,NameForm>
+  public ConcurrentHashMap<ObjectClass,List<NameForm>>
               getNameFormsByObjectClass()
   {
     return nameFormsByOC;
@@ -2657,15 +2658,17 @@
 
 
   /**
-   * Retrieves the name form definition for the specified objectclass.
+   * Retrieves the name forms definition for the specified
+   * objectclass.
    *
    * @param  objectClass  The objectclass for the name form to
    *                      retrieve.
    *
-   * @return  The requested name form, or <CODE>null</CODE> if no name
-   *          form is registered with the provided objectClass.
+   * @return  The requested name forms, or <CODE>null</CODE> if no
+   *           name forms are registered with the provided
+   *           objectClass.
    */
-  public NameForm getNameForm(ObjectClass objectClass)
+  public List<NameForm> getNameForm(ObjectClass objectClass)
   {
     return nameFormsByOC.get(objectClass);
   }
@@ -2708,19 +2711,25 @@
     synchronized (nameFormsByOC)
     {
       ObjectClass objectClass = nameForm.getStructuralClass();
-
+      List<NameForm> mappedForms = nameFormsByOC.get(objectClass);
       if (! overwriteExisting)
       {
-        if (nameFormsByOC.containsKey(objectClass))
+        if(mappedForms !=null)
         {
-          NameForm conflictingNameForm =
-               nameFormsByOC.get(objectClass);
-
-          Message message = ERR_SCHEMA_CONFLICTING_NAME_FORM_OC.
-              get(nameForm.getNameOrOID(), objectClass.getNameOrOID(),
-                  conflictingNameForm.getNameOrOID());
-          throw new DirectoryException(
-                         ResultCode.CONSTRAINT_VIOLATION, message);
+          //Iterate over the forms to make sure we aren't adding a
+          //duplicate.
+          for(NameForm nf : mappedForms)
+          {
+            if(nf.equals(nameForm))
+            {
+              Message message = ERR_SCHEMA_CONFLICTING_NAME_FORM_OC.
+                get(nameForm.getNameOrOID(),
+                    objectClass.getNameOrOID(),
+                    nf.getNameOrOID());
+              throw new DirectoryException(
+                           ResultCode.CONSTRAINT_VIOLATION, message);
+            }
+          }
         }
 
         String oid = toLowerCase(nameForm.getOID());
@@ -2750,7 +2759,13 @@
         }
       }
 
-      nameFormsByOC.put(objectClass, nameForm);
+      if(mappedForms == null)
+      {
+        mappedForms = new ArrayList<NameForm>();
+      }
+
+      mappedForms.add(nameForm);
+      nameFormsByOC.put(objectClass, mappedForms);
       nameFormsByName.put(toLowerCase(nameForm.getOID()), nameForm);
 
       for (String name : nameForm.getNames().keySet())
@@ -2781,6 +2796,16 @@
   {
     synchronized (nameFormsByOC)
     {
+      List<NameForm> mappedForms = nameFormsByOC.get(
+              nameForm.getStructuralClass());
+      if(mappedForms != null)
+      {
+        mappedForms.remove(nameForm);
+        if(mappedForms.size() == 0)
+        {
+          nameFormsByOC.remove(nameForm.getStructuralClass());
+        }
+      }
       nameFormsByOC.remove(nameForm.getStructuralClass(), nameForm);
       nameFormsByName.remove(toLowerCase(nameForm.getOID()),
                              nameForm);
@@ -3006,15 +3031,18 @@
         }
       }
 
-      for (NameForm nf : nameFormsByOC.values())
+      for (List<NameForm> mappedForms : nameFormsByOC.values())
       {
-        if (nf.getRequiredAttributes().contains(t) ||
-            nf.getOptionalAttributes().contains(t))
+        for(NameForm nf : mappedForms)
         {
-          NameForm newNF = nf.recreateFromDefinition();
-          deregisterNameForm(nf);
-          registerNameForm(newNF, true);
-          rebuildDependentElements(nf, depth+1);
+          if (nf.getRequiredAttributes().contains(t) ||
+              nf.getOptionalAttributes().contains(t))
+          {
+            NameForm newNF = nf.recreateFromDefinition();
+            deregisterNameForm(nf);
+            registerNameForm(newNF, true);
+            rebuildDependentElements(nf, depth+1);
+          }
         }
       }
 
@@ -3058,13 +3086,19 @@
         }
       }
 
-      NameForm nf = nameFormsByOC.get(c);
-      if (nf != null)
+      List<NameForm> mappedForms = nameFormsByOC.get(c);
+      if(mappedForms != null)
       {
-        NameForm newNF = nf.recreateFromDefinition();
-        deregisterNameForm(nf);
-        registerNameForm(newNF, true);
-        rebuildDependentElements(nf, depth+1);
+        for(NameForm nf : mappedForms)
+        {
+          if (nf != null)
+          {
+            NameForm newNF = nf.recreateFromDefinition();
+            deregisterNameForm(nf);
+            registerNameForm(newNF, true);
+            rebuildDependentElements(nf, depth+1);
+          }
+        }
       }
 
       for (DITContentRule dcr : ditContentRules.values())
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
index 19249d4..33ed933 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/backends/SchemaBackendTestCase.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.backends;
 
@@ -2923,8 +2923,8 @@
       "-f", path
     };
 
-    assertFalse(LDAPModify.mainModify(args, false, null, null) == 0);
-    assertFalse(DirectoryServer.getSchema().hasNameForm(nameFormName));
+    assertTrue(LDAPModify.mainModify(args, false, null, null) == 0);
+    assertTrue(DirectoryServer.getSchema().hasNameForm(nameFormName));
   }
 
 
@@ -5405,7 +5405,7 @@
   {
     File tempFile = File.createTempFile("schema", "testImportLDIF");
     tempFile.deleteOnExit();
-    
+
     LDIFExportConfig exportConfig =
       new LDIFExportConfig(tempFile.getAbsolutePath(),
                            ExistingFileBehavior.OVERWRITE);
@@ -5414,7 +5414,7 @@
 
     LDIFImportConfig importConfig =
          new LDIFImportConfig(tempFile.getAbsolutePath());
-    
+
     schemaBackend.importLDIF(importConfig);
   }
 

--
Gitblit v1.10.0