--- /dev/null
+nbproject
+build
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project name="XEMELIOS-xml-marshall" default="usage" basedir=".">
+ <import file="../../common-tasks.xml"/>
+ <description>Builds, tests, and runs the project XEMELIOS xml-marshall</description>
+ <property file="${user.home}/.ant.properties"/>
+ <xmlproperty file="component-definition-properties.xml"/>
+
+ <target name="usage">
+ <echo>
+ Using ${ant.version}
+
+ These are targets supported by this ANT build script:
+
+ compile - compile all .java files, except
+ thoses in ./tmp folder.
+ clean - deletes all compiled and generated
+ files and resources.
+ jars - build jar files.
+
+ Do not call this script directly, use the one located
+ at root of projet (in ../..) instead.
+ </echo>
+ </target>
+
+ <target name="compile" depends="mk-output-dirs,define-compile-debug,prepare">
+ <javac srcdir="java" destdir="build/classes" debug="${compile.debug}" encoding="ISO-8859-1">
+ <classpath>
+ <fileset dir="../core/lib" includes="*.jar"/>
+ </classpath>
+ </javac>
+ <copy todir="build/classes">
+ <fileset dir="java">
+ <include name="**/*"/>
+ <exclude name="**/*.class"/>
+ <exclude name="**/*.java"/>
+ <exclude name="**/*.form"/>
+ </fileset>
+ </copy>
+ </target>
+
+ <target name="jars" depends="prepare">
+ <copy file="manifest/manifest.txt" tofile="build/manifest.txt">
+ <filterset>
+ <filter token="version" value="${component.release}"/>
+ <filter token="name" value="${component.name}"/>
+ </filterset>
+ </copy>
+ <jar destfile="build/jars/${component.name}.jar" basedir="build/classes" manifest="build/manifest.txt"/>
+ </target>
+
+ <target name="clean">
+ <delete dir="build"/>
+ </target>
+
+ <target name="config" depends="get-configuration,prepare">
+ <property name="component.dir" value="build/config/source/${component.name}/${component.release}"/>
+ <copy file="component-definition-properties.xml" tofile="build/config/source/component-definition-properties.xml"/>
+ <mkdir dir="${component.dir}"/>
+ <copy todir="${component.dir}">
+ <fileset dir="build/jars" includes="*.jar"/>
+ </copy>
+ <!--propertyfile file="${component.dir}/component.properties">
+ <entry key="description" value="Module d'écriture xml"/>
+ <entry key="type" value="xemelios-updates"/>
+ <entry key="base.dest" value="${xemelios.prg}/root/lib/"/>
+ <entry key="requires" value="${component.requires}"/>
+ </propertyfile-->
+ <antcall target="generate-update"/>
+ </target>
+
+ <target name="setup">
+ <copy todir="../../build/setup/root/lib">
+ <fileset dir="build/jars" includes="*.jar"/>
+ </copy>
+ </target>
+
+ <target name="mk-output-dirs">
+ <mkdir dir="build/classes"/>
+ <mkdir dir="build/jars"/>
+ </target>
+</project>
+
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="../../defs/technical-component-definition.xsd">
+ <name>xml-marshall</name>
+ <description>Composant d'écriture XML</description>
+ <release>5.0.0.2</release>
+ <url>http://xemelios.org/updatesV5/xml-marshall</url>
+ <type>COMPOSANT</type>
+ <destination>
+ <base>${xemelios.root}/lib</base>
+ </destination>
+ <release-notes>
+ <release v="5.0.0.1">
+ <note>Standardisation des Factory XML</note>
+ </release>
+ </release-notes>
+</component>
--- /dev/null
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package fr.gouv.finances.cp.utils.xml.marshal;
+
+/**
+ *
+ * @author chm
+ */
+public interface CharacterEscaper {
+
+ public String escapeChar(char ch);
+ public String escapeString(String s);
+
+}
--- /dev/null
+/*
+ * Copyright
+ * 2008 axYus - www.axyus.com
+ * 2008 c.Marhcand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.cp.utils.xml.marshal;
+
+import fr.gouv.finances.cp.utils.xml.marshal.escapers.IdenticalEscaper;
+
+/**
+ *
+ * @author chm
+ */
+public class CharacterEscaperFactory {
+
+ public static CharacterEscaper getCharacterEscaper(String charset) {
+// if("ISO-8859-1".equals(charset)) {
+// return new ISO88591Escaper();
+// } else if("UTF-8".equals(charset)) {
+// return new UTF8Escaper();
+// } else
+// return new DefaultCharacterEscaper();
+ return new IdenticalEscaper();
+ }
+
+}
--- /dev/null
+/*\r
+ * Copyright \r
+ * 2005 axYus - www.axyus.com\r
+ * 2005 C.Marchand - christophe.marchand@axyus.com\r
+ * \r
+ * This file is part of XEMELIOS.\r
+ * \r
+ * XEMELIOS is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * XEMELIOS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with XEMELIOS; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+\r
+package fr.gouv.finances.cp.utils.xml.marshal;\r
+\r
+/**\r
+ * Thrown if parsed xml is invalid.\r
+ * <p>License : LGPL\r
+ * @author: Christophe MARCHAND\r
+ */\r
+public class InvalidXmlDefinition extends Exception {\r
+ /**\r
+ * Comment for <code>serialVersionUID</code>\r
+ */\r
+ private static final long serialVersionUID = 3905805266510165298L;\r
+ private Exception parentException = null;\r
+ /**\r
+ * InvalidXmlDefinition constructor comment.\r
+ */\r
+ public InvalidXmlDefinition() {\r
+ super();\r
+ }\r
+ /**\r
+ * InvalidXmlDefinition constructor comment.\r
+ * @param ex java.lang.Exception\r
+ */\r
+ public InvalidXmlDefinition(Exception ex) {\r
+ super();\r
+ parentException = ex;\r
+ }\r
+ /**\r
+ * InvalidXmlDefinition constructor comment.\r
+ * @param s java.lang.String\r
+ */\r
+ public InvalidXmlDefinition(String s) {\r
+ super(s);\r
+ }\r
+ /**\r
+ * Returns the parent exception if defined, <code>this</code> otherwise.\r
+ * @return java.lang.Exception\r
+ */\r
+ public Exception getException() {\r
+ if(parentException!=null) {\r
+ return parentException;\r
+ }\r
+ return this;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright \r
+ * 2005 axYus - www.axyus.com\r
+ * 2005 C.Marchand - christophe.marchand@axyus.com\r
+ * \r
+ * This file is part of XEMELIOS.\r
+ * \r
+ * XEMELIOS is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * XEMELIOS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with XEMELIOS; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+\r
+package fr.gouv.finances.cp.utils.xml.marshal;\r
+\r
+/**\r
+ * Mutable version of {@link #java.lang.Boolean}.\r
+ * <p>This class is fully-compliant with {@link java.lang.Boolean}, except\r
+ * {@link #valueOf(String)} method, which returns a <code>MutableBoolean</code>\r
+ * instead of a {@link java.lang.Boolean}.\r
+ * <p>License : LGPL\r
+ * @author: Christophe MARCHAND\r
+ */\r
+public class MutableBoolean implements java.io.Serializable {\r
+ /**\r
+ * Comment for <code>serialVersionUID</code>\r
+ */\r
+ private static final long serialVersionUID = 3904682695270414643L;\r
+ private boolean value = false;\r
+\r
+ /**\r
+ * MutableBoolean constructor comment.\r
+ */\r
+ public MutableBoolean() {\r
+ super();\r
+ }\r
+\r
+ /**\r
+ * Constructs a <code>MutableBoolean</code> from a {@link java.lang.Boolean} value.\r
+ * @param value The initial value.\r
+ */\r
+ public MutableBoolean(Boolean value) {\r
+ super();\r
+ this.value = value.booleanValue();\r
+ }\r
+\r
+ /**\r
+ * Constructs a <code>MutableBoolean</code> from a {@link java.lang.String} value.\r
+ * @param value The initial value.\r
+ */\r
+ public MutableBoolean(String value) {\r
+ super();\r
+ if (value != null) {\r
+ this.value = value.equalsIgnoreCase("true");\r
+ }\r
+ }\r
+ /**\r
+ * Constructs a <code>MutableBoolean</code> from a <code>boolean</code> value.\r
+ * @param value The initial value.\r
+ */\r
+ public MutableBoolean(boolean value) {\r
+ super();\r
+ this.value = value;\r
+ }\r
+ /**\r
+ * Returns the value of this <code>MutableBoolean</code> object as a boolean primitive.\r
+ * @return boolean\r
+ */\r
+ public boolean booleanValue() {\r
+ return value;\r
+ }\r
+ /**\r
+ * Returns <code>true</code> if and only if the argument is <code>not null</code>\r
+ * and is a {@link java.lang.Boolean} or a <code>MutableBoolean</code> object that\r
+ * represents the same boolean value as this object.\r
+ * @return boolean\r
+ * @param o java.lang.Object\r
+ */\r
+ @Override\r
+ public boolean equals(Object o) {\r
+ if (o == null) {\r
+ return false;\r
+ } else\r
+ if (o instanceof java.lang.Boolean) {\r
+ return (((java.lang.Boolean) o).booleanValue() == value);\r
+ } else\r
+ if (o instanceof MutableBoolean) {\r
+ return (((MutableBoolean) o).booleanValue() == value);\r
+ } else {\r
+ return false;\r
+ }\r
+ }\r
+// /**\r
+// * Returns <code>true</code> if and only if the system property named by the\r
+// * argument exists and is equal to the string <code>"true"</code>.\r
+// * <p>If there is no property with the specified <code>name</code>, or if the\r
+// * specified <code>name</code> is empty or <code>null</code>, then <code>false</code>\r
+// * is returned.\r
+// * @return boolean\r
+// * @param name java.lang.String\r
+// */\r
+// public boolean getBoolean(String name) {\r
+// String propVal = Sys tem.getProperty(name);\r
+// if (propVal == null) {\r
+// return false;\r
+// }\r
+// return propVal.equalsIgnoreCase("true");\r
+// }\r
+ /**\r
+ * Returns a hash code for this <code>MutableBoolean</code> object.\r
+ * @return the integer <code>1231</code> if this object represents <code>true</code>;\r
+ * returns the integer <code>1237</code> if this object represents <code>false</code>.\r
+ */\r
+ @Override\r
+ public int hashCode() {\r
+ return (value ? 1231 : 1237);\r
+ }\r
+ /**\r
+ * Insert the method's description here.\r
+ * @param newValue boolean\r
+ */\r
+ public void setValue(boolean newValue) {\r
+ value = newValue;\r
+ }\r
+ /**\r
+ * Returns a <code>String</code> object representing this <code>MutableBoolean</code>'s\r
+ * value. If this object represents the value <code>true</code>, a string equal to \r
+ * "<code>true</code>" is returned. Otherwise, a string equal to "<code>false</code>"\r
+ * is returned.\r
+ * @return a string representation of this object.\r
+ */\r
+ @Override\r
+ public String toString() {\r
+ return (value ? "true" : "false");\r
+ }\r
+ /**\r
+ * Returns a <code>MutableBoolean</code> with a value represented by the \r
+ * specified String. The <code>MutableBoolean</code> returned represents \r
+ * the value <code>true</code> if the string argument is <code>not null</code>\r
+ * and is equal, ignoring case, to the string "<code>true</code>". \r
+ * <p>Example: <code>Boolean.valueOf("True")</code> returns <code>true</code>.\r
+ * <br>Example: <code>Boolean.valueOf("yes")</code> returns <code>false</code>.\r
+ * @return the <code>MutableBoolean</code> value represented by the string.\r
+ * @param s a string.\r
+ */\r
+ public static MutableBoolean valueOf(String s) {\r
+ return new MutableBoolean(s);\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright
+ * 2005 axYus - www.axyus.com
+ * 2005 N LE CORRE - nicolas.lecorre@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package fr.gouv.finances.cp.utils.xml.marshal;
+
+import org.xml.sax.Attributes;
+
+/**
+ *
+ * Cette interface apporte un certain nombre de méthodes permettant de naviguer au sein de l'arborescence construite d'après un fichier
+ * de configuration métier.
+ *
+ */
+public interface NoeudModifiable extends XmlMarshallable {
+ /**
+ * Retourne le <tt>NoeudModifiable</tt> représentant l'élément parent dans l'arbre
+ * @return NoeudModifiable
+ */
+ public NoeudModifiable getParentAsNoeudModifiable();
+ /**
+ * Met à jour le <tt>NoeudModifiable</tt> représentant l'élément parent dans l'arbre
+ * @param p le parent
+ */
+ public void setParentAsNoeudModifiable(NoeudModifiable p);
+ /**
+ * Retourne un élément fils retrouvé dans l'une des collections de fils de l'élément courant à partir de son tag et de son identifiant.
+ * Attention, son identifiant n'est pas toujours la valeur de l'attribut <tt>id</tt>.
+ * Pour connaitre le nom de l'attribut identifiant, utiliser {@link getChildIdAttrName(String)}
+ * @param tagName le tag du fils cherché
+ * @param id l'identifiant du fils cherché
+ * @return NoeudModifiable
+ */
+ public NoeudModifiable getChildAsNoeudModifiable(String tagName, String id);
+ /**
+ * NON IMPLEMENTE POUR LE MOMENT
+ */
+ public void modifyAttr(String attrName, String value);
+ /**
+ * Met à jour les attributs de l'élement courant avec ceux de la collection <tt>attrs</tt>
+ * @param attrs la liste des attributs à mettre à jour
+ */
+ public void modifyAttrs(Attributes attrs);
+ /**
+ * Retourne le nom du ou des attribut(s) servant d'identifiant pour le fils dont le tag est passé en paramètre
+ * @param childTagName le tag du fils
+ * @return String[]
+ */
+ public String[] getChildIdAttrName(String childTagName);
+ /**
+ * Permet de remettre à zéro le buffer rempli par addCharacterData
+ */
+ public void resetCharData();
+ /**
+ * Renvoie la valeur de l'attribut identifiant.
+ * Attention, cet attribut n'est pas forcément <tt>id</tt>.
+ * Pour connaitre le nom de l'attribut identifiant, utiliser {@link getChildIdAttrName(String)}
+ * @return id value
+ */
+ public String getIdValue();
+ /**
+ * Renvoie le XPath de cet element
+ */
+ public String getConfigXPath();
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright
+ * 2005 axYus - www.axyus.com
+ * 2005 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.cp.utils.xml.marshal;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.xml.sax.SAXException;
+
+/**
+ * This class wraps a org.xml.sax.Attributes object and defines helper methods;
+ * <p>
+ * License : LGPL
+ *
+ * @author: Christophe MARCHAND
+ */
+public class XmlAttributes {
+ private org.xml.sax.Attributes attrs = null;
+
+ private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ private static final SimpleDateFormat dt_sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZ");
+
+ /**
+ * Construct an XmlAttributes based on this <code>attrs</code> attributes.
+ */
+ public XmlAttributes(org.xml.sax.Attributes attrs) {
+ super();
+ this.attrs = attrs;
+ }
+
+ /**
+ * Returns the attributes.
+ *
+ * @return org.xml.sax.Attributes
+ */
+ public org.xml.sax.Attributes getAttributes() {
+ return attrs;
+ }
+
+ /**
+ * Constructs and returns a <code>BigDecimal</code> parsed from a
+ * specified attribute value.
+ *
+ * @return java.math.BigDecimal
+ * @param attName
+ * java.lang.String
+ */
+ public java.math.BigDecimal getBigDecimalValue(String attName) {
+ return new java.math.BigDecimal(attrs.getValue(attName));
+ }
+
+ /**
+ * Returns the boolean value of the specified attribute.
+ *
+ * @return boolean
+ * @param attName The attribute to read
+ */
+ public boolean getBooleanValue(String attName) throws SAXException {
+ // chm:2006-04-21
+ // as xs:boolean may have yes / true/ 1, change this
+ String sTmp = attrs.getValue(attName);
+ if(sTmp==null) return false;
+ sTmp = "|"+sTmp.toUpperCase()+"|";
+ if("|TRUE|YES|1|".contains(sTmp)) return true;
+ else if("|FALSE|NO|0|".contains(sTmp)) return false;
+ else throw new SAXException("invalid boolean value for attribute "+attName+"=\""+sTmp+"\"");
+ }
+
+ /**
+ * Returns the <code>int</code> value
+ *
+ * @return int
+ * @param attName
+ * java.lang.String
+ */
+ public int getIntValue(String attName) {
+ return Integer.parseInt(attrs.getValue(attName));
+ }
+
+ /**
+ * Returns the <code>long</code> value of the specified attribute.
+ *
+ * @return long
+ * @param attName
+ * java.lang.String
+ */
+ public long getLongValue(String attName) {
+ return Long.parseLong(attrs.getValue(attName));
+ }
+
+ /**
+ * Returns the value of the specified attribute.
+ *
+ * @return java.lang.String
+ * @param attName
+ * java.lang.String
+ */
+ public String getValue(String attName) {
+ return attrs.getValue(attName);
+ }
+ public char getCharValue(String attName) {
+ String s = getValue(attName);
+ if(s!=null && s.length()>0) return s.charAt(0);
+ return '\u0000';
+ }
+
+ /**
+ * Returns the value of the specified attribute.
+ *
+ * @return java.lang.String
+ * @param uri
+ * java.lang.String
+ * @param localName
+ * java.lang.String
+ */
+ public String getValue(String uri, String localName) {
+ return attrs.getValue(uri, localName);
+ }
+ /**
+ * Returns the first char of the specified attribute, or <tt>\u0000</tt> if specified is empty or null
+ * @param uri
+ * @param localName
+ * @return
+ */
+ public char getCharValue(String uri, String localName) {
+ String s = getValue(uri,localName);
+ if(s!=null && s.length()>0) return s.charAt(0);
+ return '\u0000';
+ }
+
+
+ public Date getDateValue(String attName) {
+ String s = getValue(attName);
+ if(s==null) return null;
+ try {
+ return sdf.parse(s);
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+ public Date getDateValue(String uri, String localName) {
+ String s = getValue(uri, localName);
+ if(s==null) return null;
+ try {
+ return sdf.parse(s);
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+
+ public Date getDateTimeValue(String attName) {
+ String s = getValue(attName);
+ if(s==null) return null;
+ try {
+ return dt_sdf.parse(s);
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+ public Date getDateTimeValue(String uri, String localName) {
+ String s = getValue(uri, localName);
+ if(s==null) return null;
+ try {
+ return dt_sdf.parse(s);
+ } catch(Exception ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright
+ * 2005 axYus - www.axyus.com
+ * 2005 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.cp.utils.xml.marshal;
+
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.SAXException;
+
+/**
+ * This class is a Marshaller parser.
+ * <p>License : LGPL
+ * @author: Christophe MARCHAND
+ */
+public class XmlMarshalParser {
+
+ /**
+ * The XmlUnMarshaller.
+ */
+ protected XmlUnMarshaller unMarshaller = null;
+
+ /**
+ * The SAX parser.
+ */
+ SAXParser parser = null;
+
+
+ /**
+ * Constructs a new validating XmlMarsalParser based on this <code>mapping</code>
+ * and instanciate everything needed to parse.
+ * @param mapping The mapping between XML tags and classes to instanciate.
+ * @param saxFactory The SAXParserFactory to use
+ */
+ public XmlMarshalParser(java.util.HashMap mapping, SAXParserFactory saxFactory) throws SAXException, ParserConfigurationException, FactoryConfigurationError {
+ this(mapping,true, saxFactory);
+ }
+
+
+ /**
+ * Constructs a new XmlMarsalParser based on this <code>mapping</code>
+ * and instanciate everything needed to parse.
+ * @param mapping The mapping between XML tags and classes to instanciate
+ * @param validating Wether the parser should be a validating one or not
+ * @param saxFactory The SAXParserFactory to use
+ */
+ public XmlMarshalParser(java.util.HashMap mapping, boolean validating, SAXParserFactory saxFactory) throws SAXException, ParserConfigurationException, FactoryConfigurationError {
+ super();
+ unMarshaller = new XmlUnMarshaller(mapping);
+ parser = saxFactory.newSAXParser();
+ }
+
+
+ /**
+ * Return the constructed <code>XmlMarshallable</code> object.
+ * @return com.labodev.xml.XmlMarshallable
+ */
+ public XmlMarshallable getMarshallable() {
+ return unMarshaller.getMarshallable();
+ }
+
+ public void setInitialData(XmlMarshallable data) {
+ unMarshaller.setDataToChange(data);
+ }
+
+ /**
+ * Parse the content of the file specified as XML using the inner
+ * <code>XmlUnMarshaller</code>.
+ * @param f java.io.File
+ * @exception java.io.IOException The exception description.
+ * @exception org.xml.sax.SAXException The exception description.
+ */
+ public void parse(java.io.File f) throws java.io.IOException, org.xml.sax.SAXException {
+ parser.parse(f,unMarshaller);
+ }
+
+
+ /**
+ * Parse the content of the file specified as XML using the inner
+ * <code>XmlUnMarshaller</code>.
+ * @param is java.io.InputStream
+ * @exception java.io.IOException The exception description.
+ * @exception org.xml.sax.SAXException The exception description.
+ */
+ public void parse(java.io.InputStream is) throws java.io.IOException, org.xml.sax.SAXException {
+ parser.parse(is,unMarshaller);
+ }
+
+
+ /**
+ * Parse the content of the file specified as XML using the inner
+ * <code>XmlUnMarshaller</code>.
+ * @param uri java.lang.String
+ * @exception java.io.IOException The exception description.
+ * @exception org.xml.sax.SAXException The exception description.
+ */
+ public void parse(String uri) throws java.io.IOException, org.xml.sax.SAXException {
+ parser.parse(uri,unMarshaller);
+ }
+
+ /**
+ * Parse the content of the file specified as XML using the inner
+ * <code>XmlUnMarshaller</code>.
+ * @param is org.xml.sax.InputSource
+ * @exception java.io.IOException The exception description.
+ * @exception org.xml.sax.SAXException The exception description.
+ */
+ public void parse(org.xml.sax.InputSource is) throws java.io.IOException, org.xml.sax.SAXException {
+ parser.parse(is,unMarshaller);
+ }
+}
--- /dev/null
+/*\r
+ * Copyright \r
+ * 2005 axYus - www.axyus.com\r
+ * 2005 C.Marchand - christophe.marchand@axyus.com\r
+ * \r
+ * This file is part of XEMELIOS.\r
+ * \r
+ * XEMELIOS is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * XEMELIOS is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with XEMELIOS; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+ */\r
+package fr.gouv.finances.cp.utils.xml.marshal;\r
+\r
+import javax.xml.namespace.QName;\r
+\r
+/**\r
+ * Base interface that each tag-associated class must implement.\r
+ * <br><b>WARNING :</b> there is no language-way to force this,\r
+ * but you <b>MUST</b> provide a constructor with this signature :\r
+ * <br><center><code>public <className> (String tagName) {}</code></center>\r
+ * <br>or instanciation will throw a <code>java.lang.NoSuchMethodException</code>.\r
+ * <p>License : LGPL\r
+ * @author Christophe MARCHAND\r
+ */\r
+public interface XmlMarshallable extends Cloneable {\r
+\r
+ /**\r
+ * Called by the <code>XmlUnMarshaller</code> to add <code>#CDATA</code> or <code>#PCDATA</code> data.\r
+ * @param cData java.lang.String\r
+ * @exception org.xml.sax.SAXException The exception description.\r
+ */\r
+ public void addCharacterData(String cData) throws org.xml.sax.SAXException;\r
+\r
+ /**\r
+ * Receive notification that a child is to be added to this element.\r
+ * @param child The child to add.\r
+ * @param tag The child's element QName.\r
+ * @exception org.xml.sax.SAXException The exception description.\r
+ */\r
+ public void addChild(XmlMarshallable child, QName tag) throws org.xml.sax.SAXException;\r
+\r
+ /**\r
+ * This method is called by the <code>XmlUnMarshaller</code> to allow the model to load its attributes.\r
+ * If the object to construct depends on attributes or anything you can imagine,\r
+ * instanciate what's desired and returns it ; the returned object will be used\r
+ * for next call. In other case, just add <code>return this;</code> to your code.\r
+ * @param attributes com.labodev.xml.XmlAttributes\r
+ * @return XmlMarshallable The resulted object.\r
+ * @exception org.xml.sax.SAXException The exception description.\r
+ */\r
+ public XmlMarshallable getAttributes(XmlAttributes attributes) throws org.xml.sax.SAXException;\r
+\r
+ /**\r
+ * Returns the child of this object that is to be modified by xml reading.\r
+ * @param uri The namespace-uri of the child object name\r
+ * @param localName The child localName\r
+ * @param qName The child quailfied-name\r
+ * @param atts The attributes defined in xml file for the child object\r
+ * @return The child found or <code>null</code>\r
+ */\r
+ public XmlMarshallable getChildToModify(String uri, String localName, String qName, org.xml.sax.Attributes atts);\r
+\r
+ /**\r
+ * Writes this element, its attributes and its child(ren).\r
+ * @param output com.labodev.xml.XmlOutputter\r
+ */\r
+ public void marshall(XmlOutputter output);\r
+\r
+ /**\r
+ * Must throw an <code>InvalidXmlException</code> if an attribute or one of\r
+ * its children is wrong.\r
+ * @exception com.labodev.xml.marshal.InvalidXmlDefinition The exception description.\r
+ */\r
+ public void validate() throws InvalidXmlDefinition;\r
+\r
+ public Object clone();\r
+\r
+ public QName getQName();\r
+}\r
--- /dev/null
+/*\r * Copyright \r * 2005 axYus - www.axyus.com\r * 2005 C.Marchand - christophe.marchand@axyus.com\r * \r * This file is part of XEMELIOS.\r * \r * XEMELIOS is free software; you can redistribute it and/or modify\r * it under the terms of the GNU General Public License as published by\r * the Free Software Foundation; either version 2 of the License, or\r * (at your option) any later version.\r * \r * XEMELIOS is distributed in the hope that it will be useful,\r * but WITHOUT ANY WARRANTY; without even the implied warranty of\r * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r * GNU General Public License for more details.\r * \r * You should have received a copy of the GNU General Public License\r * along with XEMELIOS; if not, write to the Free Software\r * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r */\rpackage fr.gouv.finances.cp.utils.xml.marshal;\r\rimport fr.gouv.finances.cp.utils.xml.marshal.escapers.NamespaceContextImpl;\rimport java.io.IOException;\rimport java.io.OutputStreamWriter;\rimport java.nio.charset.Charset;\rimport java.text.SimpleDateFormat;\rimport java.util.Date;\rimport java.util.Iterator;\rimport java.util.Stack;\rimport java.util.Vector;\rimport javax.xml.namespace.QName;\rimport org.apache.log4j.Logger;\r\r/**\r * This class defines an xml writer.\r * <p>License : LGPL\r * @author: Christophe MARCHAND\r */\rpublic class XmlOutputter {\r private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");\r private static final SimpleDateFormat dt_sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZ");\r\r private static final Logger logger = Logger.getLogger(XmlOutputter.class);\r private static final String DEFAULT_ENCODING = "UTF-8";\r private String encoding;\r private OutputStreamWriter os;\r private static final String CRLF = System.getProperty("line.separator");\r private boolean writeStarted = false;\r private NamespaceContextImpl nsCtx;\r Charset cs = null;\r /**\r * Indent level. Incremented by <code>startTag(String)</code>, decremented by\r * <code>endTag(String)</code>.\r */\r private int indentLevel = 0;\r /**\r * Indent string.\r */\r public static final transient String INDENT_STR = " ";\r /**\r * A vector to store attributes.\r */\r private Vector<Attribute> attributes = null;\r /**\r * to store if attributes have been written or not.\r */\r private boolean attributesFlushed = false;\r /**\r * Indent string.\r */\r private String indentStr = INDENT_STR;\r /**\r * a stack to remember if top-element as child or not.\r */\r private Stack<MutableBoolean> stack = null;\r private CharacterEscaper escaper = null;\r private Stack<String> nsStack = null;\r\r class Attribute extends java.lang.Object {\r\r private String attName = null;\r private String value = null;\r private QName attQ = null;\r\r public Attribute(String attName, String value) {\r this.attName = attName;\r this.value = value;\r }\r\r public Attribute(QName attQ, String value) {\r this.attQ = attQ;\r this.value = value;\r }\r\r @Override\r public String toString() {\r StringBuffer sb = new StringBuffer();\r if (attName != null) {\r sb.append(" ").append(attName).append("=\"");\r } else {\r sb.append(" ");\r if (attQ.getPrefix() != null && attQ.getPrefix().length() > 0) {\r sb.append(attQ.getPrefix()).append(":");\r }\r sb.append(attQ.getLocalPart()).append("=\"");\r }\r if (value != null) {\r sb.append(value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'"));\r }\r sb.append("\"");\r return sb.toString();\r }\r\r public String toString(CharacterEscaper escaper) {\r StringBuffer sb = new StringBuffer();\r if (attName != null) {\r sb.append(" ").append(attName).append("=\"");\r } else {\r sb.append(" ");\r if (attQ.getPrefix() != null && attQ.getPrefix().length() > 0) {\r sb.append(attQ.getPrefix()).append(":");\r }\r sb.append(attQ.getLocalPart()).append("=\"");\r }\r if (value != null) {\r sb.append(escaper.escapeString(value));\r }\r sb.append("\"");\r return sb.toString();\r }\r }\r\r /**\r * Constructs a XmlOutputter object based on a <code>OutputStream</code>.\r * \r * @param out the outputstream to write to\r * @param encoding The encoding of xml output\r * @see java.io.OutputStream\r */\r public XmlOutputter(OutputStreamWriter out, String encoding) {\r super();\r this.os = out;\r this.encoding = encoding;\r init();\r }\r\r /**\r * Constructs a XmlOutputter object based on a <code>OutputStream</code>, with the default encoding (UTF-8).\r * @param out the outputstream to write to\r */\r public XmlOutputter(OutputStreamWriter out) {\r this(out, DEFAULT_ENCODING);\r }\r\r /**\r * Writes a int attribute.\r * @param tag java.lang.String\r * @param value int\r */\r public void addAttribute(String attr, int value) {\r addAttribute(attr, Integer.toString(value));\r }\r\r /**\r * Writes a int attribute.\r * @param tag\r * @param value int\r */\r public void addAttribute(QName attr, int value) {\r addAttribute(attr, Integer.toString(value));\r }\r\r /**\r * Writes a long attribute.\r * @param tag java.lang.String\r * @param value long\r */\r public void addAttribute(String attr, long value) {\r addAttribute(attr, Long.toString(value));\r }\r\r /**\r * Writes a long attribute.\r * @param tag\r * @param value long\r */\r public void addAttribute(QName attr, long value) {\r addAttribute(attr, Long.toString(value));\r }\r\r /**\r * Writes an attribute.\r * @param tag java.lang.String\r * @param value java.lang.String\r */\r public void addAttribute(String attr, String value) {\r attributes.add(new Attribute(attr, value));\r }\r\r /**\r * Writes an attribute.\r * @param tag\r * @param value java.lang.String\r */\r public void addAttribute(QName attr, String value) {\r attributes.add(new Attribute(attr, value));\r }\r\r /**\r * Writes a BigDecimal attribute.\r * @param tag java.lang.String\r * @param value java.math.BigDecimal\r */\r public void addAttribute(String attr, java.math.BigDecimal value) {\r addAttribute(attr, value.toString());\r }\r\r /**\r * Writes a BigDecimal attribute.\r * @param tag\r * @param value java.math.BigDecimal\r */\r public void addAttribute(QName attr, java.math.BigDecimal value) {\r addAttribute(attr, value.toString());\r }\r\r /**\r * Writes a boolean attribute.\r * @param tag java.lang.String\r * @param value boolean\r */\r public void addAttribute(String attr, boolean value) {\r addAttribute(attr, value ? "true" : "false");\r }\r\r /**\r * Writes a boolean attribute.\r * @param tag\r * @param value boolean\r */\r public void addAttribute(QName attr, boolean value) {\r addAttribute(attr, value ? "true" : "false");\r }\r /**\r * Writes a java.util.Date attribute, conforming to <tt>xs:date</tt>\r * @param attName\r * @param date\r */\r public void addAttribute(String attName, Date date) {\r addAttribute(attName,sdf.format(date));\r }\r /**\r * Writes a java.util.Date attribute, conforming to <tt>xs:date</tt>\r * @param attr\r * @param date\r */\r public void addAttribute(QName attr, Date date) {\r addAttribute(attr,sdf.format(date));\r }\r /**\r * Writes a java.util.Date attribute, conforming to <tt>xs:date</tt>\r * @param attName\r * @param date\r */\r public void addDateTimeAttribute(String attName, Date date) {\r addAttribute(attName,dt_sdf.format(date));\r }\r /**\r * Writes a java.util.Date attribute, conforming to <tt>xs:date</tt>\r * @param attr\r * @param date\r */\r public void addDateTimeAttribute(QName attr, Date date) {\r addAttribute(attr,dt_sdf.format(date));\r }\r\r /**\r * Adds character data (#CDATA) to encapsulated Writer.\r * @param cData java.lang.String\r */\r public void addCharacterData(String cData) {\r flushAttributes(false);\r try {\r os.write(escaper.escapeString(cData));\r } catch (Throwable t) {\r }\r if (cData.indexOf("\n") != (-1)) {\r (stack.peek()).setValue(true);\r }\r }\r\r public void addComment(String comment) {\r writeStarted = true;\r flushAttributes(false);\r try {\r os.write("<!-- ");\r os.write(comment);\r os.write(" -->");\r } catch (Throwable t) {\r }\r }\r\r /**\r * Close the stack-on-top element. If <code>tag</code> is different of stack-on-top,\r * throws an <code>InvalidParameterException</code>.\r * @param tag java.lang.String\r * @exception java.security.InvalidParameterException If tag name\r * doesn't match the previously opened one.\r */\r public void endTag(String tag) throws java.security.InvalidParameterException {\r if (attributesFlushed) {\r indentLevel--;\r MutableBoolean bool = (MutableBoolean) stack.pop();\r if (bool.booleanValue()) {\r try {\r writeIndent();\r } catch (Throwable t) {\r }\r }\r try {\r os.write("</");\r os.write(tag);\r os.write(">");\r } catch (Throwable t) {\r }\r if (indentLevel == 0) {\r try {\r os.write(CRLF);\r } catch (Throwable t) {\r }\r }\r } else {\r flushAttributes(true);\r indentLevel--;\r }\r }\r\r public void endTag(QName tag) throws java.security.InvalidParameterException {\r if (attributesFlushed) {\r indentLevel--;\r MutableBoolean bool = (MutableBoolean) stack.pop();\r if (bool.booleanValue()) {\r try {\r writeIndent();\r } catch (Throwable t) {\r }\r }\r try {\r os.write("</");\r if (tag.getPrefix() != null && tag.getPrefix().length() > 0) {\r os.write(tag.getPrefix());\r os.write(":");\r }\r os.write(tag.getLocalPart());\r os.write(">");\r } catch (Throwable t) {\r }\r\r if (indentLevel == 0) {\r try {\r os.write(CRLF);\r } catch (Throwable t) {\r }\r }\r\r } else {\r flushAttributes(true);\r indentLevel--;\r }\r String ns = tag.getPrefix().concat(":").concat(tag.getNamespaceURI());\r String pushed = nsStack.pop();\r if (ns.equals(pushed)) {\r nsCtx.removeMapping(tag.getPrefix());\r }\r }\r\r /**\r * writes attributes to writer. Adds <code>/></code> if <code>close</code>,\r * and just <code>></code> otherwise.\r * @param close boolean\r */\r private void flushAttributes(boolean close) {\r if (!attributesFlushed) {\r for (Attribute attr : attributes) {\r try {\r os.write(attr.toString(escaper));\r } catch (Throwable t) {\r }\r }\r attributesFlushed = true;\r try {\r if (close) {\r os.write("/>");\r } else {\r os.write(">");\r }\r } catch (Throwable t) {\r }\r }\r }\r\r public void addCData(String cData) {\r flushAttributes(false);\r try{\r os.write("<![CDATA[");\r os.write(cData);\r os.write("]]>");\r } catch(IOException ex) {\r // TODO, maybe\r }\r }\r\r /**\r * Class initialization method. Called by all constructors.\r * If you override this method, do not forget to add <code>super.init()</code>\r * in your code.\r */\r private void init() throws RuntimeException {\r String osEncoding = fmtEncoding(os.getEncoding());\r if(!osEncoding.equals(fmtEncoding(encoding))) {\r logger.debug("compare "+osEncoding+" to "+fmtEncoding(encoding));\r throw new RuntimeException("Can not create an " + encoding + "-XmlOutputter on a " + os.getEncoding() + "-OutputStreamWritter");\r }\r attributes = new Vector<Attribute>();\r stack = new Stack<MutableBoolean>();\r writeStarted = true;\r escaper = CharacterEscaperFactory.getCharacterEscaper(encoding);\r nsCtx = new NamespaceContextImpl();\r nsStack = new Stack<String>();\r try {\r os.write("<?xml version=\"1.0\" encoding=\"");\r os.write(encoding);\r os.write("\"?");\r } catch (Throwable t) {\r }\r }\r\r private static String fmtEncoding(String encoding) {\r StringBuilder sb = new StringBuilder();\r for(char c:encoding.toCharArray()) {\r if('A'<=c && c<='Z') sb.append(c);\r if('0'<=c && c<='9') sb.append(c);\r if('a'<=c && c<='z') sb.append(Character.toUpperCase(c));\r }\r return sb.toString();\r }\r\r /**\r * An easy way to define an custom indent string.\r * @param s java.lang.String\r */\r public void setIndentStr(String s) {\r indentStr = s;\r }\r\r /**\r * Opens a new Tag.\r * @param tag java.lang.String\r */\r public void startTag(String tag) {\r flushAttributes(false);\r attributesFlushed = false;\r attributes.removeAllElements();\r try {\r writeIndent();\r os.write("<");\r os.write(tag);\r indentLevel++;\r if (!stack.isEmpty()) {\r ((MutableBoolean) stack.peek()).setValue(true);\r }\r } catch (Throwable t) {\r }\r stack.push(new MutableBoolean(false));\r }\r\r public void startTag(QName tag) {\r flushAttributes(false);\r attributesFlushed = false;\r attributes.removeAllElements();\r try {\r writeIndent();\r os.write("<");\r if (tag.getPrefix() != null && tag.getPrefix().length() > 0) {\r os.write(tag.getPrefix());\r os.write(":");\r }\r os.write(tag.getLocalPart());\r Iterator it = nsCtx.getPrefixes(tag.getNamespaceURI());\r if (it == null) {\r os.write(" xmlns");\r if (tag.getPrefix() != null && tag.getPrefix().length() > 0) {\r os.write(":");\r os.write(tag.getPrefix());\r }\r os.write("=\"");\r os.write(tag.getNamespaceURI());\r os.write("\"");\r nsCtx.addMapping(tag.getPrefix(), tag.getNamespaceURI());\r nsStack.push(tag.getPrefix().concat(":").concat(tag.getNamespaceURI()));\r } else {\r nsStack.push(null);\r }\r indentLevel++;\r if (!stack.isEmpty()) {\r ((MutableBoolean) stack.peek()).setValue(true);\r }\r } catch (Throwable t) {\r }\r stack.push(new MutableBoolean(false));\r }\r\r /**\r * Writes the needed indentation.\r */\r public void writeIndent() throws IOException {\r os.write(CRLF);\r for (int i = 0; i < indentLevel; i++) {\r os.write(indentStr);\r }\r }\r\r public void close() throws IOException {\r os.flush();\r os.close();\r }\r\r public OutputStreamWriter getWriter() {\r return os;\r }\r}\r\r
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright
+ * 2005 axYus - www.axyus.com
+ * 2005 C.Marchand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.cp.utils.xml.marshal;
+
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.Stack;
+
+import javax.xml.namespace.QName;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * This class is the DefaultHandler used to construct a <code>XmlMarshallable</code> structure.
+ * <p>License : LGPL
+ * @author Christophe MARCHAND
+ */
+public class XmlUnMarshaller extends DefaultHandler {
+
+ /**
+ * The mapping between tags and classes to instanciate.
+ */
+ private HashMap<QName, Class> mapping = null;
+ /**
+ * The constructed object.
+ */
+ private XmlMarshallable marshallable = null;
+ private XmlMarshallable dataToChange = null;
+ /**
+ * The stack of <code>XmlMarshallable</code> objects.
+ */
+ private Stack<XmlMarshallable> stack = null;
+
+ /**
+ * Constructs a new <code>XmlUnMarshaller</code> on this
+ * <code>mapping</code>.<br><b>WARNING :</b>
+ * You must create your HashMap with correct initial size
+ * and correct loadFactor to increase performance.
+ * <br><b>WARNING :</b> <code>mapping</code> must
+ * not be modified by a concurrent thread than the one where
+ * this <code>XmlUnMarshaller</code> runs, or results are
+ * unpredictible.
+ */
+ public XmlUnMarshaller(HashMap<QName, Class> mapping) {
+ super();
+ this.mapping = mapping;
+ stack = new Stack<XmlMarshallable>();
+ }
+
+ public void setDataToChange(XmlMarshallable data) {
+ this.dataToChange = data;
+ }
+
+ /**
+ * Receive notification of character data inside an element.
+ * @param ch char[]
+ * @param start int
+ * @param length int
+ * @exception org.xml.sax.SAXException The exception description.
+ */
+ @Override
+ public void characters(char[] ch, int start, int length) throws org.xml.sax.SAXException {
+ XmlMarshallable m = stack.peek();
+ String s = new String(ch, start, length);
+ // FIXME: enhance this for performance
+ if (s.trim().length() > 0) {
+ m.addCharacterData(s);
+ }
+ }
+
+ /**
+ * Receive notification of the end of an element.
+ * @param uri java.lang.String
+ * @param localName java.lang.String
+ * @param qName java.lang.String
+ * @exception org.xml.sax.SAXException The exception description.
+ */
+ @Override
+ public void endElement(String uri, String localName, String qName) throws org.xml.sax.SAXException {
+ XmlMarshallable m = stack.pop();
+ if (stack.empty()) {
+ marshallable = m;
+ } else {
+ XmlMarshallable parent = stack.peek();
+ parent.addChild(m, getQName(uri, localName, qName));
+ }
+ }
+
+ /**
+ * Returns the constructed object.
+ * @return com.labodev.xml.XmlMarshallable
+ */
+ public XmlMarshallable getMarshallable() {
+ return marshallable;
+ }
+
+ /**
+ * Returns the name, qualified or not.
+ * @return java.lang.String
+ * @param uri java.lang.String
+ * @param localName java.lang.String
+ * @param qName java.lang.String
+ */
+ protected static QName getQName(String uri, String localName, String qName) {
+ return new QName(uri, localName);
+ }
+
+ /**
+ * Receive notification of the start of an element.
+ * @param uri java.lang.String
+ * @param localName java.lang.String
+ * @param qName java.lang.String
+ * @param atts org.xml.sax.Attributes
+ * @exception org.xml.sax.SAXException The exception description.
+ */
+ @Override
+ public void startElement(String uri, String localName, String qName, org.xml.sax.Attributes atts) throws org.xml.sax.SAXException {
+ QName tag = getQName(uri, localName, qName);
+ Class clazz = (Class) mapping.get(tag);
+ if (clazz == null) {
+ throw new SAXException("Unknown mapping for tag <" + tag + ">.");
+ }
+ try {
+ XmlMarshallable m = null;
+ XmlMarshallable current = (!stack.isEmpty() ? stack.peek() : null);
+ if (current != null) {
+ m = current.getChildToModify(uri, localName, qName, atts);
+ } else {
+ if (dataToChange != null && dataToChange.getQName().equals(new QName(uri, localName))) {
+ m = dataToChange;
+ }
+ }
+ if (m == null) {
+ Constructor c = clazz.getConstructor(new Class[]{QName.class});
+ m = (XmlMarshallable) c.newInstance(new Object[]{tag});
+ }
+ XmlMarshallable m2 = m.getAttributes(new XmlAttributes(atts));
+ m2 = (m2 == null) ? m : m2;
+ stack.push(m2);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new SAXException(ex);
+ }
+ }
+ public HashMap<QName, Class> getMapping() { return mapping; }
+}
--- /dev/null
+/*
+ * Copyright
+ * 2008 axYus - www.axyus.com
+ * 2008 c.Marhcand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.cp.utils.xml.marshal.escapers;
+
+import fr.gouv.finances.cp.utils.xml.marshal.CharacterEscaper;
+
+/**
+ *
+ * @author chm
+ */
+public class DefaultCharacterEscaper implements CharacterEscaper {
+
+ public DefaultCharacterEscaper() {
+ super();
+ }
+
+ public String escapeChar(char ch) {
+ switch(ch) {
+ case '<': return "<";
+ case '>': return ">";
+ case '&': return "&";
+ case '"': return """;
+ }
+ return String.valueOf(ch);
+ }
+
+ public String escapeString(String s) {
+ if(s==null) return null;
+ StringBuilder sb = new StringBuilder();
+ for(char c:s.toCharArray()) {
+ sb.append(escapeChar(c));
+ }
+ return sb.toString();
+ }
+
+}
--- /dev/null
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package fr.gouv.finances.cp.utils.xml.marshal.escapers;
+
+/**
+ *
+ * @author chm
+ */
+public class ISO88591Escaper extends DefaultCharacterEscaper {
+
+ public ISO88591Escaper() {
+ super();
+ }
+
+ @Override
+ public String escapeChar(char ch) {
+ switch(ch) {
+/* case '°': return "°";
+ case 'À': return "À";
+ case 'Á': return "Á";
+ case 'Â': return "Â";
+ case 'Ã': return "Ã";
+ case 'Ä': return "Ä";
+ case 'Å': return "Å";
+ case 'Æ': return "Æ";
+ case 'Ç': return "Ç";
+ case 'È': return "È";
+ case 'É': return "É";
+ case 'Ê': return "Ê";
+ case 'Ë': return "Ë";
+ case 'Ì': return "Ì";
+ case 'Í': return "Í";
+ case 'Î': return "Î";
+ case 'Ï': return "Ï";
+ case 'Ò': return "Ò";
+ case 'Ó': return "Ó";
+ case 'Ô': return "Ô";
+ case 'Õ': return "Õ";
+ case 'Ö': return "Ö";
+ case '×': return "×";
+ case 'Ø': return "Ø";
+ case 'Ù': return "Ù";
+ case 'Ú': return "Ú";
+ case 'Û': return "Û";
+ case 'Ü': return "Ü";
+ case 'Ý': return "Ý";
+ case 'à': return "à";
+ case 'á': return "á";
+ case 'â': return "â";
+ case 'ã': return "ã";
+ case 'ä': return "ä";
+ case 'å': return "å";
+ case 'æ': return "æ";
+ case 'ç': return "ç";
+ case 'è': return "è";
+ case 'é': return "é";
+ case 'ê': return "ê";
+ case 'ë': return "ë";
+ case 'ì': return "ì";
+ case 'í': return "í";
+ case 'î': return "î";
+ case 'ï': return "ï";
+ case 'ð': return "ð";
+ case 'ñ': return "ñ";
+ case 'ò': return "ò";
+ case 'ó': return "ó";
+ case 'ô': return "ô";
+ case 'õ': return "õ";
+ case 'ö': return "ö";
+ case '÷': return "÷";
+ case 'ø': return "ø";
+ case 'ù': return "ù";
+ case 'ú': return "ú";
+ case 'û': return "û";
+ case 'ü': return "ü";
+ case 'ý': return "ý";
+ case 'þ': return "þ";
+ case 'ÿ': return "ÿ";
+ case '?': return "œ";*/
+// case '?': return "Œ";
+ }
+ return super.escapeChar(ch);
+ }
+}
--- /dev/null
+/*
+ * Copyright
+ * 2008 axYus - www.axyus.com
+ * 2008 c.Marhcand - christophe.marchand@axyus.com
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package fr.gouv.finances.cp.utils.xml.marshal.escapers;
+
+/**
+ *
+ * @author chm
+ */
+public class IdenticalEscaper extends DefaultCharacterEscaper {
+ public IdenticalEscaper() {
+ super();
+ }
+
+}
--- /dev/null
+/*
+ *
+ * Copyright
+ * 2009 axYus - www.axyus.com
+ * 2009 Christophe Marchand <christophe.marchand@axyus.com>
+ *
+ * This file is part of XEMELIOS.
+ *
+ * XEMELIOS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * XEMELIOS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with XEMELIOS; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+package fr.gouv.finances.cp.utils.xml.marshal.escapers;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import javax.xml.XMLConstants;
+
+/**
+ *
+ * @author Christophe Marchand <christophe.marchand@axyus.com>
+ */
+public class NamespaceContextImpl {
+ private Hashtable<String,String> prefixToUri = null;
+ private Hashtable<String,ArrayList<String>> uriToPrefix = null;
+ private ArrayList<NsMapping> mappings = null;
+
+ /** Creates a new instance of NamespaceContextImpl */
+ public NamespaceContextImpl() {
+ super();
+ prefixToUri = new Hashtable<String,String>();
+ uriToPrefix = new Hashtable<String,ArrayList<String>>();
+ mappings = new ArrayList<NsMapping>();
+ }
+ public void addMapping(String prefix, String uri) {
+ if(prefix==null || uri==null) return;
+ prefixToUri.put(prefix,uri);
+ ArrayList<String> prefixes = uriToPrefix.get(uri);
+ if(prefixes==null) {
+ prefixes = new ArrayList<String>();
+ uriToPrefix.put(uri,prefixes);
+ }
+ prefixes.add(prefix);
+ Collections.sort(prefixes);
+ mappings.add(new NsMapping(prefix,uri));
+ }
+ public void removeMapping(String prefix) {
+ String uri = prefixToUri.remove(prefix);
+ if(uri!=null) {
+ ArrayList<String> prefixes = uriToPrefix.get(uri);
+ prefixes.remove(prefix);
+ mappings.remove(prefix);
+ }
+ }
+
+ public String getNamespaceURI(String prefix) {
+ String ret = prefixToUri.get(prefix);
+ return ret;
+ }
+
+ public String getPrefix(String namespaceURI) {
+ String ret = null;
+ if(namespaceURI==null) throw new IllegalArgumentException("namespaceURI can not be null");
+ else if(XMLConstants.XML_NS_PREFIX.equals(namespaceURI)) {
+ ret = XMLConstants.XML_NS_URI;
+ } else if(XMLConstants.XMLNS_ATTRIBUTE.equals(namespaceURI)) {
+ ret = XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
+ }
+ ArrayList<String> prefixes = uriToPrefix.get(namespaceURI);
+ if(prefixes!=null) {
+ ret = prefixes.get(0);
+ }
+ return ret;
+ }
+
+ public Iterator getPrefixes(String namespaceURI) {
+ if(namespaceURI==null) throw new IllegalArgumentException("namespaceURI must not be null");
+ ArrayList<String> prefixes = uriToPrefix.get(namespaceURI);
+ if(prefixes!=null) {
+ return prefixes.iterator();
+ } else if(XMLConstants.XML_NS_PREFIX.equals(namespaceURI)) {
+ return new StringIterator<String>(XMLConstants.XML_NS_URI);
+ } else if(XMLConstants.XMLNS_ATTRIBUTE.equals(namespaceURI)) {
+ return new StringIterator<String>(XMLConstants.XMLNS_ATTRIBUTE_NS_URI);
+ }
+ return null;
+ }
+ public ArrayList<NsMapping> getMappings() {
+ return mappings;
+ }
+
+ public static class NsMapping {
+ String prefix, uri;
+ boolean written = false;
+ public NsMapping(String prefix,String uri) {
+ super();
+ this.prefix = prefix;
+ this.uri = uri;
+ }
+ public boolean isWritten() { return written; }
+ public void setWritten() { written = true; }
+ public boolean equals(Object o) {
+ if(o instanceof NsMapping) {
+ NsMapping other = (NsMapping)o;
+ return other.prefix.equals(this.prefix);
+ } else if(o instanceof String) {
+ return prefix.equals((String)o);
+ }
+ return false;
+ }
+ public String getPrefix() { return prefix; }
+ public String getUri() { return uri; }
+ }
+ @SuppressWarnings("hiding")
+ private class StringIterator<String> implements Iterator {
+ private final String data;
+ private boolean answered = false;
+ public StringIterator(String data) {
+ this.data=data;
+ }
+ public boolean hasNext() { return !answered; }
+ public String next() {
+ if(answered) throw new NoSuchElementException();
+ answered=true;
+ return data;
+ }
+ public void remove() {
+ throw new UnsupportedOperationException("can not remove !");
+ }
+ }
+
+}
--- /dev/null
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package fr.gouv.finances.cp.utils.xml.marshal.escapers;
+
+/**
+ *
+ * @author chm
+ */
+public class UTF8Escaper extends DefaultCharacterEscaper {
+
+ public UTF8Escaper() {
+ super();
+ }
+
+ @Override
+ public String escapeChar(char ch) {
+ switch (ch) {
+ case '?': return "€";
+// case '?': return "Œ";
+// case '?': return "œ";
+ case '°': return "°";
+ case 'À': return "À";
+ case 'Á': return "Á";
+ case 'Â': return "Â";
+ case 'Ã': return "Ã";
+ case 'Ä': return "Ä";
+ case 'Å': return "Å";
+ case 'Æ': return "Æ";
+ case 'Ç': return "Ç";
+ case 'È': return "È";
+ case 'É': return "É";
+ case 'Ê': return "Ê";
+ case 'Ë': return "Ë";
+ case 'Ì': return "Ì";
+ case 'Í': return "Í";
+ case 'Î': return "Î";
+ case 'Ï': return "Ï";
+ case 'Ð': return "Ð";
+ case 'Ñ': return "Ñ";
+ case 'Ò': return "Ò";
+ case 'Ó': return "Ó";
+ case 'Ô': return "Ô";
+ case 'Õ': return "Õ";
+ case 'Ö': return "Ö";
+ case '×': return "×";
+ case 'Ø': return "Ø";
+ case 'Ù': return "Ù";
+ case 'Ú': return "Ú";
+ case 'Û': return "Û";
+ case 'Ü': return "Ü";
+ case 'Ý': return "Ý";
+ case 'Þ': return "Þ";
+ case 'ß': return "ß";
+ case 'à': return "à";
+ case 'á': return "á";
+ case 'â': return "â";
+ case 'ã': return "ã";
+ case 'ä': return "ä";
+ case 'å': return "å";
+ case 'æ': return "æ";
+ case 'ç': return "ç";
+ case 'è': return "è";
+ case 'é': return "é";
+ case 'ê': return "ê";
+ case 'ë': return "ë";
+ case 'ì': return "ì";
+ case 'í': return "í";
+ case 'î': return "î";
+ case 'ï': return "ï";
+ case 'ð': return "ð";
+ case 'ñ': return "ñ";
+ case 'ò': return "ò";
+ case 'ó': return "ó";
+ case 'ô': return "ô";
+ case 'õ': return "õ";
+ case 'ö': return "ö";
+ case '÷': return "÷";
+ case 'ø': return "ø";
+ case 'ù': return "ù";
+ case 'ú': return "ú";
+ case 'û': return "û";
+ case 'ü': return "ü";
+ case 'ý': return "ý";
+ case 'þ': return "þ";
+ case 'ÿ': return "ÿ";
+// case '?': return "Ā";
+// case '?': return "ā";
+// case '?': return "Ă";
+// case '?': return "ă";
+// case '?': return "Ą";
+// case '?': return "ą";
+// case '?': return "Ć";
+// case '?': return "ć";
+// case '?': return "Ĉ";
+// case '?': return "ĉ";
+// case '?': return "Ċ";
+// case '?': return "ċ";
+// case '?': return "Č";
+// case '?': return "č";
+// case '?': return "Ď";
+// case '?': return "ď";
+// case '?': return "Đ";
+// case '?': return "đ";
+// case '?': return "Ē";
+// case '?': return "ē";
+// case '?': return "Ĕ";
+// case '?': return "ĕ";
+// case '?': return "Ė";
+// case '?': return "ė";
+// case '?': return "Ę";
+// case '?': return "ę";
+// case '?': return "Ě";
+// case '?': return "ě";
+// case '?': return "Ĩ";
+// case '?': return "ĩ";
+// case '?': return "Ī";
+// case '?': return "ī";
+// case '?': return "Ĭ";
+// case '?': return "ĭ";
+// case '?': return "Į";
+// case '?': return "į";
+// case '?': return "İ";
+// case '?': return "ı";
+// case '?': return "Ō";
+// case '?': return "ō";
+// case '?': return "Ŏ";
+// case '?': return "ŏ";
+// case '?': return "Ő";
+// case '?': return "ő";
+// case '?': return "Œ";
+// case '?': return "œ";
+// case '?': return "Ũ";
+// case '?': return "ũ";
+// case '?': return "Ū";
+// case '?': return "ū";
+// case '?': return "Ŭ";
+// case '?': return "ŭ";
+// case '?': return "Ů";
+// case '?': return "ů";
+// case '?': return "Ű";
+// case '?': return "ű";
+// case '?': return "Ų";
+// case '?': return "Ų";
+// case '?': return "Ŷ";
+// case '?': return "ŷ";
+// case '?': return "Ÿ";
+ }
+ return super.escapeChar(ch);
+ }
+}
--- /dev/null
+Manifest-version: 1.0
+Jar-Version: @version@
+Jar-Content: @name@
+