summaryrefslogtreecommitdiff
path: root/src/com/memberwebs/ldapxml/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/memberwebs/ldapxml/map')
-rw-r--r--src/com/memberwebs/ldapxml/map/LXAttribute.java78
-rw-r--r--src/com/memberwebs/ldapxml/map/LXBase.java261
-rw-r--r--src/com/memberwebs/ldapxml/map/LXClass.java116
-rw-r--r--src/com/memberwebs/ldapxml/map/LXEntry.java130
-rw-r--r--src/com/memberwebs/ldapxml/map/LXMap.java167
-rw-r--r--src/com/memberwebs/ldapxml/map/LXMapException.java56
-rw-r--r--src/com/memberwebs/ldapxml/map/LXSAXHandler.java488
7 files changed, 1296 insertions, 0 deletions
diff --git a/src/com/memberwebs/ldapxml/map/LXAttribute.java b/src/com/memberwebs/ldapxml/map/LXAttribute.java
new file mode 100644
index 0000000..8d95770
--- /dev/null
+++ b/src/com/memberwebs/ldapxml/map/LXAttribute.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2004, Nate Nielsen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * CONTRIBUTORS
+ * Nate Nielsen <nielsen@memberwebs.com>
+ *
+ */
+
+package com.memberwebs.ldapxml.map;
+
+
+
+/**
+ * Represents an &lt;attribute&gt; or &lt;element&gt; in an LX map.
+ *
+ * @author nielsen@memberwebs.com
+ * @version 0.5
+ */
+public class LXAttribute
+ extends LXBase
+{
+ /**
+ * Construct an LXAttribute object. Can only be constructed
+ * from within the package.
+ *
+ * @param parent The parent in the map tree.
+ * @param isElement Set to true if this is object represents an
+ * &lt;element&gt;, otherwise an &lt;attribute&gt;.
+ */
+ LXAttribute(LXBase parent, boolean isElement)
+ {
+ super(parent);
+ m_isElement = isElement;
+ }
+
+ /**
+ * Check whether this object represents an &lt;element&gt;
+ * or &lt;attribute&gt;.
+ *
+ * @return The state.
+ */
+ public final boolean isElement()
+ {
+ return m_isElement;
+ }
+
+ protected boolean m_isElement;
+};
diff --git a/src/com/memberwebs/ldapxml/map/LXBase.java b/src/com/memberwebs/ldapxml/map/LXBase.java
new file mode 100644
index 0000000..82b3d09
--- /dev/null
+++ b/src/com/memberwebs/ldapxml/map/LXBase.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2004, Nate Nielsen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * CONTRIBUTORS
+ * Nate Nielsen <nielsen@memberwebs.com>
+ *
+ */
+
+package com.memberwebs.ldapxml.map;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * A base class for all objects in an LX map tree.
+ *
+ * @author nielsen@memberwebs.com
+ * @version 0.5
+ */
+public class LXBase
+{
+ /**
+ * Constructs an LXBase object.
+ *
+ * @param parent The parent object in the LX map tree.
+ */
+ LXBase(LXBase parent)
+ {
+ m_name = null;
+ m_xmlName = null;
+ m_nameSpace = null;
+ m_ns = null;
+ m_parent = parent;
+ m_isUseable = true;
+
+ // If we have a parent and it doesn't have any children set
+ // Then give it child capabilities.
+ if(parent != null && parent.m_children == null)
+ parent.m_children = new Hashtable();
+ }
+
+ /**
+ * Get the full XML name for this object. This includes any namespace
+ * prefixes prepended to the name.
+ *
+ * @return The XML name.
+ */
+ public String getXmlName()
+ {
+ String xmlName = m_xmlName;
+ if(xmlName == null)
+ xmlName = m_name;
+
+ if(xmlName != null)
+ {
+ String prefix = getPrefix();
+ if(prefix != null)
+ xmlName = prefix + ":" + xmlName;
+ }
+
+ return xmlName;
+ }
+
+
+ /**
+ * Get the name of this object.
+ *
+ * @return The name.
+ */
+ public final String getName()
+ {
+ return m_name;
+ }
+
+
+ /**
+ * Set the name of this object. Updates the parent (if any)
+ * to reflect this change in tree structure.
+ *
+ * @param name The new name
+ */
+ void setName(String name)
+ {
+ if(m_name != null && m_parent != null)
+ m_parent.m_children.remove(m_name);
+
+ if(name != null)
+ {
+ if(m_parent != null)
+ m_parent.m_children.put(name, this);
+
+ m_name = name;
+ }
+ }
+
+ /**
+ * Get the namespace prefix for this object. If this object has
+ * no namespaces info set, returns the parent objects namespace
+ * prefix.
+ *
+ * @return The namespace prefix, or null if there is no prefix.
+ */
+ public String getPrefix()
+ {
+ // If we have a namespace then return
+ // the ns value regardless
+ if(m_nameSpace != null)
+ return m_ns;
+
+ if(m_ns != null)
+ return m_ns;
+
+ if(m_parent != null)
+ return m_parent.getPrefix();
+
+ return null;
+ }
+
+ /**
+ * Get the full namespace URI for this object.
+ *
+ * @param here If set to true, then parent namespaces will
+ * be returned if none is set on this object.
+ * @return The namespace.
+ */
+ public String getNamespace(boolean here)
+ {
+ if(m_nameSpace != null || here)
+ return m_nameSpace;
+
+ if(m_parent != null)
+ return m_parent.getNamespace();
+
+ return null;
+ }
+
+ /**
+ * Get the full namespace URI for this node.
+ * If this object has no namespace, it's parent will
+ * be queried.
+ *
+ * @return The namespace.
+ */
+ public String getNamespace()
+ {
+ return getNamespace(false);
+ }
+
+ /**
+ * Get this object's parent in the LX map tree.
+ *
+ * @return The parent, or null if this object has no parent.
+ */
+ public final LXBase getParent()
+ {
+ return m_parent;
+ }
+
+ /**
+ * Get a child of this object in the LX map tree.
+ *
+ * @param name The child's name.
+ * @return The child, or null if no such child is present.
+ */
+ public final LXBase getChild(String name)
+ {
+ if(m_children == null)
+ return null;
+
+ return (LXBase)m_children.get(name);
+ }
+
+ /**
+ * Get the names of all the child objects.
+ *
+ * @return An enumeraton of the child attribute names.
+ */
+ public final Enumeration getChildNames()
+ {
+ if(m_children == null)
+ return null;
+
+ return m_children.keys();
+ }
+
+ /**
+ * Check whether this object has been marked unusable.
+ *
+ * @return Usability status.
+ */
+ public final boolean isUseable()
+ {
+ return m_isUseable;
+ }
+
+ /**
+ * Get the LX hook for this object. If this
+ * object has no hook, then the parent will be queried.
+ *
+ * @return The class name of the LX hook.
+ */
+ public String getHook()
+ {
+ if(m_hook == null && m_parent != null)
+ return m_parent.getHook();
+
+ return m_hook;
+ }
+
+ // The name to be used when creating XML for this object.
+ String m_xmlName;
+
+ // Namespace information for this object
+ String m_nameSpace;
+ String m_ns;
+
+ // The hook for this object and below
+ String m_hook;
+
+ // Is this object useable or not
+ boolean m_isUseable;
+
+ // This object's parent in the LX map
+ private LXBase m_parent;
+
+ // This object's name
+ private String m_name;
+
+ // Children in the LX map tree of this object.
+ private Hashtable m_children;
+};
diff --git a/src/com/memberwebs/ldapxml/map/LXClass.java b/src/com/memberwebs/ldapxml/map/LXClass.java
new file mode 100644
index 0000000..94e0da9
--- /dev/null
+++ b/src/com/memberwebs/ldapxml/map/LXClass.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2004, Nate Nielsen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * CONTRIBUTORS
+ * Nate Nielsen <nielsen@memberwebs.com>
+ *
+ */
+
+package com.memberwebs.ldapxml.map;
+
+
+
+/**
+ * Represents a &lt;class&gt; in an LX map.
+ *
+ * @author nielsen@memberwebs.com
+ * @version 0.5
+ */
+public class LXClass
+ extends LXBase
+{
+ /**
+ * Construct a new LXClass.
+ *
+ * @param parent This class's parent object in the LX map tree.
+ */
+ LXClass(LXBase parent)
+ {
+ super(parent);
+ m_isInline = true;
+ m_isInclusive = true;
+ }
+
+ /**
+ * Returns an attribute of this class.
+ *
+ * @param name The attribute's name
+ * @return The attrtibute, or null if no such attribute is present.
+ */
+ public LXAttribute getAttribute(String name)
+ {
+ LXAttribute attr = (LXAttribute)getChild(name);
+
+ // If there is no such attribute and we're allowed
+ // to just include everything, then...
+ if(attr == null)
+ {
+ if(m_isInclusive)
+ {
+ // ... just create it on the fly.
+ attr = new LXAttribute(this, true);
+ attr.setName(name);
+ }
+ }
+
+ // Check if we haven't been marked as unusable
+ else if(!attr.isUseable())
+ {
+ attr = null;
+ }
+
+ return attr;
+ }
+
+ /**
+ * Checks if this class' attributes go inline
+ * or if the class gets it's own element in XML.
+ *
+ * @return Inline or not.
+ */
+ public final boolean isInline()
+ {
+ return m_isInline;
+ }
+
+ public final boolean isInclusive()
+ {
+ return m_isInclusive;
+ }
+
+ // Include all attributes not otherwise specified
+ boolean m_isInclusive;
+
+ // Create a class element around attributes in XML.
+ boolean m_isInline;
+};
diff --git a/src/com/memberwebs/ldapxml/map/LXEntry.java b/src/com/memberwebs/ldapxml/map/LXEntry.java
new file mode 100644
index 0000000..cf1760b
--- /dev/null
+++ b/src/com/memberwebs/ldapxml/map/LXEntry.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2004, Nate Nielsen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * CONTRIBUTORS
+ * Nate Nielsen <nielsen@memberwebs.com>
+ *
+ */
+
+package com.memberwebs.ldapxml.map;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+
+
+
+/**
+ * Represents an &lt;entry&gt object in an LX map.
+ *
+ * @author nielsen@memberwebs.com
+ * @version 0.5
+ */
+public class LXEntry
+ extends LXBase
+{
+ private Map m_xmlMap;
+ private Map m_nameMap;
+
+ /**
+ * Constructs a new LXEntry object.
+ *
+ * @param parent The parent of this entry in the LX map tree.
+ */
+ LXEntry(LXBase parent)
+ {
+ super(parent);
+ }
+
+ /**
+ * Gets a class in this entry.
+ *
+ * @param name The name of the class.
+ * @return The class, or null if no such class is present.
+ */
+ public LXClass getClass(String name)
+ {
+ LXClass cls = (LXClass)getChild(name);
+
+ if(cls != null && !cls.isUseable())
+ cls = null;
+
+ return cls;
+ }
+
+ /**
+ * Resolve an XML name to an attribute.
+ */
+ public LXAttribute resolveXMLName(String name)
+ {
+ loadNameMaps();
+ return (LXAttribute)m_xmlMap.get(name);
+ }
+
+ public LXAttribute resolveName(String name)
+ {
+ loadNameMaps();
+ return (LXAttribute)m_nameMap.get(name);
+ }
+
+ private void loadNameMaps()
+ {
+ // Note: This should never be called internally until the map
+ // is completely built. It relies on the map remaining static
+ // after this point, as there is no method for syncinc the
+ // cached map created below.
+
+ if(m_xmlMap == null || m_nameMap == null)
+ {
+ m_xmlMap = new Hashtable();
+ m_nameMap = new Hashtable();
+
+ Enumeration e = getChildNames();
+ while(e != null && e.hasMoreElements())
+ {
+ LXClass cls = getClass((String)e.nextElement());
+
+ Enumeration e2 = cls.getChildNames();
+ while(e2 != null && e2.hasMoreElements())
+ {
+ LXAttribute attr = cls.getAttribute((String)e2.nextElement());
+ if(attr != null)
+ {
+ m_xmlMap.put(attr.getXmlName(), attr);
+ m_nameMap.put(attr.getName(), attr);
+ }
+ }
+ }
+ }
+ }
+};
diff --git a/src/com/memberwebs/ldapxml/map/LXMap.java b/src/com/memberwebs/ldapxml/map/LXMap.java
new file mode 100644
index 0000000..2676f18
--- /dev/null
+++ b/src/com/memberwebs/ldapxml/map/LXMap.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2004, Nate Nielsen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * CONTRIBUTORS
+ * Nate Nielsen <nielsen@memberwebs.com>
+ *
+ */
+
+package com.memberwebs.ldapxml.map;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
+
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+
+/**
+ * The in memory representation of an LX map.
+ *
+ * @author nielsen@memberwebs.com
+ * @version 0.5
+ */
+public class LXMap
+ extends LXBase
+{
+ // Cache of the name map
+ private Map m_nameMap;
+
+ // Cache of the name set
+ private Set m_nameSet;
+
+ /**
+ * Constructs a new LXMap object.
+ */
+ LXMap(Map nameMap, Set nameSet)
+ {
+ super(null);
+ m_nameMap = nameMap;
+ m_nameSet = nameSet;
+ }
+
+
+ /**
+ * Get an entry in this LX map by name.
+ *
+ * @param name The entry name.
+ * @return The entry, or null if no such entry is present
+ */
+ public LXEntry getEntry(String name)
+ {
+ LXEntry entry = (LXEntry)getChild(name);
+
+ if(entry != null && !entry.isUseable())
+ entry = null;
+
+ return entry;
+ }
+
+ /**
+ * Get public (XML) to private (LDAP) name mappings
+ * for the first entry.
+ *
+ * @return The name map.
+ */
+ public final Map getNameMap()
+ {
+ return m_nameMap;
+ }
+
+ /**
+ * Get the minimum set of LDAP attributes required
+ * to retrieve items via this map.
+ */
+ public final Set getNameSet()
+ {
+ return m_nameSet;
+ }
+
+ /**
+ * Load an LX map from an XML data stream
+ *
+ * @param source The source of the XML data.
+ */
+ public static LXMap loadMap(InputSource source)
+ throws LXMapException, IOException
+ {
+ try
+ {
+ XMLReader xr = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
+
+ // We require some form of validation on the document
+ // as our internal checks are lax
+ xr.setFeature("http://xml.org/sax/features/validation", true);
+
+ // Parse and load the map.
+ LXSAXHandler handler = new LXSAXHandler();
+ xr.setContentHandler(handler);
+ xr.setErrorHandler(handler);
+ xr.parse(source);
+
+ LXMap map = handler.getMap();
+ return map;
+ }
+ catch(SAXException e)
+ {
+ Exception inside = e.getException();
+
+ if(inside != null)
+ {
+ inside.printStackTrace();
+ if(inside instanceof LXMapException)
+ throw (LXMapException)inside;
+ else if(inside.getMessage() != null)
+ throw new LXMapException(inside.getMessage());
+ else
+ throw new LXMapException(inside.getClass().getName());
+ }
+
+ throw new LXMapException(e.getMessage());
+ }
+ }
+
+ /**
+ * Load an LX map from a uri.
+ *
+ * @param uri The fully qualified uri of the file.
+ */
+ public static LXMap loadMap(String uri)
+ throws LXMapException, IOException
+ {
+ return loadMap(new InputSource(uri));
+ }
+}
diff --git a/src/com/memberwebs/ldapxml/map/LXMapException.java b/src/com/memberwebs/ldapxml/map/LXMapException.java
new file mode 100644
index 0000000..4dd24b4
--- /dev/null
+++ b/src/com/memberwebs/ldapxml/map/LXMapException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2004, Nate Nielsen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * CONTRIBUTORS
+ * Nate Nielsen <nielsen@memberwebs.com>
+ *
+ */
+
+package com.memberwebs.ldapxml.map;
+
+import com.memberwebs.ldapxml.LXException;
+
+/**
+ * Thrown when an error occurs parsing an LX map file.
+ *
+ * @author nielsen@memberwebs.com
+ * @version 0.5
+ */
+public class LXMapException
+ extends LXException
+{
+ public LXMapException(String message)
+ {
+ super(message);
+ }
+}
diff --git a/src/com/memberwebs/ldapxml/map/LXSAXHandler.java b/src/com/memberwebs/ldapxml/map/LXSAXHandler.java
new file mode 100644
index 0000000..d81c240
--- /dev/null
+++ b/src/com/memberwebs/ldapxml/map/LXSAXHandler.java
@@ -0,0 +1,488 @@
+/*
+ * Copyright (c) 2004, Nate Nielsen
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * CONTRIBUTORS
+ * Nate Nielsen <nielsen@memberwebs.com>
+ *
+ */
+
+package com.memberwebs.ldapxml.map;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+
+/**
+ * Parses an XML file into an in memory LX map representation.
+ *
+ * @author nielsen@memberwebs.com
+ * @version 0.5
+ */
+class LXSAXHandler
+ extends DefaultHandler
+{
+ private static final String EL_ROOT = "lxmap";
+ private static final String EL_ENTRY = "entry";
+ private static final String EL_CLASS = "class";
+ private static final String EL_ELEMENT = "element";
+ private static final String EL_ATTRIBUTE = "attribute";
+ private static final String EL_RENAME = "rename";
+ private static final String EL_IGNORE = "ignore";
+ private static final String AT_NAME = "name";
+ private static final String AT_CLASS = "class";
+ private static final String AT_MODE = "mode";
+ private static final String AT_NAMESPACE = "namespace";
+ private static final String AT_NS = "ns";
+ private static final String AT_PLACE = "place";
+ private static final String AT_HOOK = "hook";
+ private static final String AT_ROOT = "root";
+ private static final String VAL_INCLUSIVE = "inclusive";
+ private static final String VAL_EXCLUSIVE = "exclusive";
+ private static final String VAL_INLINE = "inline";
+ private static final String VAL_BLOCK = "block";
+ private static final String AT_VERSION = "version";
+ private static final String VAL_VERSION = "1.0";
+
+ private static final String INTERNAL_ERROR = "LX Map parser invalid internal state";
+
+ // The root of the map being built
+ private LXMap m_map;
+
+ // The current LX map object being acted on.
+ private LXBase m_cur;
+
+ // Stack of LX objects
+ private Stack m_elStack;
+
+ // public (XML) to private (LDAP) name mappings
+ private Hashtable m_nameMap;
+
+ // All the LDAP attributes required for this map
+ private HashSet m_nameSet;
+
+ /**
+ * Constructs a new LXSAXHandler object.
+ */
+ public LXSAXHandler()
+ {
+ m_elStack = new Stack();
+ m_nameMap = new Hashtable();
+ m_nameSet = null;
+ }
+
+ /**
+ * Called at the start of the XML document.
+ */
+ public void startDocument()
+ throws SAXException
+ {
+ m_cur = null;
+ m_map = null;
+ m_nameMap.clear();
+ m_nameSet = new HashSet();
+ }
+
+ /**
+ * Called at the end of the XML document.
+ */
+ public void endDocument()
+ throws SAXException
+ {
+ // The current LX object should be null as we're back
+ // to the root. If not then something went wrong.
+ if(m_cur != null)
+ throw new SAXException(new LXMapException(INTERNAL_ERROR));
+ }
+
+
+ /**
+ * Called when a new element is encountered in the XML file.
+ *
+ * @param uri The element namespace
+ * @param localName The plain element name.
+ * @param qName The fully quallified element name.
+ * @param attributes The element's attributes.
+ */
+ public void startElement(String uri, String localName, String qName,
+ Attributes attributes)
+ throws SAXException
+ {
+ try
+ {
+ // Push the current LX object on a stack so it can
+ // be popped as we encounter the end of elements.
+
+ // Since null doesn't work with the collection classes
+ // we use 'this' to represent it. (See endElement)
+ if(m_cur == null)
+ m_elStack.push(this);
+ else
+ m_elStack.push(m_cur);
+
+ // Now depending on what kind of LX Object we have around
+ // we hand of parsing to different functions.
+ if(m_cur == null)
+ {
+ rootHandler(uri, localName, qName, attributes);
+ }
+ else if(m_cur instanceof LXMap)
+ {
+ entryHandler(uri, localName, qName, attributes);
+ }
+ else if(m_cur instanceof LXEntry)
+ {
+ if(!classHandler(uri, localName, qName, attributes))
+ actionHandler(uri, localName, qName, attributes);
+ }
+ else if(m_cur instanceof LXClass)
+ {
+ if(!attributeHandler(uri, localName, qName, attributes))
+ actionHandler(uri, localName, qName, attributes);
+ }
+ else if(m_cur instanceof LXAttribute)
+ {
+ actionHandler(uri, localName, qName, attributes);
+ }
+ else
+ throw new LXMapException(INTERNAL_ERROR);
+
+ }
+ catch(LXMapException e)
+ {
+ throw new SAXException(e);
+ }
+ }
+
+ /**
+ * Called when the end of an element is encountered.
+ *
+ * @param uri The namespace of this element.
+ * @param localName The plain name of this element.
+ * @param qName The fully qualified name of this element.
+ */
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException
+ {
+ // Add the current element to the naming stack
+ if(m_cur instanceof LXAttribute)
+ addName(m_cur);
+
+ // Pop the current LX object off the stack
+ Object obj = m_elStack.pop();
+ if(obj == null)
+ throw new SAXException(new LXMapException(INTERNAL_ERROR));
+
+ // If it's set to 'this' then it's actually
+ // 'null' (See startElement)
+ if(obj == this)
+ m_cur = null;
+ else
+ m_cur = (LXBase)obj;
+ }
+
+ /**
+ * Handles elements at the root document level.
+ *
+ * @param uri The element namespace
+ * @param localname The plain element name.
+ * @param qName The fully quallified element name.
+ * @param attributes The element's attributes.
+ * @return Returns true if element was processed.
+ */
+ private boolean rootHandler(String uri, String localName, String qName,
+ Attributes attributes)
+ throws LXMapException
+ {
+ if(qName.equals(EL_ROOT))
+ {
+ if(!attributes.getValue(AT_VERSION).equals(VAL_VERSION))
+ throw new LXMapException("Invalid LX Map version");
+
+ m_map = new LXMap(m_nameMap, m_nameSet);
+ m_cur = m_map;
+
+ nameAttrHandler(attributes, AT_ROOT);
+ commonAttrHandler(attributes);
+
+
+ // Put some exceptions into the name map
+ m_nameMap.put("class", "objectClass");
+
+ String prefix = m_cur.getPrefix();
+ if(prefix != null)
+ m_nameMap.put(prefix + ":class", "objectClass");
+
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Handles entry elements at the map root level.
+ *
+ * @param uri The element namespace
+ * @param localname The plain element name.
+ * @param qName The fully quallified element name.
+ * @param attributes The element's attributes.
+ * @return Returns true if element was processed.
+ */
+ private boolean entryHandler(String uri, String localName, String qName,
+ Attributes attributes)
+ throws LXMapException
+ {
+ if(qName.equals(EL_ENTRY))
+ {
+ LXEntry entry = new LXEntry(m_cur);
+ m_cur = entry;
+ nameAttrHandler(attributes, AT_CLASS);
+ commonAttrHandler(attributes);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Handles class elements at the map entry level.
+ *
+ * @param uri The element namespace
+ * @param localname The plain element name.
+ * @param qName The fully quallified element name.
+ * @param attributes The element's attributes.
+ * @return Returns true if element was processed.
+ */
+ private boolean classHandler(String uri, String localName, String qName,
+ Attributes attributes)
+ throws LXMapException
+ {
+ if(qName.equals(EL_CLASS))
+ {
+ LXClass cls = new LXClass(m_cur);
+ m_cur = cls;
+ nameAttrHandler(attributes, null);
+ commonAttrHandler(attributes);
+ classAttrHandler(attributes);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Handles attribute elements at the map class level.
+ *
+ * @param uri The element namespace
+ * @param localname The plain element name.
+ * @param qName The fully quallified element name.
+ * @param attributes The element's attributes.
+ * @return Returns true if element was processed.
+ */
+ private boolean attributeHandler(String uri, String localName, String qName,
+ Attributes attributes)
+ throws LXMapException
+ {
+ if(qName.equals(EL_ATTRIBUTE))
+ {
+ LXAttribute attr = new LXAttribute(m_cur, false);
+ m_cur = attr;
+ nameAttrHandler(attributes, null);
+ return true;
+ }
+ else if(qName.equals(EL_ELEMENT))
+ {
+ LXAttribute attr = new LXAttribute(m_cur, true);
+ m_cur = attr;
+ nameAttrHandler(attributes, null);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Handles action elements at various levels.
+ *
+ * @param uri The element namespace
+ * @param localname The plain element name.
+ * @param qName The fully quallified element name.
+ * @param attributes The element's attributes.
+ * @return Returns true if element was processed.
+ */
+ private boolean actionHandler(String uri, String localName, String qName,
+ Attributes attributes)
+ throws LXMapException
+ {
+ if(qName.equals(EL_IGNORE))
+ {
+ m_cur.m_isUseable = false;
+ return true;
+ }
+ else if(qName.equals(EL_RENAME))
+ {
+ m_cur.m_xmlName = attributes.getValue(AT_NAME);
+
+ if(m_cur.m_xmlName == null)
+ throw new LXMapException("LX map element requires a '" + AT_NAME + "' attribute");
+ }
+
+ return false;
+ }
+
+ /**
+ * Handles an element's name.
+ *
+ * @param attributes The element's attributes.
+ */
+ private void nameAttrHandler(Attributes attributes, String attr)
+ throws LXMapException
+ {
+ if(attr == null)
+ attr = AT_NAME;
+
+ m_cur.setName(attributes.getValue(attr));
+
+ if(m_cur.getName() == null)
+ throw new LXMapException("LX map element requires a '" + attr + "' attribute");
+ }
+
+ /**
+ * Handles an element's namespace and other basic info.
+ *
+ * @param attributes The element's attributes.
+ */
+ private void commonAttrHandler(Attributes attributes)
+ throws LXMapException
+ {
+ m_cur.m_nameSpace = attributes.getValue(AT_NAMESPACE);
+ m_cur.m_ns = attributes.getValue(AT_NS);
+ m_cur.m_hook = attributes.getValue(AT_HOOK);
+ }
+
+ /**
+ * Handles various attributes for class elements.
+ *
+ * @param attributes The element's attributes.
+ */
+ private void classAttrHandler(Attributes attributes)
+ throws LXMapException
+ {
+ if(!(m_cur instanceof LXClass))
+ throw new LXMapException(INTERNAL_ERROR);
+
+ LXClass cls = (LXClass)m_cur;
+
+ String inc = attributes.getValue(AT_MODE);
+ if(inc == null || inc.equals(VAL_EXCLUSIVE))
+ {
+ cls.m_isInclusive = false;
+ }
+ else if(inc.equals(VAL_INCLUSIVE))
+ {
+ // We don't know the list of names
+ m_nameSet = null;
+ cls.m_isInclusive = true;
+ }
+ else
+ throw new LXMapException("LX map invalid value for '" + AT_MODE + "' attribute");
+
+ String place = attributes.getValue(AT_PLACE);
+ if(place != null)
+ {
+ if(place.equals(VAL_INLINE))
+ cls.m_isInline = true;
+ else if(place.equals(VAL_BLOCK))
+ cls.m_isInline = false;
+ else
+ throw new LXMapException("LX map invalid value for '" + AT_PLACE + "' attribute");
+ }
+ }
+
+ /**
+ * Get the resulting LX Map.
+ *
+ * @return The map.
+ */
+ public final LXMap getMap()
+ {
+ return m_map;
+ }
+
+ /**
+ * Get public (XML) to private (LDAP) name mappings
+ * for the first entry.
+ *
+ * @return The name map.
+ */
+ public final Map getNameMap()
+ {
+ return m_nameMap;
+ }
+
+ /**
+ * Gets a listing of the minimum set of attributes required
+ * to satisfy this map, or null when not known
+ */
+ public final Set getNameSet()
+ {
+ return m_nameSet;
+ }
+
+ /**
+ * Add an LX object to the name map. This adds both
+ * the prefixed name as well as the local name.
+ *
+ * @param base The LX object whose name to add.
+ */
+ private void addName(LXBase base)
+ {
+ String name = base.getName();
+ if(base.m_xmlName != null && !m_nameMap.contains(base.m_xmlName))
+ m_nameMap.put(base.m_xmlName, name);
+
+ String xmlName = base.getXmlName();
+ if(xmlName != null && !m_nameMap.contains(xmlName))
+ m_nameMap.put(xmlName, name);
+
+ if(m_nameSet != null)
+ m_nameSet.add(name);
+ }
+}