You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by oe...@apache.org on 2007/04/05 21:32:12 UTC
svn commit: r525942 - in
/directory/sandbox/oersoy/guides/das.ldap.design.documentation:
org.apache.tuscany.das.ldap.design.documentation.toc.xml
org.apache.tuscany.das.ldap.design.documentation.xml source/recipes.xml
Author: oersoy
Date: Thu Apr 5 12:32:10 2007
New Revision: 525942
URL: http://svn.apache.org/viewvc?view=rev&rev=525942
Log: (empty)
Removed:
directory/sandbox/oersoy/guides/das.ldap.design.documentation/org.apache.tuscany.das.ldap.design.documentation.toc.xml
directory/sandbox/oersoy/guides/das.ldap.design.documentation/org.apache.tuscany.das.ldap.design.documentation.xml
Modified:
directory/sandbox/oersoy/guides/das.ldap.design.documentation/source/recipes.xml
Modified: directory/sandbox/oersoy/guides/das.ldap.design.documentation/source/recipes.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/oersoy/guides/das.ldap.design.documentation/source/recipes.xml?view=diff&rev=525942&r1=525941&r2=525942
==============================================================================
--- directory/sandbox/oersoy/guides/das.ldap.design.documentation/source/recipes.xml (original)
+++ directory/sandbox/oersoy/guides/das.ldap.design.documentation/source/recipes.xml Thu Apr 5 12:32:10 2007
@@ -1,73 +1,437 @@
<?xml version="1.0" encoding="ASCII"?>
<recipes xmlns="http://maven.apache.org/documentation/recipes/1.0.0"
- label="LDAP DAS Design Recipes">
- <recipeGroup
- id="0"
- label="Initializing the DAS">
- <recipe id="00">
- <challenge>Providing the DAS With an Initial Context</challenge>
- <solution>Use the package namespace.</solution>
- <discussion>
- <![CDATA[
- Suppose the root package of the SDO model has the following
+ label="LDAP DAS Design Guide">
+ <recipeGroup id="0" label="Initializing the LDAP Servers">
+ <recipe id="00">
+ <challenge>
+ Supporting the Base DN Used by the DAS
+ </challenge>
+ <solution>Update the Servers Configuration File</solution>
+ <discussion>
+ <![CDATA[
+ Suppose the root instance of the SDO DataGraph
+ will be stored in an entry defined by the
+ following DN:
+ <pre class="codeblock"> DN: cn=accounts, cn=users, cn=example, cn=com</pre>
+ A partition associated with the RDN <i>cn=com</i>
+ will need to be added to the servers configuration
+ before the subcontext
+ <i>cn=example</i>
+ can be added programmatically, along the remaining subcontexts
+ required to compose the base DN.
+ <br></br>
+ <br></br>
+ The related challenges section contains
+ links describing how to add partitions
+ to various ldap servers.
+ ]]>
+ </discussion>
+ <relatedRecipeDescriptor id="01" />
+ </recipe>
+ <recipe id="01">
+ <challenge>Adding a Partition/Suffix to ApacheDS</challenge>
+ <solution>Update the Servers Configuration File</solution>
+ <discussion>
+ <![CDATA[
+ To add the partition <i>cn=com</i>
+ locate the following xml block in ApacheDS's
+ server.xml configuration file:
+ </br>
+ <pre class="codeblock">
+ <property name="contextPartitionConfigurations">
+ <set>
+ <ref bean="examplePartitionConfiguration"/>
+ </set>
+ </property></pre>
+ </br>
+ Add another ref element so that the
+ xml block now looks like this:
+ </br>
+ </br>
+ <pre class="codeblock">
+ <property name="contextPartitionConfigurations">
+ <set>
+ <ref bean="examplePartitionConfiguration"/>
+ <ref bean="comPartitionConfiguration"/>
+ </set>
+ </property></pre>
+ </br>
+ </br>
+ Then add another partition configuration
+ block below the partition configuration xml block
+ that looks like this:
+ </br>
+ <pre class="codeblock">
+<bean id="examplePartitionConfiguration"
+class="org.apache.directory.server.core.partition.impl.btree.MutableBTreePartitionConfiguration">
+ <property name="name" value="example" />
+ <property name="cacheSize" value="100"/>
+ <property name="suffix" value="dc=example,dc=com" />
+ <property name="optimizerEnabled" value="true" />
+ <property name="synchOnWrite" value="true" />
+ <property name="indexedAttributes">
+ <set>
+ <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration">
+ <property name="attributeId" value="dc" />
+ <property name="cacheSize" value="100" />
+ </bean>
+ ...
+ <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration">
+ <property name="attributeId" value="objectClass" />
+ <property name="cacheSize" value="100" />
+ </bean>
+ </set>
+ </property>
+ <property name="contextEntry">
+ <value>
+ objectClass: top
+ objectClass: domain
+ objectClass: extensibleObject
+ dc: example
+ </value>
+ </property>
+</bean></pre>
+ </br>
+ </br>
+ The properties should be set as follows:
+ </br>
+ </br>
+ <pre class="codeblock">
+<bean id="comPartitionConfiguration"
+class="org.apache.directory.server.core.partition.impl.btree.MutableBTreePartitionConfiguration">
+ <property name="name" value="com" />
+ <property name="cacheSize" value="100"/>
+ <property name="suffix" value="dc=com" />
+ <property name="optimizerEnabled" value="true" />
+ <property name="synchOnWrite" value="true" />
+ <property name="indexedAttributes">
+ <set>
+ <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration">
+ <property name="attributeId" value="dc" />
+ <property name="cacheSize" value="100" />
+ </bean>
+ ...
+ <bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration">
+ <property name="attributeId" value="objectClass" />
+ <property name="cacheSize" value="100" />
+ </bean>
+ </set>
+ </property>
+ <property name="contextEntry">
+ <value>
+ objectClass: top
+ objectClass: domain
+ objectClass: extensibleObject
+ dc: example
+ </value>
+ </property>
+</bean></pre>
+ </br>
+ </br>
+ When the ApacheDS is restarted, the com
+ partition will be loaded.
+ ]]>
+ </discussion>
+ </recipe>
+ </recipeGroup>
+
+ <recipeGroup id="1" label="Initializing the DAS">
+
+ <recipe id="10">
+ <challenge>Loading the Generator Model</challenge>
+ <solution>
+ Set the Required Parameters on the DASConfig Instance
+ </solution>
+ <discussion>
+ <![CDATA[
+ The Generator Model is the model
+ used to generate static java interfaces
+ and implementations for the model's
+ DataObjects.
+ </br>
+ </br>
+ When code generation is used to
+ define the model classes,
+ DASConfig.loadGeneratorModel()
+ is used to load the generator resource
+ containing the code generation parameters.
+ </br>
+ </br>
+ When generating static java interfaces based
+ on a model, the DAS uses the basePackage
+ attribute and the prefix attribute defined
+ on the generator model to load the model's
+ classes.
+ </br>
+ </br>
+ In order to load the generator model
+ the following DASConfig attributes must be set:
+ <ul>
+ <li>
+ </li>genModelName<li>
+ </li>jarName<li>
+ <li>repositoryBase</li>
+ </ul>
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="11">
+ <challenge>
+ Providing the DAS With an Initial Context
+ </challenge>
+ <solution>Use DASConfig's initialContext Property</solution>
+ <discussion>
+ <![CDATA[
+ This approach is used when the DAS is using the
+ dynamic Data Object API to create the DataObjects.
+ </br>
+ </br>
+ The DAS will use the <i>initialContext</i> property
+ on the DASConfig class. To initialize
+ this property, specify it in the configuration
+ as follows:
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="12">
+ <challenge>
+ Providing the DAS With an Initial Context
+ </challenge>
+ <solution>Use the package namespace.</solution>
+ <discussion>
+ <![CDATA[
+ This approach is used when static java interfaces
+ have been created using a generator model.
+ The DAS configuration loads the generator
+ model resource, and then gets the model package
+ namespace from it.
+ </br>
+ </br>
+ If the root package of the SDO model has the following
namespace:
</br>
</br>
- <pre class="codeblock"> http://com.example.org/users/accounts</pre>
+ <pre class="codeblock"> http://example.com/users/accounts</pre>
</br>
</br>
- Thus we make the initial context:
-
+ The initial context is:
</br>
</br>
- <pre class="codeblock"> cn=accounts, cn=users, cn=org, cn=example, cn=com</pre>
+ <pre class="codeblock"> cn=accounts, cn=users, cn=example, cn=com</pre>
</br>
</br>
-
- The model root (DocumentRoot, or some other Class representing the root)
- will be stored in the LDAP repository using this initial context to reference
- it.
]]>
- </discussion>
- </recipe>
- </recipeGroup>
- <recipeGroup
- id="1"
- label="Storing a New DataGraph">
+ </discussion>
+ </recipe>
+ </recipeGroup>
+
+ <recipeGroup id="2" label="Writing DataGraph Metadata">
+
+ <recipe id="20">
+ <challenge>
+ Creating Metadata OID Values (Namespacing LDAP Metadata)
+ </challenge>
+ <solution>Use the model package namespace.</solution>
+ <discussion>
+ <![CDATA[
+ TODO - Alex's checksum idea
+
+ TODO - Add Emmanuel's Ascii charachter idea.
+
+ First either strip illegal characters from the package namespace and use
+ that as the globally unique OID or produce a checksum of the package namespace
+ and use that as the globally unique OID.
+ </br>
+ </br>
+ Then creates a branch per LDAP Metadata Item
+ (Syntax, AttributeType, ObjectClass, etc.)
+ by adding an integer onto the globally unique OID.
+ </br>
+ </br>
+ Then add another integer onto the branch for each
+ Metadata Item to be created, creating a unique namespace
+ for that Metadata Item.
+
+
+
+ Scratched
+ ==========================================================================
+ The DAS has preconfigured Private Enterprise Numbers (PENs)
+ branches per supported LDAP Server.
+ </br>
+ </br>
+ There is one branch for LDAP Syntax entries, one for
+ LDAP AttributeType entries, and one for ObjectClass entries.
+ </br>
+ </br>
+ The DAS uses these branches, along with the model's
+ package namespace, when creating new LDAP metadata entries.
+ </br>
+ </br>
+ Hence the the convention used to define the LDAP namespace
+ (An OID string) is to append to the globally unique OID for the
+ LDAP Metadata Item (TODO - Define Metadata Item as an either an
+ ObjectClass, AttributeType, Syntax, Control, etc.) the model packages
+ namespace. appending
+ the package namespace If a new DataType is being used by a property of the
+ a DataObject instance, the DAS will add the DataType's
+ corresponding Syntax using the DataType's package namespace,
+ along with the LDAP Server's OID for Syntax entries. to create
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="21">
+ <challenge>Creating the LDAP Syntax Entry</challenge>
+ <solution>Use JNDI</solution>
+ <discussion>
+ <![CDATA[
+ The <i>name</i> attribute (simple property) of an LDAP
+ Syntax entry corresponds
+ to the <i>name</i> member of the SDO DataType class.
+ </br>
+ </br>
+ A syntax entry is defined by three attributes:
+ - description
+ - OID
+ - Name
+ These must all be unique with respect to
+ their context siblings within the LDAP server.
+ Creating a globally unqiue OID requires
+ a Private Enterprise Number (PEN), which can be
+ obtained from IANA. The PEN is then pre fixed to
+ another integer (or combination of integers separated
+ by periods), and the combination of the two
+ make a unique identifier for the Syntax.
+ </br>
+ </br>
+ The following example shows how to define a
+ syntax entry for "java.lang.String" in ApacheDS:
+ </br>
+ </br>
+ <pre class="codeblock">
+private static final String APACHEDS_LDAP_SCHEMA_OID_SYNTAX_BRANCH = "1.3.6.1.4.1.18060.0.4.X.0";
+private static final String APACHEDS_LDAP_SCHEMA_JAVA_STRING_LOCAL_SYNTAX_OID = "java.lang.String";
+private static final String APACHEDS_LDAP_SCHEMA_JAVA_STRING_GLOBAL_SYNTAX_OID = APACHEDS_LDAP_SCHEMA_SYNTAX_OID_BRANCH +"." + JAVA_STRING_SYNTAX_LOCAL_OID;
+...
+Attributes ldapAttributes = new AttributesImpl();
+Attribute objectClass = new AttributeImpl(
+ SystemSchemaConstants.OBJECT_CLASS_AT,
+ "top" );
+objectClass.add( MetaSchemaConstants.META_TOP_OC );
+objectClass.add( MetaSchemaConstants.META_SYNTAX_OC );
+ldapAttributes.put( objectClass );
+ldapAttributes.put( MetaSchemaConstants.M_OID_AT, APACHEDS_LDAP_SCHEMA_JAVA_STRING_GLOBAL_SYNTAX_OID );
+ldapAttributes.put( MetaSchemaConstants.M_DESCRIPTION_AT, APACHEDS_LDAP_SCHEMA_JAVA_STRING_LOCAL_SYNTAX_OID );
+
+String EStringSyntaxRDN = "MetaSchemaConstants.M_OID_AT + "=" + APACHEDS_LDAP_SCHEMA_JAVA_STRING_GLOBAL_SYNTAX_OID;
+
+//With the current context being "ou=syntaxes,ou=schema"
+ctx.createSubcontext(EStringSyntaxRDN, ldapAttributes);
+ </pre>
+ </br>
+ </br>
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="22">
+ <challenge>
+ Creating an LDAP AttributeType Metadata Entry
+ </challenge>
+ <solution>Use JNDI</solution>
+ <discussion>
+ <![CDATA[
+ The LDAP AttributeType corresponds to the SDO
+ DataType.
+ </br>
+ </br>
+ Here's an example of how to create LDAP AttributeType
+ for the Ecore EString DataType:
+ </br>
+ </br>
+ <pre class="codeblock">
+
+...
+Attributes ldapAttributes = new AttributesImpl();
+Attribute objectClass = new AttributeImpl(
+ SystemSchemaConstants.OBJECT_CLASS_AT,
+ "top" );
+objectClass.add( MetaSchemaConstants.META_TOP_OC );
+objectClass.add( MetaSchemaConstants.META_ATTRIBUTE_TYPE_OC );
+ldapAttributes.put( objectClass );
+ldapAttributes.put( MetaSchemaConstants.M_NAME_AT, "baseDN");
+ldapAttributes.put( MetaSchemaConstants.M_OID_AT, SOME_GLOBAL_OID );//A trigger in ApacheDS will add this.
+ldapAttributes.put( MetaSchemaConstants.M_DESCRIPTION_AT, "baseDN member of org.tuscany.das.ldap.config.DASConfig" );
+ldapAttributes.put( MetaSchemaConstants.M_EQUALITY_AT, "caseIgnoreMatch" );
+ldapAttributes.put( MetaSchemaConstants.M_SINGLE_VALUE_AT, "FALSE" );
+ldapAttributes.put( MetaSchemaConstants.M_USAGE_AT, "directoryOperation" );
+
+String EStringSyntaxRDN = "MetaSchemaConstants.M_OID_AT + "=" + SOME_GLOBAL_OID;
+
+//With the current context being "ou=attributeTypes,ou=schema"
+ctx.createSubcontext(EStringSyntaxRDN, ldapAttributes);
+ </pre>
+ </br>
+ </br>
+
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="23">
+ <challenge>Creating an LDAP ObjectClass Entry</challenge>
+ <solution>Use JNDI</solution>
+ <discussion>
+ <![CDATA[
+ The LDAP ObjectClass corresponds
+ to an SDO Type or EMF EClass.
+ </br>
+ </br>
+ Here's an example of how to create an LDAP ObjectClass
+ for the org.tuscany.das.ldap.config.DASConfig EClass:
+ </br>
+ </br>
+ <pre class="codeblock">
+...
+Attributes ldapAttributes = new AttributesImpl();
+Attribute objectClass = new AttributeImpl(
+ SystemSchemaConstants.OBJECT_CLASS_AT,
+ "top" );
+objectClass.add( MetaSchemaConstants.META_TOP_OC );
+objectClass.add( MetaSchemaConstants.META_ATTRIBUTE_TYPE_OC );
+ldapAttributes.put( objectClass );
+ldapAttributes.put( MetaSchemaConstants.M_NAME_AT, "DASConfig");
+ldapAttributes.put( MetaSchemaConstants.M_DESCRIPTION_AT, "org.tuscany.das.ldap.config.DASConfig");
+ldapAttributes.put( MetaSchemaConstants.M_TYPE_OBJECT_CLASS_AT, "STRUCTURAL" );
+ldapAttributes.put( MetaSchemaConstants.M_MUST_AT, "cn" );
+ldapAttributes.put( MetaSchemaConstants.M_MAY_AT, "ou" );
+
+String EStringSyntaxRDN = "MetaSchemaConstants.M_OID_AT + "=" + SOME_GLOBAL_OID;
+
+//With the current context being "ou=attributeTypes,ou=schema"
+ctx.createSubcontext(EStringSyntaxRDN, ldapAttributes);
+ </pre>
+ </br>
+ </br>
+
+ ]]>
+ </discussion>
+ </recipe>
- <recipe id="10">
- <challenge>Getting the Model Resource's Root Object</challenge>
- <solution>Use the RDN from the initial context.</solution>
- <discussion>
- <![CDATA[
- In this case the RDN for the root object in the model
- is
- </br>
- </br>
- <pre class="codeblock"> accounts</pre>
- </br>
- </br>
- Therefore we can get our model root object like this:
- </br>
- </br>
- <pre class="codeblock"> EObject eObjectRoot = resource.getEObject("//@accounts"); </pre>
- </br>
- </br>
- ]]>
- </discussion>
- </recipe>
- <recipe id="11">
- <challenge>Writing an LDAP ObjectClass per EClass in the Model</challenge>
- <solution>Use the LDAP Server's Dynamic Schema Capabilities</solution>
- <discussion>
- <![CDATA[
+ <recipe id="xx">
+ <challenge>
+ Writing an LDAP ObjectClass per EClass in the Model
+ </challenge>
+ <solution>
+ Use the LDAP Server's Dynamic Schema Capabilities
+ </solution>
+ <discussion>
+ <![CDATA[
First create a new ObjectClass representing the SDO Type (Class)
and add it to a new instance of LDAP attributes.
@@ -183,15 +547,300 @@
recipe, and it will know how many to retrieve based on the value stored
in the reference attribute.
]]>
- </discussion>
- <relatedRecipeDescriptor id="10" />
- </recipe>
-
- <recipe id="12">
- <challenge>Creating a DataGraph in ADS</challenge>
- <solution>Use DAS.LDAP.write(eObject) [Just made it up]</solution>
- <discussion>
- <![CDATA[
+ </discussion>
+ </recipe>
+ </recipeGroup>
+
+ <recipeGroup label="Restoring DataGraph Metadata" id="3">
+ <recipe id="30">
+ <challenge>Creating the Model's EPackage</challenge>
+ <solution>
+ Use EcoreFactory.eINSTANCE.createEPackage()
+ </solution>
+ <discussion>
+ <![CDATA[
+ </br>
+ </br>
+ <pre class="codeblock">
+ EPackage ePackage = EcoreFactory.eINSTANCE.createEPackage()</pre>
+ </br>
+ </br>
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="30">
+ <challenge>Setting the EPackage Namespace Prefix</challenge>
+ <solution>
+ Use values of the last two segments of the Root
+ DataObject's DN
+ </solution>
+ <discussion>
+ <![CDATA[
+ Note that this is only necessary when the
+ DAS does not use a generator model.
+ </br>
+ </br>
+ If the DN of the root DataObject is
+ </br>
+ </br>
+ <pre class="codeblock">
+ DN: cn=v100, cn=accounts, cn=users, cn=example, cn=com
+ </br>
+ </br>
+ The namespace prefix is set to:
+ </br>
+ </br>
+ <pre class="codeblock">
+ DN: cn=v100, cn=accounts, cn=users, cn=example, cn=com
+ </br>
+ </br>
+ The namespace prefix gets set to <i>AccountsV100</i>.
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="30">
+ <challenge>Setting the EPackage Namespace</challenge>
+ <solution>Use values of the Root DataObject's DN</solution>
+ <discussion>
+ <![CDATA[
+ Note that this is only necessary when the
+ DAS does not use a generator model.
+ </br>
+ </br>
+ If the DN of the root DataObject is
+ </br>
+ </br>
+ <pre class="codeblock">
+ DN: cn=v100, cn=accounts, cn=users, cn=example, cn=com
+ </br>
+ </br>
+ The package namespace gets set to:
+ </br>
+ </br>
+ <pre class="codeblock">
+ DN: cn=v100, cn=accounts, cn=users, cn=example, cn=com
+ </br>
+ </br>
+ The namespace prefix gets set to <i>accounts.v100</i>.
+ ]]>
+ </discussion>
+ </recipe>
+
+ <recipe id="30">
+ <challenge>
+ Obtaining the Name of the DataObject Class
+ </challenge>
+ <solution>Use the RDN</solution>
+ <discussion>
+ <![CDATA[
+ By convention the name of the DataObject stored corresponds
+ to the RDN of its entry. So for the RDN:
+
+ </br>
+ </br>
+ <pre class="codeblock"> accounts</pre>
+ </br>
+ </br>
+
+ we would get our EClass or Type name like this this:
+
+ </br>
+ </br>
+ <pre class="codeblock">
+ String className = StringUtils.capitalize( JNDIUtils.getRDN(rootDataObjectDN) ); </pre>
+ </br>
+ </br>
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="30">
+ <challenge>
+ Creating an Instance of the DataObject's Classifier
+ </challenge>
+ <solution>
+ Use EcoreFactory.eINSTANCE.createEClass()
+ </solution>
+ <discussion>
+ <![CDATA[
+ </br>
+ </br>
+ <pre class="codeblock">
+ EClass eClass = EcoreFactory.eINSTANCE.createEClass();
+ eClass.setName()
+ </pre>
+ </br>
+ </br>
+
+ we would get our EClass or Type name like this this:
+
+ </br>
+ </br>
+ <pre class="codeblock">
+ String className = StringUtils.capitalize( JNDIUtils.getRDN(DN) ); </pre>
+ </br>
+ </br>
+ ]]>
+ </discussion>
+ </recipe>
+
+ <recipe id="31">
+ <challenge>
+ Creating an Instance of the SDO DataObject's Type
+ </challenge>
+ <solution>Use EcoreFactory.eINSTANCE</solution>
+ <discussion>
+ <![CDATA[
+ </br>
+ </br>
+ <pre class="codeblock">EClass eClass = EcoreFactory.eINSTANCE.createEClass()</pre>
+ </br>
+ </br>
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="32">
+ <challenge>
+ Getting the DataObject's Simple Properties from the LDAP
+ Entry
+ </challenge>
+ <solution>Use DirContext.getAttributes()</solution>
+ <discussion>
+ <![CDATA[
+ First get a list of all the attributes contained in the entry:
+ </br>
+ </br>
+ <pre class="codeblock">Attributes ldapAttributes = directoryContext.getAttributes(rootDataObjectDN);</pre>
+ </br>
+ </br>
+
+ Then clone it, because we need both the complex type metadata, for
+ retrieving DataObject references, and the
+ simple properties:
+
+ </br>
+ </br>
+ <pre class="codeblock">Attributes ldapAttributesClone = ldapAttributes.clone();</pre>
+ </br>
+ </br>
+
+ Then delete the objectClass attribute from the ldapAttributes map:
+
+ </br>
+ </br>
+ <pre class="codeblock">ldapAttributes.remove(SystemSchemaConstants.OBJECT_CLASS_AT);</pre>
+ </br>
+ </br>
+
+ Then remove all the attributes whose name contains the word EReference.
+
+ </br>
+ </br>
+ <pre class="codeblock">TODO Code</pre>
+ </br>
+ </br>
+
+ We now have a map of the simple property names and their corresponding
+ values.
+
+ </br>
+ </br>
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="33">
+ <challenge>
+ Getting the DataObject's Complex Properties's Metadata
+ </challenge>
+ <solution>Use DirContext.getAttributes()</solution>
+ <discussion>
+ <![CDATA[
+ First get a list of all the attributes contained in the entry:
+ </br>
+ </br>
+ <pre class="codeblock">Attributes ldapAttributes = directoryContext.getAttributes(rootDataObjectDN);</pre>
+ </br>
+ </br>
+
+ </br>
+ </br>
+ <pre class="codeblock">Attributes ldapAttributesClone = ldapAttributes.clone();</pre>
+ </br>
+ </br>
+
+ Then delete the objectClass attribute from the ldapAttributes map:
+
+ </br>
+ </br>
+ <pre class="codeblock">ldapAttributes.remove(SystemSchemaConstants.OBJECT_CLASS_AT);</pre>
+ </br>
+ </br>
+
+ Then if the attribute's name does not contain the String "EReference",
+ we remove it.
+
+ </br>
+ </br>
+ <pre class="codeblock">TODO Code</pre>
+ </br>
+ </br>
+
+ We now have a map of the complex property names and their corresponding
+ meta data values.
+ </br>
+ </br>
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="34">
+ <challenge>Adding the Root EClass's EAttributes</challenge>
+ <solution>
+ Use the Simple Properties Attributes Map
+ </solution>
+ <discussion>
+ <![CDATA[
+ For each ldapAttribute in the entry, the DAS first creates
+ an EAttribute instance, if one has not already been created
+ and added to the model's EPackage.
+ <pre class="codeblock"> EAttribute eAttribute = EcoreFactory.eINSTANCE.createEAttribute(); </pre>
+ </br>
+ </br>
+ The EAttribute requires a DataType instance in order
+ to set the the EAttribute's eType property, so the DAS
+ uses the name of the attributeType's Syntax OID
+ to lookup the DataType on the EPackage. If the
+ DataType reference returned is null, the DAS creates
+ the DataType and adds it to the EPackage.
+ </br>
+ </br>
+ The EAttribute instance also needs a name.
+ The name of the EAttribute instance is the
+ name of the attributeType.
+ </br>
+ </br>
+ If the EAttribute instance is a multiplicity
+ many EAttribute, indicated by MetaSchemaConstants.M_SINGLE_VALUE_AT
+ property of the attributeType being set to false, the
+ EAttribute's upperBound property is set to "-1".
+ </br>
+ </br>
+ Lastly if the attributeType is a
+ MetaSchemaConstants.M_MUST_AT attribute,
+ then the EAttribute required property is set to true.
+ </br>
+ </br>
+ ]]>
+ </discussion>
+ </recipe>
+ </recipeGroup>
+
+ <recipeGroup label="Writing a DataGraph" id="4">
+ <recipe id="40">
+ <challenge>Writing a DataGraph to ADS</challenge>
+ <solution>
+ Use DAS.LDAP.write(eObject) [Just made it up]
+ </solution>
+ <discussion>
+ <![CDATA[
Creating a DataGraph in ADS means writing all the
DataObjects contained in the graph to ADS,
along with their corresponding
@@ -318,15 +967,17 @@
</br>
</br>
]]>
- </discussion>
- <relatedRecipeDescriptor id="11" />
- </recipe>
-
- <recipe id="13">
- <challenge>Creating an EReference Subcontext</challenge>
- <solution>Use the JNDI InitialContext bind Operation</solution>
- <discussion>
- <![CDATA[
+ </discussion>
+ <relatedRecipeDescriptor id="11" />
+ </recipe>
+
+ <recipe id="13">
+ <challenge>Creating an EReference Subcontext</challenge>
+ <solution>
+ Use the JNDI InitialContext bind Operation
+ </solution>
+ <discussion>
+ <![CDATA[
We need to establish a subcontext for each EReference.
<br/>
<br/>
@@ -385,9 +1036,75 @@
<br/>
DN: cn=user2, cn=accounts, cn=users, cn=org, cn=example, cn=com
<br/>
- ]]>
- </discussion>
- </recipe>
-
- </recipeGroup>
+]]>
+ </discussion>
+ </recipe>
+
+ </recipeGroup>
+
+ <recipeGroup label="Restoring a DataGraph" id="5">
+
+ <recipe id="50">
+ <challenge>Creating a DataObject Instance</challenge>
+ <solution>Use the RDN from the current directory context</solution>
+ <discussion>
+ <![CDATA[
+ First get the model's Factory from the EPackage.
+ </br>
+ </br>
+ <pre class="codeblock">EFactory eFactory = modelEPackage.getFactory()</pre>
+ </br>
+ </br>
+ Then create an instance of the
+
+ Therefore we can get our model root object like this:
+
+ </br>
+ </br>
+ <pre class="codeblock"> EObject eObject = eFactory.create("FileUtils.capitalize(rdnValue);</pre>
+ </br>
+ </br>
+
+ Note that if the rdnValue corresponds to a multiplicity many
+ EReference then the integer at the end of the rdnValue must
+ be removed.
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="51">
+ <challenge>Setting a DataObject's Simple Properties</challenge>
+ <solution></solution>
+ <discussion>
+ <![CDATA[
+ ]]>
+ </discussion>
+ </recipe>
+ <recipe id="52">
+ <challenge> Setting the DataObject's Complex Properties</challenge>
+ <solution></solution>
+ <discussion>
+ <![CDATA[
+ ]]>
+ </discussion>
+ </recipe>
+ </recipeGroup>
+
+
+ <recipeGroup id="x" label="Prototype Setup">
+
+ <recipe id="x0">
+ <challenge>Creating the Prototype Project</challenge>
+ <solution>
+ Run mvn archetype:create -DartifactId=das.ldap.prototype -DgroupId=org.apache.tuscany
+ </solution>
+ </recipe>
+
+ <recipe id="x1">
+ <challenge>
+ Adding the EMF Dependencies to the Build
+ </challenge>
+ <solution>See Discussion</solution>
+ <discussion></discussion>
+ </recipe>
+ </recipeGroup>
</recipes>