Return-Path: Delivered-To: apmail-cocoon-cvs-archive@www.apache.org Received: (qmail 63740 invoked from network); 11 Oct 2004 09:55:51 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 11 Oct 2004 09:55:51 -0000 Received: (qmail 99850 invoked by uid 500); 11 Oct 2004 09:54:51 -0000 Delivered-To: apmail-cocoon-cvs-archive@cocoon.apache.org Received: (qmail 99766 invoked by uid 500); 11 Oct 2004 09:54:50 -0000 Mailing-List: contact cvs-help@cocoon.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@cocoon.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list cvs@cocoon.apache.org Received: (qmail 99741 invoked by uid 99); 11 Oct 2004 09:54:50 -0000 X-ASF-Spam-Status: No, hits=-10.0 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Mon, 11 Oct 2004 02:54:49 -0700 Received: (qmail 62891 invoked by uid 65534); 11 Oct 2004 09:54:48 -0000 Date: 11 Oct 2004 09:54:48 -0000 Message-ID: <20041011095448.62888.qmail@minotaur.apache.org> From: jeremy@apache.org To: cvs@cocoon.apache.org Subject: svn commit: rev 54529 - cocoon/trunk/src/blocks/naming/java/org/apache/cocoon/component X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N Author: jeremy Date: Mon Oct 11 02:54:47 2004 New Revision: 54529 Added: cocoon/trunk/src/blocks/naming/java/org/apache/cocoon/component/ cocoon/trunk/src/blocks/naming/java/org/apache/cocoon/component/EntryManager.java cocoon/trunk/src/blocks/naming/java/org/apache/cocoon/component/LDAPEntryManager.java Log: An LDAP Component designed to be used from FlowScript, that can read, create, update and find Entries Added: cocoon/trunk/src/blocks/naming/java/org/apache/cocoon/component/EntryManager.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/blocks/naming/java/org/apache/cocoon/component/EntryManager.java Mon Oct 11 02:54:47 2004 @@ -0,0 +1,32 @@ +package org.apache.cocoon.component; + +import org.apache.avalon.framework.component.*; +import javax.naming.directory.*; +import java.util.Map; +import org.apache.cocoon.ProcessingException; + + +/** + * The EntryManager is an Avalon Component for managing the Entries in a Javax Naming Directory. + * This is the interface implemented by {@link org.apache.cocoon.component.LDAPEntryManager LDAPEntryManager}. + * @author Jeremy Quinn http://apache.org/~jeremy. + */ + +public interface EntryManager extends Component { + String ROLE = EntryManager.class.getName(); + int ADD_ATTRIBUTE = DirContext.ADD_ATTRIBUTE; + int REMOVE_ATTRIBUTE = DirContext.REMOVE_ATTRIBUTE; + int REPLACE_ATTRIBUTE = DirContext.REPLACE_ATTRIBUTE; + + public void create(String entry_name, Map entity_attributes) throws ProcessingException ; + + public Map get(String entry_name) throws ProcessingException; + + public Map find(Map match_attributes) throws ProcessingException; + + public Map find(String context, Map match_attributes) throws ProcessingException; + + public void modify(String entry_name, int mod_operand, Map mod_attributes) throws ProcessingException; + +} + Added: cocoon/trunk/src/blocks/naming/java/org/apache/cocoon/component/LDAPEntryManager.java ============================================================================== --- (empty file) +++ cocoon/trunk/src/blocks/naming/java/org/apache/cocoon/component/LDAPEntryManager.java Mon Oct 11 02:54:47 2004 @@ -0,0 +1,304 @@ +package org.apache.cocoon.component; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.naming.Context; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchResult; + +import org.apache.avalon.excalibur.pool.Recyclable; +import org.apache.avalon.framework.activity.Disposable; +import org.apache.avalon.framework.logger.AbstractLogEnabled; +import org.apache.avalon.framework.parameters.ParameterException; +import org.apache.avalon.framework.parameters.Parameterizable; +import org.apache.avalon.framework.parameters.Parameters; +import org.apache.cocoon.ProcessingException; + +/** + * The LDAPEntryManager is an Avalon Component for managing Entries in a Javax Naming Directory. + * This is the LDAP implementation of the {@link org.apache.cocoon.component.EntryManager EntryManager} interface. + * This is designed to be used from FlowScript, it uses Maps instead of NamingEnumerations and Attributes. + * @author Jeremy Quinn http://apache.org/~jeremy. + * + * Example configuration (goes in cocoon.xconf) + *

+ *	<component role="org.apache.cocoon.component.EntryManager" class="org.apache.cocoon.component.LDAPEntryManager" logger="flow.ldap">
+ *	  <parameter name="ldap-host" value="hostname:port"/>
+ *	  <parameter name="ldap-base" value="dc=example,dc=com"/>
+ *	  <parameter name="ldap-user" value="username"/>
+ *	  <parameter name="ldap-pass" value="password"/>
+ *  </component>
+ *   

+ */ + +public class LDAPEntryManager + extends AbstractLogEnabled + implements EntryManager, Parameterizable, Disposable, Recyclable { + + /* congiguration parameter names */ + protected final static String LDAP_HOST_PARAM = "ldap-host"; + protected final static String LDAP_USER_PARAM = "ldap-user"; + protected final static String LDAP_PASS_PARAM = "ldap-pass"; + protected final static String LDAP_BASE_PARAM = "ldap-base"; + + /* internal state */ + private boolean disposed = false; + private boolean recycled = false; + + /* internal instance variables */ + protected DirContext context = null; + protected Hashtable environment = null; + + /* default constructor */ + public LDAPEntryManager() { + } + + /** Avalon, Parameterize this Class */ + public void parameterize(Parameters params) throws ParameterException { + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAPEntryManager parameterizing"); + } + if (this.environment == null) { + String host = params.getParameter (LDAP_HOST_PARAM); + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAP using host: " + host); + } + String base = params.getParameter (LDAP_BASE_PARAM); + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAP using base: " + base); + } + String user = params.getParameter (LDAP_USER_PARAM); + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAP using user: " + user); + } + String pass = params.getParameter (LDAP_PASS_PARAM); + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAP using pass: " + pass); + } + this.environment = new Hashtable (); + this.environment.put (Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + this.environment.put (Context.PROVIDER_URL, host + "/" + base); + if (user != null) { + this.environment.put (Context.SECURITY_AUTHENTICATION, "simple"); + this.environment.put (Context.SECURITY_PRINCIPAL, user); + this.environment.put (Context.SECURITY_CREDENTIALS, pass); + } + } + } + + /* Avalon, Recycle this Class */ + public final void recycle() { + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAPEntryManager recycling"); + } + try { + this.context.close(); + } catch ( Exception e) { + getLogger().error ("LDAPEntryManager.recycle() :" + e.getMessage()); + } finally { + this.context = null; + } + this.recycled = true; + } + + /* Avalon, Dispose of this Class */ + public final void dispose() { + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAPEntryManager disposing"); + } + try { + if (context != null) { + this.context.close(); + } + } catch ( Exception e) { + getLogger().error ("LDAPEntryManager.recycle() :" + e.getMessage()); + } finally { + this.context = null; + this.environment = null; + this.disposed = true; + } + } + + /* lazy initialise this class */ + protected void initialize() throws Exception { + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAPEntryManager initialising"); + } + if (null == this.environment) { + throw new IllegalStateException("LDAPEntryManager.initialize() : Not Configured"); + } + if (this.disposed) { + throw new IllegalStateException("LDAPEntryManager.initialize() : Already disposed"); + } + try { + this.context = new InitialDirContext (this.environment); + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAPEntryManager new context: " + this.context.getNameInNamespace ()); + } + } catch ( Exception e) { + getLogger().error ("LDAPEntryManager.initialize()" + e.getMessage()); + return; + } + } + + /** + * Creates a new Entry + * + * @param name The name of the Entry to create + * @param attributes The Map of Attributes to create it with + */ + public void create(String name, Map attributes) throws ProcessingException { + Context newContext = null; + try { + if (this.context == null) initialize (); + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAPEntryManager creating new Context: " + name); + } + newContext = context.createSubcontext (name, map2Attributes (attributes)); + } catch (Exception e) { + getLogger ().error ("LDAPEntryManager.create() :" + e.getMessage()); + throw new ProcessingException (e); + } finally { + try { + if (newContext != null) newContext.close (); + } catch (NamingException ne) { + throw new ProcessingException (ne); + } + } + } + + /** + * Retrieves a named Entry's Attributes + * + * @param name The name of the Entry to modify + * @return a Map of the Attributes + */ + public Map get(String name) throws ProcessingException { + try { + if (this.context == null) initialize (); + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAPEntryManager retrieving Entry: " + name); + } + return attributes2Map (context.getAttributes (name)); + } catch (Exception e) { + getLogger ().error ("LDAPEntryManager.get() :" + e.getMessage()); + throw new ProcessingException (e); + } + } + + /** + * Finds Entries based on matching their Attributes + * + * @param attributes The Attributes to match + * @return a Map of the results, each with a Map of their Attributes + */ + public Map find(Map attributes) throws ProcessingException { + return find("", attributes); + } + + /** + * Finds Entries based on their Attributes + * + * @param cntx The sub-context to search + * @param attributes The Attributes to match + * @return a Map of the results, each with a Map of their Attributes + */ + public Map find(String cntx, Map attributes) throws ProcessingException { + try { + if (this.context == null) initialize (); + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAPEntryManager finding Entries in: " + cntx); + } + return namingEnumeration2Map (context.search (cntx, map2Attributes (attributes))); + } catch (Exception e) { + getLogger ().error ("LDAPEntryManager.find() :" + e.getMessage()); + throw new ProcessingException (e); + } + } + + /** + * Modifies an existing Entry + * + * @param name The name of the Entry to modify + * @param mod_op The modification mode to use + * @param attributes The Map of modifications + */ + public void modify(String name, int mod_op, Map attributes) throws ProcessingException { + try { + if (this.context == null) initialize (); + if (getLogger ().isDebugEnabled ()) { + getLogger ().debug ("LDAPEntryManager modifying Entry: " + name); + } + context.modifyAttributes (name, mod_op, map2Attributes (attributes)); + } catch (Exception e) { + getLogger ().error ("LDAPEntryManager.modify() :" + e.getMessage()); + throw new ProcessingException (e); + } + } + + /* + Converts an Attributes Enumeration into a Map of those Attributes + Should be easier to manupulate in FlowScript and display in JXTemplate + Keep in mind that because there can be many entries for each Attribute + we store each value of the Map as an Array + */ + private Map attributes2Map (Attributes attributes) throws NamingException { + Map map = new HashMap (); + for (NamingEnumeration atts = attributes.getAll(); atts.hasMore();) { + Attribute attr = (Attribute)atts.next(); + String id = attr.getID(); + List val = new java.util.ArrayList (); + NamingEnumeration vals = attr.getAll(); + while (vals.hasMore ()) { + val.add (vals.next ()); + } + map.put (id, val); + } + return map; + } + + /* + Converts a Map into an Enumeration of Attributes + Should be easier to provide from FlowScript + */ + private Attributes map2Attributes (Map map) { + Attributes attrs = new BasicAttributes (false); + Iterator keys = map.keySet ().iterator (); + while (keys.hasNext ()) { + String key = (String)keys.next (); + Iterator vals = ((List)map.get (key)).iterator (); + Attribute attr = new BasicAttribute (key); + while (vals.hasNext ()) { + attr.add ((String)vals.next ()); + } + attrs.put (attr); + } + return attrs; + } + + /* + Converts a NamingEnumeration into a Map of those Entries, with Attributes + Should be easier to manupulate in FlowScript and display in JXTemplate + */ + private Map namingEnumeration2Map (NamingEnumeration enum) throws NamingException { + Map map = new HashMap (); + while (enum.hasMore ()) { + SearchResult sr = (SearchResult)enum.next (); + map.put (sr.getName (), attributes2Map(sr.getAttributes ())); + } + return map; + } +} + +