liblaf-plugin-java-1.0/0000755000175000017500000000000011114062202013107 5ustar godgodliblaf-plugin-java-1.0/build5.0.xml0000644000175000017500000001260011037262756015176 0ustar godgod liblaf-plugin-java-1.0/src/0000755000175000017500000000000010570367264013723 5ustar godgodliblaf-plugin-java-1.0/src/META-INF/0000755000175000017500000000000011037262462015054 5ustar godgodliblaf-plugin-java-1.0/src/META-INF/MANIFEST.MF0000644000175000017500000000010111063275212016472 0ustar godgodManifest-Version: 1.0 Laf-Plugin-Version: 1.0final Vile Weed liblaf-plugin-java-1.0/src/org/0000755000175000017500000000000010570367264014512 5ustar godgodliblaf-plugin-java-1.0/src/org/jvnet/0000755000175000017500000000000010570367264015640 5ustar godgodliblaf-plugin-java-1.0/src/org/jvnet/lafplugin/0000755000175000017500000000000011037262462017612 5ustar godgodliblaf-plugin-java-1.0/src/org/jvnet/lafplugin/ComponentPluginManager.java0000644000175000017500000001135710736450332025100 0ustar godgod/* * Copyright (c) 2005-2008 Laf-Plugin Kirill Grouchnikov and contributors. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * o 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. * * o Neither the name of Flamingo Kirill Grouchnikov nor the names of * its contributors may 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. */ package org.jvnet.lafplugin; import java.util.Iterator; import java.util.Set; import javax.swing.UIDefaults; /** * Plugin manager for look-and-feels. * * @author Kirill Grouchnikov * @author Erik Vickroy * @author Robert Beeger * @author Frederic Lavigne * @author Pattrick Gotthardt */ public class ComponentPluginManager extends PluginManager { /** * Simple constructor. * * @param xmlName * The name of XML file that contains plugin configuration. * @param mainTag * The main tag in the XML configuration file. * @param pluginTag * The tag that corresponds to a single plugin kind. Specifies * the plugin kind that will be located in * {@link #getAvailablePlugins(boolean)}. */ public ComponentPluginManager(String xmlName) { super(xmlName, LafComponentPlugin.TAG_MAIN, LafComponentPlugin.COMPONENT_TAG_PLUGIN_CLASS); } /** * Helper function to initialize all available component plugins of * this plugin manager. Calls the * {@link LafComponentPlugin#initialize()} of all available component * plugins. */ public void initializeAll() { Set availablePlugins = this.getAvailablePlugins(); for (Iterator iterator = availablePlugins.iterator(); iterator .hasNext();) { Object pluginObject = iterator.next(); if (pluginObject instanceof LafComponentPlugin) ((LafComponentPlugin) pluginObject).initialize(); } } /** * Helper function to uninitialize all available component plugins of * this plugin manager. Calls the * {@link LafComponentPlugin#uninitialize()} of all available component * plugins. */ public void uninitializeAll() { Set availablePlugins = this.getAvailablePlugins(); for (Iterator iterator = availablePlugins.iterator(); iterator .hasNext();) { Object pluginObject = iterator.next(); if (pluginObject instanceof LafComponentPlugin) ((LafComponentPlugin) pluginObject).uninitialize(); } } /** * Helper function to process the (possibly) theme-dependent default * settings of all available component plugins of this plugin * manager. Calls the {@link LafComponentPlugin#getDefaults(Object)} of all * available plugins and puts the respective results in the specified table. * * @param table * The table that will be updated with the (possibly) * theme-dependent default settings of all available component * plugins. * @param themeInfo * LAF-specific information on the current theme. */ public void processAllDefaultsEntries(UIDefaults table, Object themeInfo) { Set availablePlugins = this.getAvailablePlugins(); for (Iterator iterator = availablePlugins.iterator(); iterator .hasNext();) { Object pluginObject = iterator.next(); if (pluginObject instanceof LafComponentPlugin) { Object[] defaults = ((LafComponentPlugin) pluginObject) .getDefaults(themeInfo); if (defaults != null) { table.putDefaults(defaults); } } } } } liblaf-plugin-java-1.0/src/org/jvnet/lafplugin/XMLParseException.java0000644000175000017500000000772610401563642024001 0ustar godgod/* XMLParseException.java * * $Revision: 1.2 $ * $Date: 2006/03/02 16:40:02 $ * $Name: $ * * This file is part of NanoXML 2 Lite. * Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved. * * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from the * use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software in * a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. *****************************************************************************/ package org.jvnet.lafplugin; /** * An XMLParseException is thrown when an error occures while parsing an XML * string. *

* $Revision: 1.2 $
* $Date: 2006/03/02 16:40:02 $

* * @see nanoxml.XMLElement * * @author Marc De Scheemaecker * @version $Name: $, $Revision: 1.2 $ */ public class XMLParseException extends RuntimeException { /** * Indicates that no line number has been associated with this exception. */ public static final int NO_LINE = -1; /** * The line number in the source code where the error occurred, or * NO_LINE if the line number is unknown. * *

Invariants:
*
*/ private int lineNr; /** * Creates an exception. * * @param name The name of the element where the error is located. * @param message A message describing what went wrong. * *
Preconditions:
*
* *
Postconditions:
*
*/ public XMLParseException(String name, String message) { super("XML Parse Exception during parsing of " + ((name == null) ? "the XML definition" : ("a " + name + " element")) + ": " + message); this.lineNr = XMLParseException.NO_LINE; } /** * Creates an exception. * * @param name The name of the element where the error is located. * @param lineNr The number of the line in the input. * @param message A message describing what went wrong. * *
Preconditions:
*
* *
Postconditions:
*
*/ public XMLParseException(String name, int lineNr, String message) { super("XML Parse Exception during parsing of " + ((name == null) ? "the XML definition" : ("a " + name + " element")) + " at line " + lineNr + ": " + message); this.lineNr = lineNr; } /** * Where the error occurred, or NO_LINE if the line number is * unknown. * * @see nanoxml.XMLParseException#NO_LINE */ public int getLineNr() { return this.lineNr; } } liblaf-plugin-java-1.0/src/org/jvnet/lafplugin/LafComponentPlugin.java0000644000175000017500000000571310736450334024231 0ustar godgod/* * Copyright (c) 2005-2008 Laf-Plugin Kirill Grouchnikov and contributors. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * o 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. * * o Neither the name of Flamingo Kirill Grouchnikov nor the names of * its contributors may 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. */ package org.jvnet.lafplugin; import javax.swing.plaf.metal.MetalTheme; /** * Basic interface for look-and-feel plugins. * * @author Kirill Grouchnikov * @author Erik Vickroy * @author Robert Beeger * @author Frederic Lavigne * @author Pattrick Gotthardt */ public interface LafComponentPlugin extends LafPlugin { /** * XML tag for look-and-feel plugins that specify component UI delegates. */ public static final String COMPONENT_TAG_PLUGIN_CLASS = "component-plugin-class"; /** * Initializes this plugin. */ public void initialize(); /** * Unitializes this plugin. */ public void uninitialize(); /** * Retrieves a collection of custom settings based on the specified theme. * The entries in the array should be pairwise, odd being symbolic name of a * setting, and even being the setting value. * * @param themeInfo * Theme information object. Can be {@link MetalTheme}, for * instance or any other LAF-specific object. * @return Collection of custom settings based on the specified theme. The * entries in the array should be pairwise, odd being symbolic name * of a setting, and even being the setting value. */ public Object[] getDefaults(Object themeInfo); } liblaf-plugin-java-1.0/src/org/jvnet/lafplugin/LafPlugin.license0000644000175000017500000000304310357100440023026 0ustar godgodCopyright (c) 2005, Kirill Grouchnikov and Erik Vickroy 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. * Neither the name of the Kirill Grouchnikov and Erik Vickroy nor the names of its contributors may 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.liblaf-plugin-java-1.0/src/org/jvnet/lafplugin/PluginManager.java0000644000175000017500000001625211037130436023207 0ustar godgod/* * Copyright (c) 2005-2008 Laf-Plugin Kirill Grouchnikov and contributors. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * o 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. * * o Neither the name of Flamingo Kirill Grouchnikov nor the names of * its contributors may 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. */ package org.jvnet.lafplugin; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.*; import javax.swing.UIManager; /** * Plugin manager for look-and-feels. * * @author Kirill Grouchnikov * @author Erik Vickroy * @author Robert Beeger * @author Frederic Lavigne * @author Pattrick Gotthardt */ public class PluginManager { private String mainTag; private String pluginTag; private String xmlName; private Set plugins; /** * Simple constructor. * * @param xmlName * The name of XML file that contains plugin configuration. * @param mainTag * The main tag in the XML configuration file. * @param pluginTag * The tag that corresponds to a single plugin kind. Specifies * the plugin kind that will be located in * {@link #getAvailablePlugins(boolean)}. */ public PluginManager(String xmlName, String mainTag, String pluginTag) { this.xmlName = xmlName; this.mainTag = mainTag; this.pluginTag = pluginTag; this.plugins = null; } // protected String getPluginClass(URL pluginUrl) { // InputStream is = null; // try { // DocumentBuilder builder = DocumentBuilderFactory.newInstance() // .newDocumentBuilder(); // is = pluginUrl.openStream(); // Document doc = builder.parse(is); // Node root = doc.getFirstChild(); // if (!this.mainTag.equals(root.getNodeName())) // return null; // NodeList children = root.getChildNodes(); // for (int i = 0; i < children.getLength(); i++) { // Node child = children.item(i); // if (!this.pluginTag.equals(child.getNodeName())) // continue; // if (child.getChildNodes().getLength() != 1) // return null; // Node text = child.getFirstChild(); // if (text.getNodeType() != Node.TEXT_NODE) // return null; // return text.getNodeValue(); // } // return null; // } catch (Exception exc) { // return null; // } finally { // if (is != null) { // try { // is.close(); // } catch (Exception e) { // } // } // } // } // protected String getPluginClass(URL pluginUrl) { InputStream is = null; InputStreamReader isr = null; try { XMLElement xml = new XMLElement(); is = pluginUrl.openStream(); isr = new InputStreamReader(is); xml.parseFromReader(isr); if (!this.mainTag.equals(xml.getName())) return null; Enumeration children = xml.enumerateChildren(); while (children.hasMoreElements()) { XMLElement child = (XMLElement) children.nextElement(); if (!this.pluginTag.equals(child.getName())) continue; if (child.countChildren() != 0) return null; return child.getContent(); } return null; } catch (Exception exc) { return null; } finally { if (isr != null) { try { isr.close(); } catch (Exception e) { } } if (is != null) { try { is.close(); } catch (Exception e) { } } } } protected Object getPlugin(URL pluginUrl) throws Exception { String pluginClassName = this.getPluginClass(pluginUrl); if (pluginClassName == null) return null; ClassLoader classLoader = (ClassLoader) UIManager.get("ClassLoader"); if (classLoader == null) classLoader = Thread.currentThread().getContextClassLoader(); Class pluginClass = Class.forName(pluginClassName, true, classLoader); if (pluginClass == null) return null; Object pluginInstance = pluginClass.newInstance(); if (pluginInstance == null) return null; return pluginInstance; } /** * Returns a collection of all available plugins. * * @return Collection of all available plugins. The classpath is scanned * only once. * @see #getAvailablePlugins(boolean) */ public Set getAvailablePlugins() { return this.getAvailablePlugins(false); } /** * Returns a collection of all available plugins. The parameter specifies * whether the classpath should be rescanned or whether to return the * already found plugins (after first-time scan). * * @param toReload * If true, the classpath is scanned for available * plugins every time this function is called. If * false, the classpath scan is performed only once. * The consecutive calls return the cached result. * @return Collection of all available plugins. */ public Set getAvailablePlugins(boolean toReload) { if (!toReload && (this.plugins != null)) return this.plugins; this.plugins = new HashSet(); // the following is fix by Dag Joar and Christian Schlichtherle // for application running with -Xbootclasspath VM flag. In this case, // the using MyClass.class.getClassLoader() would return null, // but the context class loader will function properly // that classes will be properly loaded regardless of whether the lib is // added to the system class path, the extension class path and // regardless of the class loader architecture set up by some // frameworks. ClassLoader cl = (ClassLoader) UIManager.get("ClassLoader"); if (cl == null) cl = Thread.currentThread().getContextClassLoader(); try { Enumeration urls = cl.getResources(this.xmlName); while (urls.hasMoreElements()) { URL pluginUrl = (URL) urls.nextElement(); Object pluginInstance = this.getPlugin(pluginUrl); if (pluginInstance != null) this.plugins.add(pluginInstance); } } catch (Exception exc) { return null; } return plugins; } } liblaf-plugin-java-1.0/src/org/jvnet/lafplugin/XMLElement.java0000644000175000017500000030414710572341014022432 0ustar godgod/* XMLElement.java * * $Revision: 1.3 $ * $Date: 2007/03/03 22:44:09 $ * $Name: $ * * This file is part of NanoXML 2 Lite. * Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved. * * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from the * use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software in * a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. *****************************************************************************/ package org.jvnet.lafplugin; import java.io.ByteArrayOutputStream; import java.io.CharArrayReader; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringReader; import java.io.Writer; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; /** * XMLElement is a representation of an XML object. The object is able to parse * XML code. *

*
Parsing XML Data
*
* You can parse XML data using the following code: *
    * XMLElement xml = new XMLElement();
    * FileReader reader = new FileReader("filename.xml");
    * xml.parseFromReader(reader); *
*
Retrieving Attributes
*
* You can enumerate the attributes of an element using the method * {@link #enumerateAttributeNames() enumerateAttributeNames}. * The attribute values can be retrieved using the method * {@link #getStringAttribute(java.lang.String) getStringAttribute}. * The following example shows how to list the attributes of an element: *
    * XMLElement element = ...;
    * Enumeration enum = element.getAttributeNames();
    * while (enum.hasMoreElements()) {
    *     String key = (String) enum.nextElement();
    *     String value = element.getStringAttribute(key);
    *     System.out.println(key + " = " + value);
    * } *
*
Retrieving Child Elements
*
* You can enumerate the children of an element using * {@link #enumerateChildren() enumerateChildren}. * The number of child elements can be retrieved using * {@link #countChildren() countChildren}. *
*
Elements Containing Character Data
*
* If an elements contains character data, like in the following example: *
    * <title>The Title</title> *
* you can retrieve that data using the method * {@link #getContent() getContent}. *
*
Subclassing XMLElement
*
* When subclassing XMLElement, you need to override the method * {@link #createAnotherElement() createAnotherElement} * which has to return a new copy of the receiver. *
*

* * @see nanoxml.XMLParseException * * @author Marc De Scheemaecker * <cyberelf@mac.com> * @version $Name: $, $Revision: 1.3 $ */ public class XMLElement { /** * Serialization serial version ID. */ static final long serialVersionUID = 6685035139346394777L; /** * Major version of NanoXML. Classes with the same major and minor * version are binary compatible. Classes with the same major version * are source compatible. If the major version is different, you may * need to modify the client source code. * * @see nanoxml.XMLElement#NANOXML_MINOR_VERSION */ public static final int NANOXML_MAJOR_VERSION = 2; /** * Minor version of NanoXML. Classes with the same major and minor * version are binary compatible. Classes with the same major version * are source compatible. If the major version is different, you may * need to modify the client source code. * * @see nanoxml.XMLElement#NANOXML_MAJOR_VERSION */ public static final int NANOXML_MINOR_VERSION = 2; /** * The attributes given to the element. * *

Invariants:
*
  • The field can be empty. *
  • The field is never null. *
  • The keys and the values are strings. *
*/ private Hashtable attributes; /** * Child elements of the element. * *
Invariants:
*
  • The field can be empty. *
  • The field is never null. *
  • The elements are instances of XMLElement * or a subclass of XMLElement. *
*/ private Vector children; /** * The name of the element. * *
Invariants:
*
  • The field is null iff the element is not * initialized by either parse or setName. *
  • If the field is not null, it's not empty. *
  • If the field is not null, it contains a valid * XML identifier. *
*/ private String name; /** * The #PCDATA content of the object. * *
Invariants:
*
  • The field is null iff the element is not a * #PCDATA element. *
  • The field can be any string, including the empty string. *
*/ private String contents; /** * Conversion table for &...; entities. The keys are the entity names * without the & and ; delimiters. * *
Invariants:
*
  • The field is never null. *
  • The field always contains the following associations: * "lt" => "<", "gt" => ">", * "quot" => "\"", "apos" => "'", * "amp" => "&" *
  • The keys are strings *
  • The values are char arrays *
*/ private Hashtable entities; /** * The line number where the element starts. * *
Invariants:
*
  • lineNr >= 0 *
*/ private int lineNr; /** * true if the case of the element and attribute names * are case insensitive. */ private boolean ignoreCase; /** * true if the leading and trailing whitespace of #PCDATA * sections have to be ignored. */ private boolean ignoreWhitespace; /** * Character read too much. * This character provides push-back functionality to the input reader * without having to use a PushbackReader. * If there is no such character, this field is '\0'. */ private char charReadTooMuch; /** * The reader provided by the caller of the parse method. * *
Invariants:
*
  • The field is not null while the parse method * is running. *
*/ private Reader reader; /** * The current line number in the source content. * *
Invariants:
*
  • parserLineNr > 0 while the parse method is running. *
*/ private int parserLineNr; /** * Creates and initializes a new XML element. * Calling the construction is equivalent to: * * *
Postconditions:
*
  • countChildren() => 0 *
  • enumerateChildren() => empty enumeration *
  • enumeratePropertyNames() => empty enumeration *
  • getChildren() => empty vector *
  • getContent() => "" *
  • getLineNr() => 0 *
  • getName() => null *
* * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable) * XMLElement(Hashtable) * @see nanoxml.XMLElement#XMLElement(boolean) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean) * XMLElement(Hashtable, boolean) */ public XMLElement() { this(new Hashtable(), false, true, true); } /** * Creates and initializes a new XML element. * Calling the construction is equivalent to: * * * @param entities * The entity conversion table. * *
Preconditions:
*
* *
Postconditions:
*
* * @see nanoxml.XMLElement#XMLElement() * @see nanoxml.XMLElement#XMLElement(boolean) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean) * XMLElement(Hashtable, boolean) */ public XMLElement(Hashtable entities) { this(entities, false, true, true); } /** * Creates and initializes a new XML element. * Calling the construction is equivalent to: * * * @param skipLeadingWhitespace * true if leading and trailing whitespace in PCDATA * content has to be removed. * *
Postconditions:
*
* * @see nanoxml.XMLElement#XMLElement() * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable) * XMLElement(Hashtable) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean) * XMLElement(Hashtable, boolean) */ public XMLElement(boolean skipLeadingWhitespace) { this(new Hashtable(), skipLeadingWhitespace, true, true); } /** * Creates and initializes a new XML element. * Calling the construction is equivalent to: * * * @param entities * The entity conversion table. * @param skipLeadingWhitespace * true if leading and trailing whitespace in PCDATA * content has to be removed. * *
Preconditions:
*
* *
Postconditions:
*
* * @see nanoxml.XMLElement#XMLElement() * @see nanoxml.XMLElement#XMLElement(boolean) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable) * XMLElement(Hashtable) */ public XMLElement(Hashtable entities, boolean skipLeadingWhitespace) { this(entities, skipLeadingWhitespace, true, true); } /** * Creates and initializes a new XML element. * * @param entities * The entity conversion table. * @param skipLeadingWhitespace * true if leading and trailing whitespace in PCDATA * content has to be removed. * @param ignoreCase * true if the case of element and attribute names have * to be ignored. * *
Preconditions:
*
* *
Postconditions:
*
* * @see nanoxml.XMLElement#XMLElement() * @see nanoxml.XMLElement#XMLElement(boolean) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable) * XMLElement(Hashtable) * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean) * XMLElement(Hashtable, boolean) */ public XMLElement(Hashtable entities, boolean skipLeadingWhitespace, boolean ignoreCase) { this(entities, skipLeadingWhitespace, true, ignoreCase); } /** * Creates and initializes a new XML element. *

* This constructor should only be called from * {@link #createAnotherElement() createAnotherElement} * to create child elements. * * @param entities * The entity conversion table. * @param skipLeadingWhitespace * true if leading and trailing whitespace in PCDATA * content has to be removed. * @param fillBasicConversionTable * true if the basic entities need to be added to * the entity list. * @param ignoreCase * true if the case of element and attribute names have * to be ignored. * *

Preconditions:
*
* *
Postconditions:
*
* * @see nanoxml.XMLElement#createAnotherElement() */ protected XMLElement(Hashtable entities, boolean skipLeadingWhitespace, boolean fillBasicConversionTable, boolean ignoreCase) { this.ignoreWhitespace = skipLeadingWhitespace; this.ignoreCase = ignoreCase; this.name = null; this.contents = ""; this.attributes = new Hashtable(); this.children = new Vector(); this.entities = entities; this.lineNr = 0; Enumeration enumeration = this.entities.keys(); while (enumeration.hasMoreElements()) { Object key = enumeration.nextElement(); Object value = this.entities.get(key); if (value instanceof String) { value = ((String) value).toCharArray(); this.entities.put(key, value); } } if (fillBasicConversionTable) { this.entities.put("amp", new char[] { '&' }); this.entities.put("quot", new char[] { '"' }); this.entities.put("apos", new char[] { '\'' }); this.entities.put("lt", new char[] { '<' }); this.entities.put("gt", new char[] { '>' }); } } /** * Adds a child element. * * @param child * The child element to add. * *
Preconditions:
*
* *
Postconditions:
*
* * @see nanoxml.XMLElement#countChildren() * @see nanoxml.XMLElement#enumerateChildren() * @see nanoxml.XMLElement#getChildren() * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement) * removeChild(XMLElement) */ public void addChild(XMLElement child) { this.children.addElement(child); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * *
Preconditions:
*
* *
Postconditions:
*
* * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getAttribute(java.lang.String) * getAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object) * getAttribute(String, Object) * @see nanoxml.XMLElement#getAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String) * getStringAttribute(String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.lang.String) * getStringAttribute(String, String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getStringAttribute(String, Hashtable, String, boolean) */ public void setAttribute(String name, Object value) { if (this.ignoreCase) { name = name.toUpperCase(); } this.attributes.put(name, value.toString()); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * * @deprecated Use {@link #setAttribute(java.lang.String, java.lang.Object) * setAttribute} instead. */ public void addProperty(String name, Object value) { this.setAttribute(name, value); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * *
Preconditions:
*
* *
Postconditions:
*
* * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getIntAttribute(java.lang.String) * getIntAttribute(String) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int) * getIntAttribute(String, int) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getIntAttribute(String, Hashtable, String, boolean) */ public void setIntAttribute(String name, int value) { if (this.ignoreCase) { name = name.toUpperCase(); } this.attributes.put(name, Integer.toString(value)); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * * @deprecated Use {@link #setIntAttribute(java.lang.String, int) * setIntAttribute} instead. */ public void addProperty(String key, int value) { this.setIntAttribute(key, value); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * *
Preconditions:
*
* *
Postconditions:
*
* * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String) * getDoubleAttribute(String) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double) * getDoubleAttribute(String, double) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getDoubleAttribute(String, Hashtable, String, boolean) */ public void setDoubleAttribute(String name, double value) { if (this.ignoreCase) { name = name.toUpperCase(); } this.attributes.put(name, Double.toString(value)); } /** * Adds or modifies an attribute. * * @param name * The name of the attribute. * @param value * The value of the attribute. * * @deprecated Use {@link #setDoubleAttribute(java.lang.String, double) * setDoubleAttribute} instead. */ public void addProperty(String name, double value) { this.setDoubleAttribute(name, value); } /** * Returns the number of child elements of the element. * *
Postconditions:
*
  • result >= 0 *
* * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement) * addChild(XMLElement) * @see nanoxml.XMLElement#enumerateChildren() * @see nanoxml.XMLElement#getChildren() * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement) * removeChild(XMLElement) */ public int countChildren() { return this.children.size(); } /** * Enumerates the attribute names. * *
Postconditions:
*
  • result != null *
* * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String) * getAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object) * getAttribute(String, String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String) * getStringAttribute(String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.lang.String) * getStringAttribute(String, String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getStringAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String) * getIntAttribute(String) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int) * getIntAttribute(String, int) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getIntAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String) * getDoubleAttribute(String) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double) * getDoubleAttribute(String, double) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getDoubleAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getBooleanAttribute(java.lang.String, * java.lang.String, * java.lang.String, boolean) * getBooleanAttribute(String, String, String, boolean) */ public Enumeration enumerateAttributeNames() { return this.attributes.keys(); } /** * Enumerates the attribute names. * * @deprecated Use {@link #enumerateAttributeNames() * enumerateAttributeNames} instead. */ public Enumeration enumeratePropertyNames() { return this.enumerateAttributeNames(); } /** * Enumerates the child elements. * *
Postconditions:
*
  • result != null *
* * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement) * addChild(XMLElement) * @see nanoxml.XMLElement#countChildren() * @see nanoxml.XMLElement#getChildren() * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement) * removeChild(XMLElement) */ public Enumeration enumerateChildren() { return this.children.elements(); } /** * Returns the child elements as a Vector. It is safe to modify this * Vector. * *
Postconditions:
*
  • result != null *
* * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement) * addChild(XMLElement) * @see nanoxml.XMLElement#countChildren() * @see nanoxml.XMLElement#enumerateChildren() * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement) * removeChild(XMLElement) */ public Vector getChildren() { try { return (Vector) this.children.clone(); } catch (Exception e) { // this never happens, however, some Java compilers are so // braindead that they require this exception clause return null; } } /** * Returns the PCDATA content of the object. If there is no such content, * null is returned. * * @deprecated Use {@link #getContent() getContent} instead. */ public String getContents() { return this.getContent(); } /** * Returns the PCDATA content of the object. If there is no such content, * null is returned. * * @see nanoxml.XMLElement#setContent(java.lang.String) * setContent(String) */ public String getContent() { return this.contents; } /** * Returns the line nr in the source data on which the element is found. * This method returns 0 there is no associated source data. * *
Postconditions:
*
  • result >= 0 *
*/ public int getLineNr() { return this.lineNr; } /** * Returns an attribute of the element. * If the attribute doesn't exist, null is returned. * * @param name The name of the attribute. * *
Preconditions:
*
* * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object) * getAttribute(String, Object) * @see nanoxml.XMLElement#getAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getAttribute(String, Hashtable, String, boolean) */ public Object getAttribute(String name) { return this.getAttribute(name, null); } /** * Returns an attribute of the element. * If the attribute doesn't exist, defaultValue is returned. * * @param name The name of the attribute. * @param defaultValue Key to use if the attribute is missing. * *
Preconditions:
*
* * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getAttribute(java.lang.String) * getAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getAttribute(String, Hashtable, String, boolean) */ public Object getAttribute(String name, Object defaultValue) { if (this.ignoreCase) { name = name.toUpperCase(); } Object value = this.attributes.get(name); if (value == null) { value = defaultValue; } return value; } /** * Returns an attribute by looking up a key in a hashtable. * If the attribute doesn't exist, the value corresponding to defaultKey * is returned. *

* As an example, if valueSet contains the mapping "one" => * "1" * and the element contains the attribute attr="one", then * getAttribute("attr", mapping, defaultKey, false) returns * "1". * * @param name * The name of the attribute. * @param valueSet * Hashtable mapping keys to values. * @param defaultKey * Key to use if the attribute is missing. * @param allowLiterals * true if literals are valid. * *

Preconditions:
*
* * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getAttribute(java.lang.String) * getAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object) * getAttribute(String, Object) */ public Object getAttribute(String name, Hashtable valueSet, String defaultKey, boolean allowLiterals) { if (this.ignoreCase) { name = name.toUpperCase(); } Object key = this.attributes.get(name); Object result; if (key == null) { key = defaultKey; } result = valueSet.get(key); if (result == null) { if (allowLiterals) { result = key; } else { throw this.invalidValue(name, (String) key); } } return result; } /** * Returns an attribute of the element. * If the attribute doesn't exist, null is returned. * * @param name The name of the attribute. * *
Preconditions:
*
* * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.lang.String) * getStringAttribute(String, String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getStringAttribute(String, Hashtable, String, boolean) */ public String getStringAttribute(String name) { return this.getStringAttribute(name, null); } /** * Returns an attribute of the element. * If the attribute doesn't exist, defaultValue is returned. * * @param name The name of the attribute. * @param defaultValue Key to use if the attribute is missing. * *
Preconditions:
*
* * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getStringAttribute(java.lang.String) * getStringAttribute(String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getStringAttribute(String, Hashtable, String, boolean) */ public String getStringAttribute(String name, String defaultValue) { return (String) this.getAttribute(name, defaultValue); } /** * Returns an attribute by looking up a key in a hashtable. * If the attribute doesn't exist, the value corresponding to defaultKey * is returned. *

* As an example, if valueSet contains the mapping "one" => * "1" * and the element contains the attribute attr="one", then * getAttribute("attr", mapping, defaultKey, false) returns * "1". * * @param name * The name of the attribute. * @param valueSet * Hashtable mapping keys to values. * @param defaultKey * Key to use if the attribute is missing. * @param allowLiterals * true if literals are valid. * *

Preconditions:
*
* * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getStringAttribute(java.lang.String) * getStringAttribute(String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.lang.String) * getStringAttribute(String, String) */ public String getStringAttribute(String name, Hashtable valueSet, String defaultKey, boolean allowLiterals) { return (String) this.getAttribute(name, valueSet, defaultKey, allowLiterals); } /** * Returns an attribute of the element. * If the attribute doesn't exist, 0 is returned. * * @param name The name of the attribute. * *
Preconditions:
*
* * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int) * getIntAttribute(String, int) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getIntAttribute(String, Hashtable, String, boolean) */ public int getIntAttribute(String name) { return this.getIntAttribute(name, 0); } /** * Returns an attribute of the element. * If the attribute doesn't exist, defaultValue is returned. * * @param name The name of the attribute. * @param defaultValue Key to use if the attribute is missing. * *
Preconditions:
*
* * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getIntAttribute(java.lang.String) * getIntAttribute(String) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getIntAttribute(String, Hashtable, String, boolean) */ public int getIntAttribute(String name, int defaultValue) { if (this.ignoreCase) { name = name.toUpperCase(); } String value = (String) this.attributes.get(name); if (value == null) { return defaultValue; } else { try { return Integer.parseInt(value); } catch (NumberFormatException e) { throw this.invalidValue(name, value); } } } /** * Returns an attribute by looking up a key in a hashtable. * If the attribute doesn't exist, the value corresponding to defaultKey * is returned. *

* As an example, if valueSet contains the mapping "one" => 1 * and the element contains the attribute attr="one", then * getIntAttribute("attr", mapping, defaultKey, false) returns * 1. * * @param name * The name of the attribute. * @param valueSet * Hashtable mapping keys to values. * @param defaultKey * Key to use if the attribute is missing. * @param allowLiteralNumbers * true if literal numbers are valid. * *

Preconditions:
*
* * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getIntAttribute(java.lang.String) * getIntAttribute(String) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int) * getIntAttribute(String, int) */ public int getIntAttribute(String name, Hashtable valueSet, String defaultKey, boolean allowLiteralNumbers) { if (this.ignoreCase) { name = name.toUpperCase(); } Object key = this.attributes.get(name); Integer result; if (key == null) { key = defaultKey; } try { result = (Integer) valueSet.get(key); } catch (ClassCastException e) { throw this.invalidValueSet(name); } if (result == null) { if (! allowLiteralNumbers) { throw this.invalidValue(name, (String) key); } try { result = Integer.valueOf((String) key); } catch (NumberFormatException e) { throw this.invalidValue(name, (String) key); } } return result.intValue(); } /** * Returns an attribute of the element. * If the attribute doesn't exist, 0.0 is returned. * * @param name The name of the attribute. * *
Preconditions:
*
* * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double) * getDoubleAttribute(String, double) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getDoubleAttribute(String, Hashtable, String, boolean) */ public double getDoubleAttribute(String name) { return this.getDoubleAttribute(name, 0.); } /** * Returns an attribute of the element. * If the attribute doesn't exist, defaultValue is returned. * * @param name The name of the attribute. * @param defaultValue Key to use if the attribute is missing. * *
Preconditions:
*
* * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String) * getDoubleAttribute(String) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getDoubleAttribute(String, Hashtable, String, boolean) */ public double getDoubleAttribute(String name, double defaultValue) { if (this.ignoreCase) { name = name.toUpperCase(); } String value = (String) this.attributes.get(name); if (value == null) { return defaultValue; } else { try { return Double.valueOf(value).doubleValue(); } catch (NumberFormatException e) { throw this.invalidValue(name, value); } } } /** * Returns an attribute by looking up a key in a hashtable. * If the attribute doesn't exist, the value corresponding to defaultKey * is returned. *

* As an example, if valueSet contains the mapping "one" => * 1.0 * and the element contains the attribute attr="one", then * getDoubleAttribute("attr", mapping, defaultKey, false) * returns 1.0. * * @param name * The name of the attribute. * @param valueSet * Hashtable mapping keys to values. * @param defaultKey * Key to use if the attribute is missing. * @param allowLiteralNumbers * true if literal numbers are valid. * *

Preconditions:
*
* * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String) * getDoubleAttribute(String) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double) * getDoubleAttribute(String, double) */ public double getDoubleAttribute(String name, Hashtable valueSet, String defaultKey, boolean allowLiteralNumbers) { if (this.ignoreCase) { name = name.toUpperCase(); } Object key = this.attributes.get(name); Double result; if (key == null) { key = defaultKey; } try { result = (Double) valueSet.get(key); } catch (ClassCastException e) { throw this.invalidValueSet(name); } if (result == null) { if (! allowLiteralNumbers) { throw this.invalidValue(name, (String) key); } try { result = Double.valueOf((String) key); } catch (NumberFormatException e) { throw this.invalidValue(name, (String) key); } } return result.doubleValue(); } /** * Returns an attribute of the element. * If the attribute doesn't exist, defaultValue is returned. * If the value of the attribute is equal to trueValue, * true is returned. * If the value of the attribute is equal to falseValue, * false is returned. * If the value doesn't match trueValue or * falseValue, an exception is thrown. * * @param name The name of the attribute. * @param trueValue The value associated with true. * @param falseValue The value associated with true. * @param defaultValue Value to use if the attribute is missing. * *
Preconditions:
*
* * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#removeAttribute(java.lang.String) * removeAttribute(String) * @see nanoxml.XMLElement#enumerateAttributeNames() */ public boolean getBooleanAttribute(String name, String trueValue, String falseValue, boolean defaultValue) { if (this.ignoreCase) { name = name.toUpperCase(); } Object value = this.attributes.get(name); if (value == null) { return defaultValue; } else if (value.equals(trueValue)) { return true; } else if (value.equals(falseValue)) { return false; } else { throw this.invalidValue(name, (String) value); } } /** * Returns an attribute by looking up a key in a hashtable. * * @deprecated Use {@link #getIntAttribute(java.lang.String, * java.util.Hashtable, java.lang.String, boolean) * getIntAttribute} instead. */ public int getIntProperty(String name, Hashtable valueSet, String defaultKey) { return this.getIntAttribute(name, valueSet, defaultKey, false); } /** * Returns an attribute. * * @deprecated Use {@link #getStringAttribute(java.lang.String) * getStringAttribute} instead. */ public String getProperty(String name) { return this.getStringAttribute(name); } /** * Returns an attribute. * * @deprecated Use {@link #getStringAttribute(java.lang.String, * java.lang.String) getStringAttribute} instead. */ public String getProperty(String name, String defaultValue) { return this.getStringAttribute(name, defaultValue); } /** * Returns an attribute. * * @deprecated Use {@link #getIntAttribute(java.lang.String, int) * getIntAttribute} instead. */ public int getProperty(String name, int defaultValue) { return this.getIntAttribute(name, defaultValue); } /** * Returns an attribute. * * @deprecated Use {@link #getDoubleAttribute(java.lang.String, double) * getDoubleAttribute} instead. */ public double getProperty(String name, double defaultValue) { return this.getDoubleAttribute(name, defaultValue); } /** * Returns an attribute. * * @deprecated Use {@link #getBooleanAttribute(java.lang.String, * java.lang.String, java.lang.String, boolean) * getBooleanAttribute} instead. */ public boolean getProperty(String key, String trueValue, String falseValue, boolean defaultValue) { return this.getBooleanAttribute(key, trueValue, falseValue, defaultValue); } /** * Returns an attribute by looking up a key in a hashtable. * * @deprecated Use {@link #getAttribute(java.lang.String, * java.util.Hashtable, java.lang.String, boolean) * getAttribute} instead. */ public Object getProperty(String name, Hashtable valueSet, String defaultKey) { return this.getAttribute(name, valueSet, defaultKey, false); } /** * Returns an attribute by looking up a key in a hashtable. * * @deprecated Use {@link #getStringAttribute(java.lang.String, * java.util.Hashtable, java.lang.String, boolean) * getStringAttribute} instead. */ public String getStringProperty(String name, Hashtable valueSet, String defaultKey) { return this.getStringAttribute(name, valueSet, defaultKey, false); } /** * Returns an attribute by looking up a key in a hashtable. * * @deprecated Use {@link #getIntAttribute(java.lang.String, * java.util.Hashtable, java.lang.String, boolean) * getIntAttribute} instead. */ public int getSpecialIntProperty(String name, Hashtable valueSet, String defaultKey) { return this.getIntAttribute(name, valueSet, defaultKey, true); } /** * Returns an attribute by looking up a key in a hashtable. * * @deprecated Use {@link #getDoubleAttribute(java.lang.String, * java.util.Hashtable, java.lang.String, boolean) * getDoubleAttribute} instead. */ public double getSpecialDoubleProperty(String name, Hashtable valueSet, String defaultKey) { return this.getDoubleAttribute(name, valueSet, defaultKey, true); } /** * Returns the name of the element. * * @see nanoxml.XMLElement#setName(java.lang.String) setName(String) */ public String getName() { return this.name; } /** * Returns the name of the element. * * @deprecated Use {@link #getName() getName} instead. */ public String getTagName() { return this.getName(); } /** * Reads one XML element from a java.io.Reader and parses it. * * @param reader * The reader from which to retrieve the XML data. * *
Preconditions:
*
* *
Postconditions:
*
* * @throws java.io.IOException * If an error occured while reading the input. * @throws nanoxml.XMLParseException * If an error occured while parsing the read data. */ public void parseFromReader(Reader reader) throws IOException, XMLParseException { this.parseFromReader(reader, /*startingLineNr*/ 1); } /** * Reads one XML element from a java.io.Reader and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param startingLineNr * The line number of the first line in the data. * *
Preconditions:
*
* *
Postconditions:
*
* * @throws java.io.IOException * If an error occured while reading the input. * @throws nanoxml.XMLParseException * If an error occured while parsing the read data. */ public void parseFromReader(Reader reader, int startingLineNr) throws IOException, XMLParseException { this.name = null; this.contents = ""; this.attributes = new Hashtable(); this.children = new Vector(); this.charReadTooMuch = '\0'; this.reader = reader; this.parserLineNr = startingLineNr; for (;;) { char ch = this.scanWhitespace(); if (ch != '<') { throw this.expectedInput("<"); } ch = this.readChar(); if ((ch == '!') || (ch == '?')) { this.skipSpecialTag(0); } else { this.unreadChar(ch); this.scanElement(this); return; } } } /** * Reads one XML element from a String and parses it. * * @param reader * The reader from which to retrieve the XML data. * *
Preconditions:
*
* *
Postconditions:
*
* * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseString(String string) throws XMLParseException { try { this.parseFromReader(new StringReader(string), /*startingLineNr*/ 1); } catch (IOException e) { // Java exception handling suxx } } /** * Reads one XML element from a String and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param offset * The first character in string to scan. * *
Preconditions:
*
* *
Postconditions:
*
* * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseString(String string, int offset) throws XMLParseException { this.parseString(string.substring(offset)); } /** * Reads one XML element from a String and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param offset * The first character in string to scan. * @param end * The character where to stop scanning. * This character is not scanned. * *
Preconditions:
*
* *
Postconditions:
*
* * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseString(String string, int offset, int end) throws XMLParseException { this.parseString(string.substring(offset, end)); } /** * Reads one XML element from a String and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param offset * The first character in string to scan. * @param end * The character where to stop scanning. * This character is not scanned. * @param startingLineNr * The line number of the first line in the data. * *
Preconditions:
*
* *
Postconditions:
*
* * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseString(String string, int offset, int end, int startingLineNr) throws XMLParseException { string = string.substring(offset, end); try { this.parseFromReader(new StringReader(string), startingLineNr); } catch (IOException e) { // Java exception handling suxx } } /** * Reads one XML element from a char array and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param offset * The first character in string to scan. * @param end * The character where to stop scanning. * This character is not scanned. * *
Preconditions:
*
* *
Postconditions:
*
* * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseCharArray(char[] input, int offset, int end) throws XMLParseException { this.parseCharArray(input, offset, end, /*startingLineNr*/ 1); } /** * Reads one XML element from a char array and parses it. * * @param reader * The reader from which to retrieve the XML data. * @param offset * The first character in string to scan. * @param end * The character where to stop scanning. * This character is not scanned. * @param startingLineNr * The line number of the first line in the data. * *
Preconditions:
*
* *
Postconditions:
*
* * @throws nanoxml.XMLParseException * If an error occured while parsing the string. */ public void parseCharArray(char[] input, int offset, int end, int startingLineNr) throws XMLParseException { try { Reader reader = new CharArrayReader(input, offset, end); this.parseFromReader(reader, startingLineNr); } catch (IOException e) { // This exception will never happen. } } /** * Removes a child element. * * @param child * The child element to remove. * *
Preconditions:
*
* *
Postconditions:
*
* * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement) * addChild(XMLElement) * @see nanoxml.XMLElement#countChildren() * @see nanoxml.XMLElement#enumerateChildren() * @see nanoxml.XMLElement#getChildren() */ public void removeChild(XMLElement child) { this.children.removeElement(child); } /** * Removes an attribute. * * @param name * The name of the attribute. * *
Preconditions:
*
* *
Postconditions:
*
* * @see nanoxml.XMLElement#enumerateAttributeNames() * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double) * setDoubleAttribute(String, double) * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int) * setIntAttribute(String, int) * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object) * setAttribute(String, Object) * @see nanoxml.XMLElement#getAttribute(java.lang.String) * getAttribute(String) * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object) * getAttribute(String, Object) * @see nanoxml.XMLElement#getAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String) * getStringAttribute(String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.lang.String) * getStringAttribute(String, String) * @see nanoxml.XMLElement#getStringAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getStringAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String) * getIntAttribute(String) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int) * getIntAttribute(String, int) * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getIntAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String) * getDoubleAttribute(String) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double) * getDoubleAttribute(String, double) * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, * java.util.Hashtable, * java.lang.String, boolean) * getDoubleAttribute(String, Hashtable, String, boolean) * @see nanoxml.XMLElement#getBooleanAttribute(java.lang.String, * java.lang.String, * java.lang.String, boolean) * getBooleanAttribute(String, String, String, boolean) */ public void removeAttribute(String name) { if (this.ignoreCase) { name = name.toUpperCase(); } this.attributes.remove(name); } /** * Removes an attribute. * * @param name * The name of the attribute. * * @deprecated Use {@link #removeAttribute(java.lang.String) * removeAttribute} instead. */ public void removeProperty(String name) { this.removeAttribute(name); } /** * Removes an attribute. * * @param name * The name of the attribute. * * @deprecated Use {@link #removeAttribute(java.lang.String) * removeAttribute} instead. */ public void removeChild(String name) { this.removeAttribute(name); } /** * Creates a new similar XML element. *

* You should override this method when subclassing XMLElement. */ protected XMLElement createAnotherElement() { return new XMLElement(this.entities, this.ignoreWhitespace, false, this.ignoreCase); } /** * Changes the content string. * * @param content * The new content string. */ public void setContent(String content) { this.contents = content; } /** * Changes the name of the element. * * @param name * The new name. * * @deprecated Use {@link #setName(java.lang.String) setName} instead. */ public void setTagName(String name) { this.setName(name); } /** * Changes the name of the element. * * @param name * The new name. * *

Preconditions:
*
* * @see nanoxml.XMLElement#getName() */ public void setName(String name) { this.name = name; } /** * Writes the XML element to a string. * * @see nanoxml.XMLElement#write(java.io.Writer) write(Writer) */ public String toString() { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(out); this.write(writer); writer.flush(); return new String(out.toByteArray()); } catch (IOException e) { // Java exception handling suxx return super.toString(); } } /** * Writes the XML element to a writer. * * @param writer * The writer to write the XML data to. * *
Preconditions:
*
* * @throws java.io.IOException * If the data could not be written to the writer. * * @see nanoxml.XMLElement#toString() */ public void write(Writer writer) throws IOException { if (this.name == null) { this.writeEncoded(writer, this.contents); return; } writer.write('<'); writer.write(this.name); if (! this.attributes.isEmpty()) { Enumeration enumeration = this.attributes.keys(); while (enumeration.hasMoreElements()) { writer.write(' '); String key = (String) enumeration.nextElement(); String value = (String) this.attributes.get(key); writer.write(key); writer.write('='); writer.write('"'); this.writeEncoded(writer, value); writer.write('"'); } } if ((this.contents != null) && (this.contents.length() > 0)) { writer.write('>'); this.writeEncoded(writer, this.contents); writer.write('<'); writer.write('/'); writer.write(this.name); writer.write('>'); } else if (this.children.isEmpty()) { writer.write('/'); writer.write('>'); } else { writer.write('>'); Enumeration enumeration = this.enumerateChildren(); while (enumeration.hasMoreElements()) { XMLElement child = (XMLElement) enumeration.nextElement(); child.write(writer); } writer.write('<'); writer.write('/'); writer.write(this.name); writer.write('>'); } } /** * Writes a string encoded to a writer. * * @param writer * The writer to write the XML data to. * @param str * The string to write encoded. * *
Preconditions:
*
*/ protected void writeEncoded(Writer writer, String str) throws IOException { for (int i = 0; i < str.length(); i += 1) { char ch = str.charAt(i); switch (ch) { case '<': writer.write('&'); writer.write('l'); writer.write('t'); writer.write(';'); break; case '>': writer.write('&'); writer.write('g'); writer.write('t'); writer.write(';'); break; case '&': writer.write('&'); writer.write('a'); writer.write('m'); writer.write('p'); writer.write(';'); break; case '"': writer.write('&'); writer.write('q'); writer.write('u'); writer.write('o'); writer.write('t'); writer.write(';'); break; case '\'': writer.write('&'); writer.write('a'); writer.write('p'); writer.write('o'); writer.write('s'); writer.write(';'); break; default: int unicode = (int) ch; if ((unicode < 32) || (unicode > 126)) { writer.write('&'); writer.write('#'); writer.write('x'); writer.write(Integer.toString(unicode, 16)); writer.write(';'); } else { writer.write(ch); } } } } /** * Scans an identifier from the current reader. * The scanned identifier is appended to result. * * @param result * The buffer in which the scanned identifier will be put. * *
Preconditions:
*
* *
Postconditions:
*
*/ protected void scanIdentifier(StringBuffer result) throws IOException { for (;;) { char ch = this.readChar(); if (((ch < 'A') || (ch > 'Z')) && ((ch < 'a') || (ch > 'z')) && ((ch < '0') || (ch > '9')) && (ch != '_') && (ch != '.') && (ch != ':') && (ch != '-') && (ch <= '\u007E')) { this.unreadChar(ch); return; } result.append(ch); } } /** * This method scans an identifier from the current reader. * * @return the next character following the whitespace. */ protected char scanWhitespace() throws IOException { for (;;) { char ch = this.readChar(); switch (ch) { case ' ': case '\t': case '\n': case '\r': break; default: return ch; } } } /** * This method scans an identifier from the current reader. * The scanned whitespace is appended to result. * * @return the next character following the whitespace. * *
Preconditions:
*
*/ protected char scanWhitespace(StringBuffer result) throws IOException { for (;;) { char ch = this.readChar(); switch (ch) { case ' ': case '\t': case '\n': result.append(ch); case '\r': break; default: return ch; } } } /** * This method scans a delimited string from the current reader. * The scanned string without delimiters is appended to * string. * *
Preconditions:
*
*/ protected void scanString(StringBuffer string) throws IOException { char delimiter = this.readChar(); if ((delimiter != '\'') && (delimiter != '"')) { throw this.expectedInput("' or \""); } for (;;) { char ch = this.readChar(); if (ch == delimiter) { return; } else if (ch == '&') { this.resolveEntity(string); } else { string.append(ch); } } } /** * Scans a #PCDATA element. CDATA sections and entities are resolved. * The next < char is skipped. * The scanned data is appended to data. * *
Preconditions:
*
*/ protected void scanPCData(StringBuffer data) throws IOException { for (;;) { char ch = this.readChar(); if (ch == '<') { ch = this.readChar(); if (ch == '!') { this.checkCDATA(data); } else { this.unreadChar(ch); return; } } else if (ch == '&') { this.resolveEntity(data); } else { data.append(ch); } } } /** * Scans a special tag and if the tag is a CDATA section, append its * content to buf. * *
Preconditions:
*
*/ protected boolean checkCDATA(StringBuffer buf) throws IOException { char ch = this.readChar(); if (ch != '[') { this.unreadChar(ch); this.skipSpecialTag(0); return false; } else if (! this.checkLiteral("CDATA[")) { this.skipSpecialTag(1); // one [ has already been read return false; } else { int delimiterCharsSkipped = 0; while (delimiterCharsSkipped < 3) { ch = this.readChar(); switch (ch) { case ']': if (delimiterCharsSkipped < 2) { delimiterCharsSkipped += 1; } else { buf.append(']'); buf.append(']'); delimiterCharsSkipped = 0; } break; case '>': if (delimiterCharsSkipped < 2) { for (int i = 0; i < delimiterCharsSkipped; i++) { buf.append(']'); } delimiterCharsSkipped = 0; buf.append('>'); } else { delimiterCharsSkipped = 3; } break; default: for (int i = 0; i < delimiterCharsSkipped; i += 1) { buf.append(']'); } buf.append(ch); delimiterCharsSkipped = 0; } } return true; } } /** * Skips a comment. * *
Preconditions:
*
*/ protected void skipComment() throws IOException { int dashesToRead = 2; while (dashesToRead > 0) { char ch = this.readChar(); if (ch == '-') { dashesToRead -= 1; } else { dashesToRead = 2; } } if (this.readChar() != '>') { throw this.expectedInput(">"); } } /** * Skips a special tag or comment. * * @param bracketLevel The number of open square brackets ([) that have * already been read. * *
Preconditions:
*
*/ protected void skipSpecialTag(int bracketLevel) throws IOException { int tagLevel = 1; // < char stringDelimiter = '\0'; if (bracketLevel == 0) { char ch = this.readChar(); if (ch == '[') { bracketLevel += 1; } else if (ch == '-') { ch = this.readChar(); if (ch == '[') { bracketLevel += 1; } else if (ch == ']') { bracketLevel -= 1; } else if (ch == '-') { this.skipComment(); return; } } } while (tagLevel > 0) { char ch = this.readChar(); if (stringDelimiter == '\0') { if ((ch == '"') || (ch == '\'')) { stringDelimiter = ch; } else if (bracketLevel <= 0) { if (ch == '<') { tagLevel += 1; } else if (ch == '>') { tagLevel -= 1; } } if (ch == '[') { bracketLevel += 1; } else if (ch == ']') { bracketLevel -= 1; } } else { if (ch == stringDelimiter) { stringDelimiter = '\0'; } } } } /** * Scans the data for literal text. * Scanning stops when a character does not match or after the complete * text has been checked, whichever comes first. * * @param literal the literal to check. * *
Preconditions:
*
*/ protected boolean checkLiteral(String literal) throws IOException { int length = literal.length(); for (int i = 0; i < length; i += 1) { if (this.readChar() != literal.charAt(i)) { return false; } } return true; } /** * Reads a character from a reader. */ protected char readChar() throws IOException { if (this.charReadTooMuch != '\0') { char ch = this.charReadTooMuch; this.charReadTooMuch = '\0'; return ch; } else { int i = this.reader.read(); if (i < 0) { throw this.unexpectedEndOfData(); } else if (i == 10) { this.parserLineNr += 1; return '\n'; } else { return (char) i; } } } /** * Scans an XML element. * * @param elt The element that will contain the result. * *
Preconditions:
*
*/ protected void scanElement(XMLElement elt) throws IOException { StringBuffer buf = new StringBuffer(); this.scanIdentifier(buf); String name = buf.toString(); elt.setName(name); char ch = this.scanWhitespace(); while ((ch != '>') && (ch != '/')) { buf.setLength(0); this.unreadChar(ch); this.scanIdentifier(buf); String key = buf.toString(); ch = this.scanWhitespace(); if (ch != '=') { throw this.expectedInput("="); } this.unreadChar(this.scanWhitespace()); buf.setLength(0); this.scanString(buf); elt.setAttribute(key, buf); ch = this.scanWhitespace(); } if (ch == '/') { ch = this.readChar(); if (ch != '>') { throw this.expectedInput(">"); } return; } buf.setLength(0); ch = this.scanWhitespace(buf); if (ch != '<') { this.unreadChar(ch); this.scanPCData(buf); } else { for (;;) { ch = this.readChar(); if (ch == '!') { if (this.checkCDATA(buf)) { this.scanPCData(buf); break; } else { ch = this.scanWhitespace(buf); if (ch != '<') { this.unreadChar(ch); this.scanPCData(buf); break; } } } else { if ((ch != '/') || this.ignoreWhitespace) { buf.setLength(0); } if (ch == '/') { this.unreadChar(ch); } break; } } } if (buf.length() == 0) { while (ch != '/') { if (ch == '!') { ch = this.readChar(); if (ch != '-') { throw this.expectedInput("Comment or Element"); } ch = this.readChar(); if (ch != '-') { throw this.expectedInput("Comment or Element"); } this.skipComment(); } else { this.unreadChar(ch); XMLElement child = this.createAnotherElement(); this.scanElement(child); elt.addChild(child); } ch = this.scanWhitespace(); if (ch != '<') { throw this.expectedInput("<"); } ch = this.readChar(); } this.unreadChar(ch); } else { if (this.ignoreWhitespace) { elt.setContent(buf.toString().trim()); } else { elt.setContent(buf.toString()); } } ch = this.readChar(); if (ch != '/') { throw this.expectedInput("/"); } this.unreadChar(this.scanWhitespace()); if (! this.checkLiteral(name)) { throw this.expectedInput(name); } if (this.scanWhitespace() != '>') { throw this.expectedInput(">"); } } /** * Resolves an entity. The name of the entity is read from the reader. * The value of the entity is appended to buf. * * @param buf Where to put the entity value. * *
Preconditions:
*
*/ protected void resolveEntity(StringBuffer buf) throws IOException { char ch = '\0'; StringBuffer keyBuf = new StringBuffer(); for (;;) { ch = this.readChar(); if (ch == ';') { break; } keyBuf.append(ch); } String key = keyBuf.toString(); if (key.charAt(0) == '#') { try { if (key.charAt(1) == 'x') { ch = (char) Integer.parseInt(key.substring(2), 16); } else { ch = (char) Integer.parseInt(key.substring(1), 10); } } catch (NumberFormatException e) { throw this.unknownEntity(key); } buf.append(ch); } else { char[] value = (char[]) this.entities.get(key); if (value == null) { throw this.unknownEntity(key); } buf.append(value); } } /** * Pushes a character back to the read-back buffer. * * @param ch The character to push back. * *
Preconditions:
*
*/ protected void unreadChar(char ch) { this.charReadTooMuch = ch; } /** * Creates a parse exception for when an invalid valueset is given to * a method. * * @param name The name of the entity. * *
Preconditions:
*
*/ protected XMLParseException invalidValueSet(String name) { String msg = "Invalid value set (entity name = \"" + name + "\")"; return new XMLParseException(this.getName(), this.parserLineNr, msg); } /** * Creates a parse exception for when an invalid value is given to a * method. * * @param name The name of the entity. * @param value The value of the entity. * *
Preconditions:
*
*/ protected XMLParseException invalidValue(String name, String value) { String msg = "Attribute \"" + name + "\" does not contain a valid " + "value (\"" + value + "\")"; return new XMLParseException(this.getName(), this.parserLineNr, msg); } /** * Creates a parse exception for when the end of the data input has been * reached. */ protected XMLParseException unexpectedEndOfData() { String msg = "Unexpected end of data reached"; return new XMLParseException(this.getName(), this.parserLineNr, msg); } /** * Creates a parse exception for when a syntax error occured. * * @param context The context in which the error occured. * *
Preconditions:
*
*/ protected XMLParseException syntaxError(String context) { String msg = "Syntax error while parsing " + context; return new XMLParseException(this.getName(), this.parserLineNr, msg); } /** * Creates a parse exception for when the next character read is not * the character that was expected. * * @param charSet The set of characters (in human readable form) that was * expected. * *
Preconditions:
*
*/ protected XMLParseException expectedInput(String charSet) { String msg = "Expected: " + charSet; return new XMLParseException(this.getName(), this.parserLineNr, msg); } /** * Creates a parse exception for when an entity could not be resolved. * * @param name The name of the entity. * *
Preconditions:
*
*/ protected XMLParseException unknownEntity(String name) { String msg = "Unknown or invalid entity: &" + name + ";"; return new XMLParseException(this.getName(), this.parserLineNr, msg); } } liblaf-plugin-java-1.0/src/org/jvnet/lafplugin/NanoXML.license0000644000175000017500000000200510357100442022420 0ustar godgod NanoXML is distributed under the zlib/libpng license, which is OSS (Open Source Software) compliant. Copyright 2000-2002 Marc De Scheemaecker, All Rights Reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. liblaf-plugin-java-1.0/src/org/jvnet/lafplugin/LafPlugin.java0000644000175000017500000000410510736450336022342 0ustar godgod/* * Copyright (c) 2005-2008 Laf-Plugin Kirill Grouchnikov and contributors. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * o Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * o 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. * * o Neither the name of Flamingo Kirill Grouchnikov nor the names of * its contributors may 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. */ package org.jvnet.lafplugin; /** * Basic interface for look-and-feel plugins. * * @author Kirill Grouchnikov * @author Erik Vickroy * @author Robert Beeger * @author Frederic Lavigne * @author Pattrick Gotthardt */ public interface LafPlugin { /** * Main XML tag. See * {@link PluginManager#PluginManager(String, String, String)}. */ public static final String TAG_MAIN = "laf-plugin"; } liblaf-plugin-java-1.0/build1.4.xml0000644000175000017500000001174510720567370015205 0ustar godgod liblaf-plugin-java-1.0/drop/0000755000175000017500000000000011063275350014070 5ustar godgodliblaf-plugin-java-1.0/drop/laf-plugin.jar0000644000175000017500000003611311063275336016634 0ustar godgodPK C.9 META-INF/PK B.9ǁvMETA-INF/MANIFEST.MFMLK-. K-*ϳR03rCq,HLHU%AE%)N@@ I y Eŕ% yz\>i9y(e%(e*rrPK C.9org/PK C.9 org/jvnet/PK C.9org/jvnet/lafplugin/PK C.9)U0org/jvnet/lafplugin/ComponentPluginManager.classRAI&$h@4@HTHT!Z⵬bę R<[-\XqA;ᚱ,z9_\@!T(1E21Jj1 .)CW0"Q\u q2 #²kn91XX%ozVF ;g; ]50|#K(i劭Tq!Q!$]KA/5so[i}~fD{~y=7]VoWxZsv);Xd]*m2%Sw]S1 &TbRMSb9~.:;byp!up0A22:ܛj`)$X9K_"_ӇcɠkKd;#v#CsHUf"jm`wg<迦}!8DanQg4xZ>P@\qb4W GR2GIDC=N}D@avhauP|Cdj+"hexNדPhf"O, P$)K{8PYNH]iR:%N]ԗ ?Ϩs^ݫÙ&+f$]6641#l(=1u,l8t"?vz*:IA YÚ$#9C]{g۾Γ: PW e`PK C.9,org/jvnet/lafplugin/LafComponentPlugin.classuPJ@Mm Wmm1 !alz<>V a|{0‰#]DŽ 7x֟ų4$=oV̑LeN 1Us&+DJhx?:>3ox*Ku8x^DO7U;!MəR7Y+*j!\E,VkOku.n"ɦd#ʲA ,sԱgaU'4nr֞/PK C.9~#org/jvnet/lafplugin/LafPlugin.class;o>=vNv.FGx_GO?F!IJDļt̼tkF^ļĜTnFҢT̜TF>Ĵ<=nFtIi`)}"F%IY%@ u!*Nddd`f`Ҭ@XPK C.9o*#%org/jvnet/lafplugin/LafPlugin.licenseRKo6 iS@/퉖h,$eDoXb@ n={y|=yqf=hݹ{{v{D;=y& q"o&_L&i"Moۇlϓ!;ξ3Ôѫ3z{]FdzCvMO޽2s:W;~΍ MSlKD@e6;^)uGy!enA5LmKH]IͶ3vfcSknܸ f?z&΃iv\Rh v0P)4vƽX\\p@L$(sd& n6tq }8G:"uhr5\ĦgӅ C m+4kHKg⭬w-לz{bִ˂KE*Zi)&B律bՁ׭JQ-Il8̗҂DM!UFAUQFuH6\ke Q }K-ZM$m */ J|+Mjz_q`%Aj!$u=a (-EW=L05M0W!M۰~g/XNH aFfЍ洪":܉_U4Q<fC҈ѻ4R6[-gh.uèZDBF5ǻ FmZ`w-&7JRxÜP* úޜpJbI؉@=qJ UߍPK C.9(#org/jvnet/lafplugin/NanoXML.licenseuSr0g&LBKg(e:%񗼕CJpc޾vMM_o?KԺ5%sK%,{5Þ;+n^܍hX_OF%8ޙr!}v\㲥[#>d{=t9=z3%] W&]ti.d2a"1 DQȩ- $Mk "C -կ) 5L=M:)ck#.9dI*$/UbP{m!9*a w}4Q#_.\,Of/k2 gL,8X=[.:aӊRi͊P]>`+[@D􀢈 ( %e58Yby,8Mz~jjfOB܄Gtu5&Yox o8b1^r]#&~h0ķѧ& >59`KD-x&^֒핝]^1- 5!r:Ydfж]9VLլ"ڝjcjZ:^cvy9! orI?<\xxsŊ/@~"]_isbY$T-aTq>:(Mh\X-Hh1b~cՈ׶d:Cve2!ZlcoiO~7wE 3\Eը9:8rLsWy:-eT9R(m .`7֠kq7ʛT`_ǚZIHd BqĻmP^@9ؖy4 ^@s0VgMwb0<SgPr֒[Ъ].6 HdTYE] mr!h ,+1)-tiAj(s &CbM<:w0vLNr?ŷʽr/|/y g<ԛ{s p,qwhrnqL ăC؏#Qj=ƛIz;StN34a4sx>_3Y2|mmE.4\ːZ/q+τ7qebuWٱ ~'P4wWA?^x3EF\91lUvVcq%QO$̟bA|N?_깻SR(x3|`G)QTӫ )c{&;L+>PK C.9Iot#!IL$org/jvnet/lafplugin/XMLElement.class[ |ݝݙɐ,GBNQ '!H `9©$vfXVMUPTZkY/zTk+dwχ}zos?>0GGCe:Su\/iqU4MG4H1׬&i "VrאG'*TQE*VLg0Ƶ,#;G{w>.BX#?"n~\ͥ 2{/y jFp 7zuL<|77r77ss 3z+7cv~;w{=<{q~تcƳOS:Ӫxͳxϫ|A/xKx{kyU7Ïb?͟*ʈ䗷<"׾w* WPcUP'T=3o?mPp~41SWu(#vi`g^8v٬3gYV?}ܚuI]PS@E"՞[ ?׶"[(64A>1K P]AJ= 6KPro(#^G `L@_&`(87INkX BVj?hs!5Z}a`]"¢z":`t,j6mUkV"'UOE|TX7ʇްpz.t_\[YTMdf\WVb43ػ6a_T/W[|V7i]R+?D%6GȡU>0L%6i ^TZVE⿊Yۃ];]LqZ HPޮ&&-ez}cseÈzXӐmWПldZ@Q BJۚ`ķzz8 G{5. >>qJj JUj7g41_Db<``;wssp͸97p;~m n1x#0ėJ|moķэ125?w^4[Jj?=Dܸ|!JGs?xPg; g?2!G>cmQb4 C,"F61ub!f)J<шk*L̤Y|r5I\s2DȢ]ig.@#w 48|J3D;lZ9Zp&svq~(G:M冸`Y|N(+r&UK|.H^x47K|3hoW?21m̪B*LzA!qmV(d&s=;bg w6sȍ;T %)!]E\2:eQB}6hS6-ө Hz(tXu ,kd)>)X,ܮӱFoLt5a?SeFڢ3FH?0ڗG5e0{ugB1/ZVH QTnM.hU=Fڌ}'>Ps5Eòڸ3 0m(K@*=;!{yaSR"HE&nw YwO|R!wYk E>ﵞ|nm}&AVb.8..8 ; TG.G'vѓA@M%PZqIr PD $\h"$Zٔ$([4H&= Ӥ17)%|sa7ǀ \xce:i%U& Js8w'tNNx; %ЩB]c'zDjs'rR;-Wߢ7x(w\}=Yo#<_'=d :='PEN>q8'Q|{A<,>ËT-CBGb ؇xzwlc<&U=V 䵏 QTnbzt"72Pi=c H(i6soJjvb@9 Q,Ǵζd"dg~0:$ Q L$>܎>'TNn'c\b)M]IR&(u!>`EQ]&bb:VULmX͆NSqWI%KiYeI%Bp/p/[>l# >. g'%ؾG'8h11ɬl7o)w}(1aa-u/<-0\#ӵmzǸv`0zQRR[$[NPGV~OUHNw.$Gcb$v Հ4=j>i4Mi\rS𦤄Vb: %_MLRe )k1Z9sPCr>*Q\ʅhP.J0?|- gYÈ2ݵ%Kx[ w̮sKl,&&P@Q((@@((1Ty Sv@:%ӕ&z6[Od "H/۪j~u.-:1!*OplIj$uϏL$T&Wb|mcp[}lAwIL[G,t`wQ%76ҿ[({ R+ 4<)hc^;G-F-F, ߡ,Aj-%GR'#q${WwwH wH O~\ I5S7/P#ubf1Ms6UM)[ܛ0Ľ%0}ƸD}U{p{ VJ {1)RpbRd{఑ ^"T>p]bkvҞ ~^[(bHJcGx$v$n @qv'NJT_&?@e͡Cp,c m;O_~1b#IHd/ Y讠1N9&Z[Xrꡃg- x&"SLO=lmɖlM\M\M\I]qd kk҉6Q ֕O8Qϰ~/xvxU诮@u-Գ0R=9L\,PR|P/@HՋp \^Kpz)az^SUxWk:z7Tu9gQ,o\|+>%Ersu*-1Rl@EDqLB#/!ux\} |>էqP}?YK}NdϋA bz(S_ (e YN:̗G8K!FZ!zrЪxRwmr\OށQ? .ۄAa-߄\o&z*gn2%&Opj1K*I~2Gl=>%X(1ڢ}5O=6\ɕ\q@n>{Y|~R-]KFh Fi;+!):ޤ,1=,YV: =#XKCOL!r| 0A;6FfcmU2L"oMz 댔y!|F=!;6}C+m7 *MBVc(Ҧ`Ve&cܩ}{dK_6)V]Vk[vQ%ρZO]OL beC =MџE3/*y\'N l<=Ȋy*ˢ9DA8!vSfv ߪ˪*}YWw"fi }9^}3ŋv`ԝշ\E:GKCo=}31P±z6s1N`Hs0P"A3/vZ=h3*y:~Cc&.Ⱥ붙r^9IZx;hY%s@sqǡfdڮT&zNٻ7`p#$s*vqXZCU1 s]rMXg4qg#,dIȱvyX0BL1U 0_)XOE^^3Xzx\Fō,lp>yxLgz/"-} ח~2>/.<_xEE WzP!q*&a1Yo3􈘥bFMYE?Gub~8O?_\_(.6bUL7yJ~x]F_+>֯S"N%_!GDy奊we>t ypRx~q~X-hC^ ^dyb'RQfUX\d11%"g_=^95۫[!\/Z+%~a~SգKT/^7a1DsЏ̦7{ߋt} 1H߆v?I;Xe7E!>\?+'l/C9GEW*p +EcN:;&/:1UT儫(JpQfU, VgŖ\҉K)!]2jHC`)$ip|"K/BWl]}ethfa^o]Xbe\IMi ut%[w1m:۟2)ɢ~}V[ ))9-,-)zQ8/`bD/FzFzB:!]ҳ=]uGyR= wPK C.9}q+org/jvnet/lafplugin/XMLParseException.classR[oA(,۪x@/x`L@Yv2?/&&jR"5ng|sf}2VR% zl`h L`)q,[(kJ WSƐ_ZU|6Z@=s}jPľ(k7TxAɐXaa{[OŶKHw)G=0v.~*{Ra-+o=++/wdG9JhtvE CVM{Ǎ4̆;rgD,kal i\g2nx7B;o,n&FJ+N 1,.]ٖnu;YLas,t?͑aHSNM &):5 8Eǧ[! S<ʘFH_yq=N&ELt~q¦1CE X/}{~X.~WX?"sKi2QxL)Md *"5:ayxs8M:wQv )KZeY2s3$ 裊.jPFb)jٗXKŌ1rw$L)}~_lУf8o.PK C.9 AMETA-INF/PK B.9ǁv+META-INF/MANIFEST.MFPK C.9Aorg/PK C.9 Aorg/jvnet/PK C.9Aorg/jvnet/lafplugin/PK C.9)U0Oorg/jvnet/lafplugin/ComponentPluginManager.classPK C.9,org/jvnet/lafplugin/LafComponentPlugin.classPK C.9~#Borg/jvnet/lafplugin/LafPlugin.classPK C.9o*#%(org/jvnet/lafplugin/LafPlugin.licensePK C.9(# org/jvnet/lafplugin/NanoXML.licensePK C.9Sz ' org/jvnet/lafplugin/PluginManager.classPK C.9Iot#!IL$@org/jvnet/lafplugin/XMLElement.classPK C.9}q+5org/jvnet/lafplugin/XMLParseException.classPK _8liblaf-plugin-java-1.0/drop/laf-plugin-50.jar0000644000175000017500000003663211063275350017060 0ustar godgodPK H.9 META-INF/PK G.9ǁvMETA-INF/MANIFEST.MFMLK-. K-*ϳR03rCq,HLHU%AE%)N@@ I y Eŕ% yz\>i9y(e%(e*rrPK G.9org/PK G.9 org/jvnet/PK H.9org/jvnet/lafplugin/PK G.9Pn.i0org/jvnet/lafplugin/ComponentPluginManager.classrDƿul˱uҀI cU P'M㖸unedHr}nL` 3$o%c1ӡst?WWȠA9b.aWrC5̩jc 4T cms4likg9uH 6,G6{ }fnn˴MRvߙ ,_`zmc{Ǒnv^reuC{t̶ݎ4;ahX.ٶPQQ{۲3c36}/#Ni >UkR9 ]mIߧQf[y%W5o|^ߏDTd ="DdG֝MW m=~Yeb(/Dk?華lub^>Ѱ kc 7u,&p1:n>Ŋ;+PzuL#Wk`i@99$2 B5?~ ȏ?Fk/t#XUMċ C '11 ' ~!8r^?c'Z /|a,b(8fP(9y Fy)ՙ=,@2OW#a/>.zRX:kݡ<* 4CaoaC%Bx`>>\ƁC™<Oxޏ]oE7gKH2'҅PوLoGh %`RrJm7CvNv.FGx_GO?F!IJDļt̼tkF^ļĜTnFҢT̜TF>Ĵ<=nFtIi`)}"F%IY%@ u!*Nddd`f`Ҭ@XPK H.9o*#%org/jvnet/lafplugin/LafPlugin.licenseRKo6 iS@/퉖h,$eDoXb@ n={y|=yqf=hݹ{{v{D;=y& q"o&_L&i"Moۇlϓ!;ξ3Ôѫ3z{]FdzCvMO޽2s:W;~΍ MSlKD@e6;^)uGy!enA5LmKH]IͶ3vfcSknܸ f?z&΃iv\Rh v0P)4vƽX\\p@L$(sd& n6tq }8G:"uhr5\ĦgӅ C m+4kHKg⭬w-לz{bִ˂KE*Zi)&B律bՁ׭JQ-Il8̗҂DM!UFAUQFuH6\ke Q }K-ZM$m */ J|+Mjz_q`%Aj!$u=a (-EW=L05M0W!M۰~g/XNH aFfЍ洪":܉_U4Q<fC҈ѻ4R6[-gh.uèZDBF5ǻ FmZ`w-&7JRxÜP* úޜpJbI؉@=qJ UߍPK H.9(#org/jvnet/lafplugin/NanoXML.licenseuSr0g&LBKg(e:%񗼕CJpc޾vMM_o?KԺ5%sK%,{5Þ;+n^܍hX_OF%8ޙr!}v\㲥[#>d{=t9=z3%] W&]ti.d2a"1 DQȩ- $Mk "C -կ) 5L=M:)ck#.9dI*$/UbP{m!9*a w}4Q#_.\,Of/k2 gL,8X=[.:aӊRi͊P]>`+[@D􀢈 ( %e58Yby,8Mz~jjfOB%/LqOℊt<:^n#% \vaxQ@/,"7]K:KO%GLu%e*PrAz1Ri#t& `MHʪr{E,_w,>C;!H`}KT@`0gS<5sьe _/E ɔsחH \ӒXP,i[:x/~UEDNA{=W((:^]KաBP8f(y< x eS[OA Sz E7c:Q.-9c;uɃݓ!=HJWE|OC +gQ3-EJ,*ǯBE1aof=ʙI7q%p6Z8Ω5׫¿B#Q>ϝ8s}F\Ϟ89=ns/LRZDF?q,d[3+`իGZ_vgiQZWl|_ygڴ $䏖zgOSs=O}9YĒ׭mn>aV=fVU[&s+Y-|?\aY\Ϟ} ܓ^gX2n8jJwp%ʜ#LBP,DZ] 6%$SMe5ŻEČ}0dBNaG+XNW ,&>/2DZed|(.L>A/avʝ,n^X!%q3OKCt]n~RvFDE&uPK H.9oAVd!L$org/jvnet/lafplugin/XMLElement.class[ |ݝݙɄ,G ' rpr j0lj/E ZkB,1W kkM*G#\s67,e˸9_ѢK*\UPJUbƽZq!.1N\̽Kxݥ[ý˸#~#Wps%7Wqs57ps-GձV|\_KUPW8C񵀷@(8J@LH ["`W><~`@zs,6y̘Y=6U; kcH$XТ|}Z#a'ZD|%憰?(#fI> Ӽ+[}a3 jI #`DkÄ?  %"i3Yд%@iO &@h 9BHe0IB. rg:"2`t,fՓ}$zz]%8&nv?B6.knm D4c5 $ʂHo9;$r|ܓŜjR:Wg҈Ve9[hnɴf1.}hJkP"0hRbzsLәtBO O/ }?L#Xf(=hiUx=*^-SCH dN$:Ԓ?Zt)('֦D& ^q`m/~ۃ%SVY$mw,%?FS%ѐdF64lo6NKH yUi3ĩn:%:\3knQZH&$lEGb֔"بuh̸AO "&7?plPC3VU&1ۈKLNb@RU|$6a6P VzL P-n[7G_e?#``|ru33ez*1nj#32AY&%M,'CKgXuMς†n Kdfspԍ pFx`R҅ VO6wjll'Yt`CG9?/tTRY79L= *)%\J SO B#|qnHzSH99,C rQ+9%&z=iQRu~ +VE,sr쥱+Y.8[X&AʛrÔ`=$%׺5Uk6z_ӚY1]MZb]**MŕĩU Ϯi)ӅK[HF,#ꟇgkпO`FtН F|+ápԱWpKjk``TPkbOHiAc(E$&c7OxMp_nĚopqǛCS|co >1FAhH3H紆oY҆1a D ^Ks8 ?pixp?MápFy?jxÇs 8h89bVm|#=A%j#',ŠYh :R1YA$;@%s@7dV ?nG&6b~'C֐O*L>y5O|R"YOʏI)R>f*{m P˵mrNjuzBd.p]$wx jj2 )*K ͅ1/B{wΦ,;)Dقi64n=:MshX3v{ !&($#K#+I+85QJs wUJak܅b<=ME;ЭйD-U2߁R^R7eѳԓً^yڑ^1'3==ӹp:zTr$4Gwd#e#HboCFx_%] >J>T0M|:7G">3\"r9n_~% CR%3HuxC_[Ml5RMcP; ^Eu5#9 Ցօk@=b:X%#"p P bn va6$x@QLGUygxdx̳y0:$j QK$6܎,cN.%cBb"bbc`g:ӎ'vn삝1lac6;.)؅dI DdNgk~g~CMYv L<4fbmVRAP*6lAOnO ek*HA9)y0 m6"w&aqH"q#HGzۡ%Xc7%׹&}|R-Welw(8Sji9KvaRWaQ | p k>xqmz-qmE_ڎTEHtCʋmڊml9AeYkI\Lʟ6izyRͭΝ]+2 qf"/X1ʭ(';1111)z#91}C\P C]15ƹr?PfG[u}z׏R0 ^J{'P$"b/ " " V$X^4!D^Oi_帢C%-9|o-@Zdم唺2]d;[2]0c*$\e@y}2 d*cW< C (Rm*,6ۑ6#m$ SJ<w4&rdRB2b:JJ+1>J UVar>)\YjbT֠NsKQ\l@K?Zzc}ڜPl-%f׹9F8R8BC!*vqlIj$GJ\&Rf#*KH k11- оM;$A彣f|39Eo 8r;Jz4NH ڭDNQm- GR |w϶pu<IF${WgwH wIDQ Iv}H@LĈ gX*uS~SC"tk%T !yƉd˲J]"^z6Ң'=4r2-;qR ɮmB>e[mebr 6oGoވAM(r߉qW'7cA,potv𻷡0BtV+t#)4 (f k4u\ӶYUL_A5xDwv|!!æ&s qW.5qjBsJ~`0!^/CHp̱d 'tOwIHRL$כzt},tkiShƖj)VTaz蠙a˵7P8x<)G YvFβdˑ6&.&.&.$NX823DEft.Q6#Q&>CfjId!r,d2In̜GvbJH@g> "J\>>Th+Tv'r̦2˦2NV7VM[7$J>hc"OlfK΂;IUWx}LP 6gqylԉP.?Z( b1@t{Kݘ;8Y(;Lj엥t;B!w"yDސKDX ֘cy!VĩG(/|,X(Y)+-ٍRNVHE[gokMN5!bP}Ά֡:չRa:Յ+b(ɹ+.D)?y![9v,V-kG=z`o wZir7N|5 J]i(N`P|jͳbY36ށaEr̢";,sIMZ`MTZ@ڱĦ3=Jm?vگC8kdWxPCT$[x O3Y|>G}A/ %_}Y V%v%Jpʌ Y{oYVɉ}7P[CM|̋bZ 9wBοs>_u7Fx18ǻh#xnDvt#s%]kWPų~ЖWS`'P~i!TG'ѐ[ Fy!Ǣ6Zr 1@!$*0FSY.yѣQMs4G'R(6wYR./ۄ\ &5H5-2'~>闟z4*:hs梷68N[(UH1re˽LuQnE5Y. Tʣssa `n%5;i].ƚFIKw:rrq:jtfz8?γsךY2#Hnvuɗbc`:.M.aZHt%Pm9ҵsG[${Op)6j7x@jɦٶ ; ضmb?օItliuOasx96GcK;a.d v 3ZP/_Lg┸N[R*+6?8(jٛ_َۤADd{Mێ*י;P7gVQJAI]wHC%z:LX+4~JSU:N%;U?HG~r(`>qb>'e'`>듰X&A SZ?kp~2Sq^[iب}:6b>賰W:<{|/~t|;~}fW_*AQ21Nz8Qir1K_!+ř*Ѩ' DX_-Vŕb~ؠ_.+jCF<_+׊m^|d('SJEIƇGoZy5dntI-y|qz|W,o2xm0J8W 7 2].؄.2|l݄6xtnl4rh$Rk| gٔưB9?Gma<[Hid._;1ui]NKnP'lNQ BgGeH}x_`ҀfS1 -b#YhxgXx{1(3Dg)Ye:ސW%wa+qXbeP]ծĪ/f##jC#|e35[u'PK H.9 AMETA-INF/PK G.9ǁv+META-INF/MANIFEST.MFPK G.9Aorg/PK G.9 Aorg/jvnet/PK H.9Aorg/jvnet/lafplugin/PK G.9Pn.i0Oorg/jvnet/lafplugin/ComponentPluginManager.classPK H.9U ^,org/jvnet/lafplugin/LafComponentPlugin.classPK H.9D`x#Vorg/jvnet/lafplugin/LafPlugin.classPK H.9o*#%<org/jvnet/lafplugin/LafPlugin.licensePK H.9(# org/jvnet/lafplugin/NanoXML.licensePK H.9otR' org/jvnet/lafplugin/PluginManager.classPK H.9oAVd!L$Norg/jvnet/lafplugin/XMLElement.classPK H.9'bq+6org/jvnet/lafplugin/XMLParseException.classPK 9