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">
+ &lt;property name="contextPartitionConfigurations"&gt;
+   &lt;set&gt;
+     &lt;ref bean="examplePartitionConfiguration"/&gt;
+   &lt;/set&gt;
+ &lt;/property&gt;</pre>
+            </br>
+			Add another ref element so that the 
+			xml block now looks like this:
+			</br>
+			</br>
+            <pre class="codeblock">
+ &lt;property name="contextPartitionConfigurations"&gt;
+   &lt;set&gt;
+     &lt;ref bean="examplePartitionConfiguration"/&gt;
+     &lt;ref bean="comPartitionConfiguration"/&gt;
+   &lt;/set&gt;
+ &lt;/property&gt;</pre>
+            </br>
+            </br>
+			Then add another partition configuration
+			block below the partition configuration xml block
+			that looks like this:
+			</br>
+            <pre class="codeblock">
+&lt;bean id="examplePartitionConfiguration" 
+class="org.apache.directory.server.core.partition.impl.btree.MutableBTreePartitionConfiguration"&gt;
+    &lt;property name="name" value="example" /&gt;
+    &lt;property name="cacheSize" value="100"/&gt;
+    &lt;property name="suffix" value="dc=example,dc=com" /&gt;
+    &lt;property name="optimizerEnabled" value="true" /&gt;
+    &lt;property name="synchOnWrite" value="true" /&gt;
+    &lt;property name="indexedAttributes"&gt;
+      &lt;set&gt;
+        &lt;bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"&gt;
+          &lt;property name="attributeId" value="dc" /&gt;
+          &lt;property name="cacheSize" value="100" /&gt;
+        &lt;/bean&gt;
+        ...
+        &lt;bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"&gt;
+          &lt;property name="attributeId" value="objectClass" /&gt;
+          &lt;property name="cacheSize" value="100" /&gt;
+        &lt;/bean&gt;
+      &lt;/set&gt;
+    &lt;/property&gt;
+    &lt;property name="contextEntry"&gt;
+      &lt;value&gt;
+        objectClass: top
+        objectClass: domain
+        objectClass: extensibleObject
+        dc: example
+      &lt;/value&gt;
+    &lt;/property&gt;
+&lt;/bean&gt;</pre>
+			</br>
+			</br>
+			The properties should be set as follows:
+			</br>
+			</br>
+            <pre class="codeblock">
+&lt;bean id="comPartitionConfiguration" 
+class="org.apache.directory.server.core.partition.impl.btree.MutableBTreePartitionConfiguration"&gt;
+    &lt;property name="name" value="com" /&gt;
+    &lt;property name="cacheSize" value="100"/&gt;
+    &lt;property name="suffix" value="dc=com" /&gt;
+    &lt;property name="optimizerEnabled" value="true" /&gt;
+    &lt;property name="synchOnWrite" value="true" /&gt;
+    &lt;property name="indexedAttributes"&gt;
+      &lt;set&gt;
+        &lt;bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"&gt;
+          &lt;property name="attributeId" value="dc" /&gt;
+          &lt;property name="cacheSize" value="100" /&gt;
+        &lt;/bean&gt;
+        ...
+        &lt;bean class="org.apache.directory.server.core.partition.impl.btree.MutableIndexConfiguration"&gt;
+          &lt;property name="attributeId" value="objectClass" /&gt;
+          &lt;property name="cacheSize" value="100" /&gt;
+        &lt;/bean&gt;
+      &lt;/set&gt;
+    &lt;/property&gt;
+    &lt;property name="contextEntry"&gt;
+      &lt;value&gt;
+        objectClass: top
+        objectClass: domain
+        objectClass: extensibleObject
+        dc: example
+      &lt;/value&gt;
+    &lt;/property&gt;
+&lt;/bean&gt;</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>