You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cocoon.apache.org by renzo estrella <re...@yahoo.com> on 2000/10/31 19:56:35 UTC

request of peer review of ldap xsl modification

I'm including my modificatThe to ldap.xsl and an
example ldapadd.xml.
I modified the xsp module that originally allowed
  to make anonymous queries to an ldap directory
  service so that it now allows
  additions,deletions,modifications
  and logging in. It can also do these in batch mode
  so that one xml file can make multiple changes to 
  the directory plus It can give you error reporting
  on the specific operation that failed and success
  on the ones that worked. I left the querying
unchanged except that I allow simple authentication. 

I'm allowing two type of entries:
  1) ldap:absolute-dn where you must specify the
absolute dn for the entry
  2) ldap:rn where you specify only a portion of the
dn and the rest of it 
      is passed as part of query string so the xml can
be used in different contexts
This is does not follow DSML naming conventions
because currently DSML doesn't
  specify modification operations only the
descriptions of entries. 
But this can be changed if needed.


ldap.xsl file:

<?xml version="1.0"?>

<!-- An LDAP XSP Taglib. Contact:
alain@dpt-info.u-strasbg.fr -->

<xsl:stylesheet version="1.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:ldap="http://www.apache.org/2000/LDAP"
	xmlns:xsp="http://www.apache.org/1999/XSP/Core"
>


  <xsl:template name="get-nested-content">
    <xsl:param name="content"/>
    <xsl:choose>
      <xsl:when test="$content/*">
        <xsl:apply-templates select="$content/*"/>
      </xsl:when>
      <xsl:otherwise>"<xsl:value-of
select="$content"/>"</xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="get-nested-string">
    <xsl:param name="content"/>
    <xsl:choose>
      <xsl:when test="$content/*">
        ""
        <xsl:for-each select="$content/node()">
          <xsl:choose>
            <xsl:when test="name(.)">
              + <xsl:apply-templates select="."/>
            </xsl:when>
            <xsl:otherwise>
              + "<xsl:value-of
select="translate(.,'&#9;&#10;&#13;','   ')"/>"
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each>
      </xsl:when>
      <xsl:otherwise>"<xsl:value-of
select="$content"/>"</xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="cleanup">
    <xsp:logic>
      cleanUp();
    </xsp:logic>
  </xsl:template>

  <xsl:template name="rn-add-entry">
    <xsl:if test="ldap:rn">
      <xsl:for-each select="ldap:rn">
        <xsl:call-template name="get-rn-name"/>
        <xsl:call-template name="add-entry"/>
      </xsl:for-each>

    </xsl:if>
  </xsl:template>  

  <xsl:template name="rn-modify-entry">
    <xsl:if test="ldap:rn">
      <xsl:for-each select="ldap:rn">
        <xsl:call-template name="get-rn-name"/>
        <xsl:call-template name="modify-entry"/>
      </xsl:for-each>
    </xsl:if>
  </xsl:template>  

  <xsl:template name="rn-delete-entry">
    <xsl:if test="ldap:rn">
      <xsl:for-each select="ldap:rn">
        <xsl:call-template name="get-rn-name"/>
        <xsl:call-template name="delete-entry"/>
      </xsl:for-each>
    </xsl:if>
  </xsl:template>  

  <xsl:template name="dn-add-entry">
    <xsl:if test="ldap:absolute-dn">
      <xsl:for-each select="ldap:absolute-dn">
        <xsl:call-template name="get-dn-name"/>
        <xsl:call-template name="add-entry"/>
      </xsl:for-each>
   </xsl:if>
  </xsl:template>  

  <xsl:template name="dn-modify-entry">
    <xsl:if test="ldap:absolute-dn">
      <xsl:for-each select="ldap:absolute-dn">
        <xsl:call-template name="get-dn-name"/>
        <xsl:call-template name="modify-entry"/>
      </xsl:for-each>
    </xsl:if>
  </xsl:template>  

  <xsl:template name="dn-delete-entry">
    <xsl:if test="ldap:absolute-dn">
      <xsl:for-each select="ldap:absolute-dn">
        <xsl:call-template name="get-dn-name"/>
        <xsl:call-template name="delete-entry"/>
      </xsl:for-each>
   </xsl:if>
  </xsl:template>

  <xsl:template name="get-dn-name">
      <xsp:logic>
        _dn=getString("<xsl:value-of
select="@val"/>","");
      </xsp:logic>
  </xsl:template>  

  <xsl:template name="get-rn-name">
      <xsp:logic>
        _dn=getString("<xsl:value-of
select="@val"/>","");
        _dn=getDN(_dn, request, document);
        if( null==_dn || _dn.length() &lt; 1 )
        {
         
<xsp:content><xsp:expr>_exceptionElement</xsp:expr></xsp:content>
          return;
        }
      </xsp:logic>
  </xsl:template>  

  <xsl:template name="add-entry">
    <xsl:call-template name="get-attributes"/>
    <xsp:logic>
      if( !addEntry(document) )
      {
        cleanAttribs();
       
<xsp:content><xsp:expr>_exceptionElement</xsp:expr></xsp:content>
      }
      else
      {
        cleanAttribs();
        setElementMessage(document,
                  "successfull addition for
position["+_processPosition+"]");
       
<xsp:content><xsp:expr>_docOKElement</xsp:expr></xsp:content>
      } 
    </xsp:logic>

  </xsl:template>  

  <xsl:template name="modify-entry">
    <xsl:call-template name="get-attributes"/>
    <xsp:logic>
      if( !modifyEntry(document) )
      {
        cleanAttribs();
       
<xsp:content><xsp:expr>_exceptionElement</xsp:expr></xsp:content>
      }
      else
      {
        cleanAttribs();
        setElementMessage(document,
                  "successfull update for
position["+_processPosition+"]");
       
<xsp:content><xsp:expr>_docOKElement</xsp:expr></xsp:content>
      } 
    </xsp:logic>
  </xsl:template>  

  <xsl:template name="delete-entry">
     <xsp:logic>
        if( !delEntry(document) )
        {
          
<xsp:content><xsp:expr>_exceptionElement</xsp:expr></xsp:content>
        }
        else
        {
           setElementMessage(document,
                  "successfull deletion for
position["+_processPosition+"]");
          
<xsp:content><xsp:expr>_docOKElement</xsp:expr></xsp:content>
        }
     </xsp:logic>
  </xsl:template>  

  <xsl:template name="get-attributes">
    <xsl:for-each select="ldap:attributes">
      <xsp:logic>
        _attrib=getString("<xsl:value-of
select="text()"/>","");
        addAttrib(_attrib);
      </xsp:logic>
    </xsl:for-each>
  </xsl:template>  


  <xsl:template match="xsp:page">
    <xsp:page>
      <xsl:apply-templates select="@*"/>
      <xsp:structure>
        <xsp:include>javax.naming.*</xsp:include>
       
<xsp:include>javax.naming.directory.*</xsp:include>
        <xsp:include>javax.naming.ldap.*</xsp:include>
        <xsp:include>java.util.Hashtable</xsp:include>
      </xsp:structure>
      <xsp:logic>

      private static Hashtable _attribs=null;
      private static LdapContext _ldapContex=null;
      private static boolean _showStackTrace=false;
      private static String _attrib="", _dn="";
      private static String
_serverURL="",_driver="",_principal="",_credentials="";
      private static String
_err_element="error",_doc_element="",_entry_element="";
      private static Element _exceptionElement=null;
      private static Element _docOKElement=null;
      private static int _processPosition=0;

    private static void init()
    {
      _attrib=""; _dn="";
      _attribs=null;
     
_serverURL="";_driver="";_principal="";_credentials="";
      _ldapContex=null;
      _err_element="error";
      _processPosition=0;
      _exceptionElement=null;
       _showStackTrace=false;
    }
    
    private static void cleanUp()
    {
      _processPosition=0;
      _attrib=""; _dn="";
      _attribs=null;
     
_serverURL="";_driver="";_principal="";_credentials="";
      _ldapContex=null;
      _showStackTrace=false;
    }

    private static void setElementMessage(Document
document, String strMsg)
    {
      _docOKElement =
document.createElement(_doc_element);
      Element eentry =
document.createElement(_entry_element);
     
eentry.appendChild(document.createTextNode(strMsg));
      _docOKElement.appendChild(eentry);
    }

    private static void addAttrib(String strAttr)
    {
      if( null==strAttr )
         return;
      if( null==_attribs )
         _attribs=new Hashtable(10);//only allocates
if needed

      int pos=strAttr.indexOf("=");
      String key="", val="";
      if( pos > 0 )
      {  //must have a key but allow empty associated
value
         key=strAttr.substring(0,pos);
         if( strAttr.length() >= pos+1 )
            val=strAttr.substring(pos+1);
         _attribs.put(key,val);
      }
    }
    private static boolean foobar()
    {
  
      try{ PrintWriter pww=new PrintWriter(new
FileWriter("tester.txt"));
        pww.println("_serverURL="+_serverURL);
        pww.flush();
      }catch(Exception ex){}
      return true;
    }

    private static boolean haveAttributes()
    {
      return (null!=_attribs &amp;&amp;
_attribs.size() &gt; 0) ;
    }
    private static javax.naming.directory.Attributes
getAttributes()
    {
      if( !haveAttributes() ) return null;
          
      javax.naming.directory.Attributes attrs = new
BasicAttributes(true);
      String key=null, value=null, as=null; 
      for(Enumeration e=_attribs.keys();
e.hasMoreElements();)
      {
         key=e.nextElement().toString();
         value=_attribs.get(key).toString();
         Attribute attr=new BasicAttribute(key);

         StringTokenizer st = new
StringTokenizer(value,",");
         for ( int i=0 ; st.hasMoreTokens() ; i++ )
         {
            as = st.nextToken();
            attr.add(as); 
         }
         attrs.put(attr);
      }
      return attrs;
     }

     private static void cleanAttribs()
     {
        if( null!=_attribs )
          _attribs.clear();
     } 

    private static String printAttribs()
    {
      String strout="";
      for(Enumeration e=_attribs.keys();
e.hasMoreElements();)
      {
        String key=e.nextElement().toString();
        String value=_attribs.get(key).toString();
        strout+="key="+key;
        strout+=" value=";
        strout+=value;
      }
      return strout;
    }
    private static String getString(String v, String
d)
    {
        if ( v.equals("") )
            return d;
        else
            return v;
    }

    private static boolean getBoolean(String v,
boolean d)
    {
        if ( v.equals("") )
            return d;
        else
            return Boolean.valueOf(v).booleanValue();
    }
    private static int getInt(String v, int d) throws
NumberFormatException
    {
        if ( v.equals("") )
            return d;
        else
            return Integer.parseInt(v);
    }
    private static long getLong(String v, long d) 
throws NumberFormatException
    {
        if ( v.equals("") )
            return d;
        else
            return Long.parseLong(v);
    }
    private static int getScope(String v, int d)
throws Exception
    {
        if ( v.equals("") )
            return d;
        else
        {
            if ( v.equalsIgnoreCase("sub") )
                return SearchControls.SUBTREE_SCOPE;
            else if ( v.equalsIgnoreCase("one") )
                return SearchControls.ONELEVEL_SCOPE;
            else if ( v.equalsIgnoreCase("base") )
                return SearchControls.OBJECT_SCOPE;
            throw new Exception("Invalid search
scope");
        }
    }
    private static String[] getAttrs(String v)
    {
        if ( v.equals("*") )
        {
            return null;
        }
        else
        {
            StringTokenizer st = new
StringTokenizer(v,",");
            String as [] = new String
[st.countTokens()];
            for ( int i=0 ; st.hasMoreTokens() ; i++ )
            {
                as[i] = st.nextToken();
            }
            return as;
        }
        
        
    }
    private static SearchControls setupControls(String
scope,
                                                String
deref,
                                                String
count,
                                                String
attrs,
                                                String
time)
        throws Exception
    {
        SearchControls constraints = new
SearchControls();
        constraints.setSearchScope(getScope(scope,
                                           
SearchControls.SUBTREE_SCOPE));
       
constraints.setDerefLinkFlag(getBoolean(deref,true));
        constraints.setCountLimit(getLong(count,0));
       
constraints.setReturningAttributes(getAttrs(attrs));
        constraints.setTimeLimit(getInt(time,0));
        return constraints;
    }
    private static Element
queryResults(NamingEnumeration ldapresults,
                                        String
ldap_searchbase,
                                        boolean
relativedn,
                                        Document
document,
                                        String doc_e,
                                        String ent_e,
                                        String id_a)
        throws Exception
    {
        Element doc = document.createElement(doc_e);
        while ( ldapresults.hasMore() )
        {
            Element ent =
document.createElement(ent_e);
            SearchResult si =
(SearchResult)ldapresults.next();
            String dn = si.getName();
            if ( ! relativedn )
            {
                if ( ! dn.equals("") )
                    dn += ",";
                dn += ldap_searchbase;
            }
            ent.setAttribute(id_a,dn);
            javax.naming.directory.Attributes attrs =
si.getAttributes();
            if ( attrs != null )
            {
                NamingEnumeration ae = attrs.getAll();
                while( ae.hasMoreElements() )
                {
                    Attribute attr =
(Attribute)ae.next();
                    String attrId = attr.getID();
                    Enumeration vals = attr.getAll();
                    while( vals.hasMoreElements() )
                    {
                        String val =
(String)vals.nextElement();
                        Element att =
document.createElement(attrId);
                       
att.appendChild(document.createTextNode(val));
                        ent.appendChild(att);
                    }
                }
            }
            doc.appendChild(ent);
        }
        return doc;
    }
      
    static private String getDN(String relative_dn,
HttpServletRequest req, Document document)
    {
      try
      {
        if( null == relative_dn ) relative_dn="";
        String dnPrefix=req.getParameter("dnprefix");
        if( null == dnPrefix || dnPrefix.length() &lt;
1 )
          throw new Exception("URL incorrectly used,
prefix parameter \"dnprefix\" was not passed");
        String returnDN=null;
        //allow empty relative_dn 
        if( null == relative_dn ||
relative_dn.length() &lt; 1 )
          returnDN = dnPrefix;
        else
          returnDN = relative_dn + "," + dnPrefix;

        return  returnDN;
      }
      catch (Exception e)
      {
            setupExeceptionMessage(e,document);   

            return "";
      }
   }

   static private boolean initLDAP(Document document)
   {
        try
        {
            Properties env = new Properties();
           
env.put(Context.INITIAL_CONTEXT_FACTORY,_driver);
            env.put(Context.PROVIDER_URL,_serverURL);

            boolean pempty=(_principal==null ||
(_principal.length() &lt; 1) ); 
            boolean cempty=(_credentials==null ||
(_credentials.length() &lt; 1) ); 
            if( !pempty &amp;&amp; !cempty )
            {
             
env.put(Context.SECURITY_AUTHENTICATION,"simple");
             
env.put(Context.SECURITY_PRINCIPAL,_principal);
             
env.put(Context.SECURITY_CREDENTIALS,_credentials);
            }
 
            _ldapContex = new
InitialLdapContext(env,null);

            return true;
        }
        catch (Exception e)
        {
            setupExeceptionMessage(e,document);   

            return false;
        }
   }

   static private boolean addEntry(Document document)
   {
        try
        {
            _processPosition++;

            if( null == _ldapContex ) 
              throw new Exception("ldap was not
initialized");

            javax.naming.directory.Attributes attrs =
getAttributes();
            
            _ldapContex.createSubcontext(_dn,attrs);

            return true;
        }
        catch (Exception e)
        {
            setupExeceptionMessage(e,document);   

            return false;
        }
   }

   static private boolean modifyEntry(Document
document)
   {
        try
        {
            _processPosition++;

            if( null == _ldapContex ) 
              throw new Exception("ldap was not
initialized");

            javax.naming.directory.Attributes attrs =
getAttributes();
            
           
_ldapContex.modifyAttributes(_dn,DirContext.REPLACE_ATTRIBUTE,attrs);

            return true;
        }
        catch (Exception e)
        {
            setupExeceptionMessage(e,document);   

            return false;
        }
   }


   static private boolean delEntry(Document document)
   {
        try
        {
            _processPosition++;

            if( null == _ldapContex ) 
              throw new Exception("ldap was not
initialized");

            _ldapContex.destroySubcontext(_dn);

            return true;
        }
        catch (Exception e)
        {
            setupExeceptionMessage(e,document);   

            return false;
        }
   }

   private static void
setupExeceptionMessage(Exception e, Document document)
   {
            Element err =
document.createElement(_err_element);
            Element msg =
document.createElement("message");
           
msg.appendChild(document.createTextNode("position["+_processPosition+"]
 "+e.getMessage()));
            err.appendChild(msg);

            if( _showStackTrace )
            { 
              StringWriter sw = new StringWriter();
              PrintWriter pw = new PrintWriter(sw);
              e.printStackTrace(pw);

              Element str =
document.createElement("stacktrace");
             
str.appendChild(document.createTextNode(sw.toString()));
              err.appendChild(str);
            }
            _exceptionElement=err;
   }   
 
      </xsp:logic>
      <xsl:apply-templates/>
    </xsp:page>
  </xsl:template>


  <xsl:template match="ldap:execute-query">

    <xsl:variable name="server-url">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:server-url"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="driver">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:driver"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="query">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:query"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="search-base">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:search-base"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="scope">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:scope"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="deref-link">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:deref-link"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="count-limit">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:count-limit"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="attributes">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:attributes"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="time-limit">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:time-limit"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="relative-dn">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:relative-dn"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="doc-element">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:doc-element"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="entry-element">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:entry-element"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="id-attribute">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:id-attribute"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="error-element">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:error-element"/>
      </xsl:call-template>
    </xsl:variable>

    <xsl:variable name="principal">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:principal"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="credentials">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:credentials"/>
      </xsl:call-template>
    </xsl:variable>

    <xsp:logic>
      {
        String doc_element =
          getString(<xsl:copy-of
select="$doc-element"/>,"ldapresults");
        String ent_element =
          getString(<xsl:copy-of
select="$entry-element"/>,"searchresult");
        String id_attr =
          getString(<xsl:copy-of
select="$id-attribute"/>,"ID");
       String err_element = 
          getString(<xsl:copy-of
select="$error-element"/>,"error");

        try
        {
            String query = <xsl:copy-of
select="$query"/>;
            Properties env = new Properties();
            env.put(Context.INITIAL_CONTEXT_FACTORY,
              getString(<xsl:copy-of
select="$driver"/>,
                       
"com.sun.jndi.ldap.LdapCtxFactory")
            );
            env.put(Context.PROVIDER_URL,
              getString(<xsl:copy-of
select="$server-url"/>,
                        "ldap://polya.u-strasbg.fr")
            );
            String principal = <xsl:copy-of
select="$principal"/>;
            String credentials=<xsl:copy-of
select="$credentials"/>;
            boolean pempty=(principal==null ||
(principal.length() &lt; 1) ); 
            boolean cempty=(credentials==null ||
(credentials.length() &lt; 1) ); 
            if( !pempty &amp;&amp; !cempty )
            {
             
env.put(Context.SECURITY_AUTHENTICATION,"simple");
             
env.put(Context.SECURITY_PRINCIPAL,<xsl:copy-of
select="$principal"/>);
             
env.put(Context.SECURITY_CREDENTIALS,<xsl:copy-of
select="$credentials"/>);
            }
 
            LdapContext ctx = new
InitialLdapContext(env,null);
            String ldap_searchbase = <xsl:copy-of
select="$search-base"/>;
            SearchControls constraints =
                setupControls(
                  <xsl:copy-of select="$scope"/>,
                  <xsl:copy-of select="$deref-link"/>,
                  <xsl:copy-of
select="$count-limit"/>,
                  <xsl:copy-of select="$attributes"/>,
                  <xsl:copy-of
select="$time-limit"/>);
            boolean relativedn =
              getBoolean(<xsl:copy-of
select="$relative-dn"/>,true);

            NamingEnumeration ldapresults =
               
ctx.search(ldap_searchbase,query,constraints);
            Element r = queryResults(ldapresults,
                                     ldap_searchbase,
                                     relativedn,
                                     document,
                                     doc_element,
                                     ent_element,
                                     id_attr);
           
<xsp:content><xsp:expr>r</xsp:expr></xsp:content>
        }
        catch (Exception e)
        {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            Element err =
document.createElement(err_element);
            Element msg =
document.createElement("message");
           
msg.appendChild(document.createTextNode(e.getMessage()));
            err.appendChild(msg);
            Element str =
document.createElement("stacktrace");
           
str.appendChild(document.createTextNode(sw.toString()));
            err.appendChild(str);
           
<xsp:content><xsp:expr>err</xsp:expr></xsp:content>
        }
      }
    </xsp:logic>
  </xsl:template> <!-- end of template
"ldap:execute-query" -->

  <xsl:template name="init-LDAP">

    <xsl:variable name="server-url">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:server-url"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="driver">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:driver"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="error-element">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:error-element"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="principal">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:principal"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="credentials">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:credentials"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="doc-element">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:doc-element"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="entry-element">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:entry-element"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="show-stacktrace">
      <xsl:call-template name="get-nested-string">
        <xsl:with-param name="content"
select="ldap:show-stacktrace"/>
      </xsl:call-template>
    </xsl:variable>


    <xsp:logic>
       init();

       _serverURL  = getString(<xsl:copy-of
select="$server-url"/>,"");
       _driver     = getString(<xsl:copy-of
select="$driver"/>,"com.sun.jndi.ldap.LdapCtxFactory");
       _err_element= getString(<xsl:copy-of
select="$error-element"/>,"error");
       _principal  = getString(<xsl:copy-of
select="$principal"/>,"");
       _credentials= getString(<xsl:copy-of
select="$credentials"/>,"");

       _doc_element  =getString(<xsl:copy-of
select="$doc-element"/>,"ldapresults");
       _entry_element=getString(<xsl:copy-of
select="$entry-element"/>,"operationresult");
      
_showStackTrace=getBoolean(getString(<xsl:copy-of
select="$show-stacktrace"/>,"false"),true);

       if( !initLDAP(document) )
       {
         
<xsp:content><xsp:expr>_exceptionElement</xsp:expr></xsp:content>
          return;
       } 
     </xsp:logic>

  </xsl:template>  <!-- end of template "init-LDAP"
-->


  <xsl:template match="ldap:execute-add">
    <xsl:call-template name="init-LDAP"/>
    <xsl:call-template name="dn-add-entry"/>
    <xsl:call-template name="rn-add-entry"/>
    <xsl:call-template name="cleanup"/>
  </xsl:template>

  <xsl:template match="ldap:execute-modify">
    <xsl:call-template name="init-LDAP"/>
    <xsl:call-template name="dn-modify-entry"/>
    <xsl:call-template name="rn-modify-entry"/>
    <xsl:call-template name="cleanup"/>
  </xsl:template>

  <xsl:template match="ldap:execute-delete">
    <xsl:call-template name="init-LDAP"/>
    <xsl:call-template name="dn-delete-entry"/>
    <xsl:call-template name="rn-delete-entry"/>
    <xsl:call-template name="cleanup"/>
  </xsl:template>

  <xsl:template match="@*|node()" priority="-1">
    <xsl:copy><xsl:apply-templates
select="@*|node()"/></xsl:copy>
  </xsl:template>


</xsl:stylesheet>

ldapadd.xml

<?xml version="1.0"?>
<?cocoon-process type="xsp"?>
<?cocoon-process type="xslt"?>
<?xml-stylesheet href="XMLSource.xsl"
type="text/xsl"?>

<xsp:page language="java" 
     xmlns:xsp="http://www.apache.org/1999/XSP/Core" 
     xmlns:ldap="http://www.apache.org/2000/LDAP" 
     xmlns:sql="http://www.apache.org/1999/SQL" >

  <root>

    <ldap:execute-add>

     
<ldap:server-url>ldap://pebble.dev.tms.toyota.com</ldap:server-url>

     
<ldap:principal>cn=brittonj,ou=people,ou=tms,ou=intranet,o=teds</ldap:principal>
      <ldap:credentials>nitwit</ldap:credentials>

     
<ldap:show-stacktrace>false</ldap:show-stacktrace>
      <ldap:doc-element>doc</ldap:doc-element>
      <ldap:entry-element>entry</ldap:entry-element>
      <ldap:error-element>error</ldap:error-element>



      <ldap:absolute-dn
val="cn=strawd,ou=people,ou=tms,ou=intranet,o=teds">
       
<ldap:attributes>sn=strawberry</ldap:attributes>
       
<ldap:attributes>objectClass=inetOrgPerson,organizationalPerson,person,ndsLoginProperties,top</ldap:attributes>
      </ldap:absolute-dn>

<!-- the following is an alternate way of specifying
entries,
    it allows you to use relative dn but you must pass
a query
     string parameter called dnprefix for this to
work.

      <ldap:rn val="cn=strawd">
       
<ldap:attributes>sn=strawberry</ldap:attributes>
       
<ldap:attributes>objectClass=inetOrgPerson,organizationalPerson,person,ndsLoginProperties,top</ldap:attributes>
      </ldap:rn>
-->
    </ldap:execute-add>

  </root>
</xsp:page>


__________________________________________________
Do You Yahoo!?
Yahoo! Messenger - Talk while you surf!  It's FREE.
http://im.yahoo.com/