From: <opa...@us...> - 2008-08-08 15:20:23
|
Revision: 3742 http://fudaa.svn.sourceforge.net/fudaa/?rev=3742&view=rev Author: opasteur Date: 2008-08-08 15:20:32 +0000 (Fri, 08 Aug 2008) Log Message: ----------- Added Paths: ----------- trunk/fudaa_devel/dodico/src/org/fudaa/dodico/hydraulique1d/metier/DeserializerHandlerVersion05.java Added: trunk/fudaa_devel/dodico/src/org/fudaa/dodico/hydraulique1d/metier/DeserializerHandlerVersion05.java =================================================================== --- trunk/fudaa_devel/dodico/src/org/fudaa/dodico/hydraulique1d/metier/DeserializerHandlerVersion05.java (rev 0) +++ trunk/fudaa_devel/dodico/src/org/fudaa/dodico/hydraulique1d/metier/DeserializerHandlerVersion05.java 2008-08-08 15:20:32 UTC (rev 3742) @@ -0,0 +1,596 @@ +/** + * @file Handler.java + * @creation 08 aout 2008 + * @modification $Date: 2007-11-30 16:04:17 $ + * @license GNU General Public License 2 + * @copyright (c)1998-2001 CETMEF 2 bd Gambetta F-60231 Compiegne + * @mail de...@fu... + */ +package org.fudaa.dodico.hydraulique1d.metier; + +import org.fudaa.dodico.boony.BoonyBase64; +import org.fudaa.dodico.boony.BoonyDeserializerHandler; +import org.fudaa.dodico.boony.BoonyDeserializerHandlerInterface; +import org.fudaa.dodico.boony.BoonyLib; +import org.fudaa.dodico.boony.BoonyXmlDeserializer; + +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Stack; +import java.util.TreeMap; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; + +import com.memoire.fu.FuLog; + +import org.fudaa.dodico.boony.BoonyXmlDeserializer.CorbaEnum; +import java.util.StringTokenizer; +import gnu.trove.TDoubleArrayList; + + + +/** + * Deserialisation du format 0.5 Mascaret. + * @author opasteur + * @version $Id: DeserializerHandlerVersion05.java,v 1.3 2007-11-30 16:04:17 jm_lacombe Exp $ + */ +class DeserializerHandlerVersion05 implements ContentHandler, BoonyDeserializerHandlerInterface { + + private final Stack arrays_; + + // Map options_ = new Properties(); + private static int tailleStringBuffer = 32; + private StringBuffer data_ = new StringBuffer(tailleStringBuffer); + private Map dobjetIObjet_; + private final Stack fields_; + protected boolean isCorba_ = true; + + private boolean isTypeArrayByte_; + private boolean isTypeArrayDouble_; + protected final Object nullValue_ = new Object(); + final Map obj_; // (id,obj) + + private final Stack objects_; + private final Map ref_; // (obj,id) + + private String singleClass_; + private List singles_; + + private final Map typeClass_; + + private final Map classNameTypeData_ = new TreeMap(); + + /** + * @param _containsCorbaObject true si des objets corba sont utilisees + */ + public DeserializerHandlerVersion05(final boolean _containsCorbaObject) { + isCorba_ = _containsCorbaObject; + ref_ = new HashMap(); + obj_ = new HashMap(); + objects_ = new Stack(); + fields_ = new Stack(); + arrays_ = new Stack(); + singles_ = new ArrayList(); + typeClass_ = new TreeMap(); + typeClass_.put("Bool", Boolean.class); + typeClass_.put("boolean", Boolean.TYPE); + typeClass_.put("Char", Character.class); + typeClass_.put("char", Character.TYPE); + typeClass_.put("byte", Byte.TYPE); + typeClass_.put("short", Short.TYPE); + typeClass_.put("Int", Integer.class); + typeClass_.put("int", Integer.TYPE); + typeClass_.put("long", Long.TYPE); + typeClass_.put("Float", Float.class); + typeClass_.put("float", Float.TYPE); + typeClass_.put("Double", Double.class); + typeClass_.put("double", Double.TYPE); + typeClass_.put("void", Void.TYPE); + typeClass_.put("String", String.class); + + } + + private String getNewClassName(final String _c) throws ClassNotFoundException { + + + final String PK_FUDAA_FUDAA_METIER="org.fudaa.fudaa.hydraulique1d.metier."; + String newpk; + int i=_c.lastIndexOf("."); + String oldpk=_c.substring(0,i+1); + String oldname=_c.substring(i+1, _c.length()); + + + if (oldpk.startsWith(PK_FUDAA_FUDAA_METIER)) { + newpk="org.fudaa.dodico.hydraulique1d.metier."; + if (PK_FUDAA_FUDAA_METIER.length()<oldpk.length()) { + newpk+=oldpk.substring(PK_FUDAA_FUDAA_METIER.length()); + } + } + // Aucun changement. + else { + return _c; + } + + //System.err.println("getNewClassName "+newpk+oldname); + return newpk+oldname; + } + + private Class getClass(final String _className) throws ClassNotFoundException { + + String newClassName=getNewClassName(_className); + + TypeData d = (TypeData) classNameTypeData_.get(newClassName); + if (d == null) { + d = new TypeData(); + classNameTypeData_.put(newClassName, d); + } + if (d.c_ == null) { + d.c_ = Class.forName(newClassName); + } + return d.c_; + } + + protected Field getField(final Class _c, final String _name) { + + final String s = _c.getName(); + //System.err.println("getField classNameTypeData_ "+classNameTypeData_+_name); + TypeData d = (TypeData) classNameTypeData_.get(s); + if (d == null) { + d = new TypeData(); + d.c_ = _c; + classNameTypeData_.put(s, d); + } + Field f = (Field) d.nomField_.get(_name); + if (f == null) { + f = searchField(_c, _name); + d.nomField_.put(_name, f); + } + return f; + } + + protected Object getFinalObjectToSet(final Object _dobjet) { + if (!isCorba_) { + return _dobjet; + } + if (dobjetIObjet_ == null) { + return _dobjet; + } + Object r = dobjetIObjet_.get(_dobjet); + if (r == null) { + r = _dobjet; + } + return r; + } + + protected final Object getObj(final String _id) { + if ("null".equals(_id)) { + return null; + } + + return obj_.get(_id); + } + + protected Class normalize(final String _type) { + Class r = (Class) typeClass_.get(_type); + if (r == null) { + try { + r = getClass(_type); + } catch (final ClassNotFoundException ex) { + BoonyLib.warning("class not found for " + _type); + } + } + if (r == null) { + r = Object.class; + } + return r; + } + + + + + + protected void saveCorbaObject(final Object _dobjet) { + if (!isCorba_) { + return; + } + if (dobjetIObjet_ == null) { + dobjetIObjet_ = new HashMap(); + } + if (!dobjetIObjet_.containsKey(_dobjet)) { + // @todo A voir peut \xEAtre... +// dobjetIObjet_.put(_dobjet, BoonyLib.buildStubFromDObject(_dobjet)); + } + } + + /** + * Recherche par recursivite les champs dans une classe. + * + * @param _c la classe en question + * @param _name le nom du champ a recherche + * @return null si pas de champ trouve + */ + protected Field searchField(final Class _c, final String _name) { + if (_c == null) { + return null; + } + final Field[] fs = _c.getDeclaredFields(); + if (fs != null) { + for (int i = fs.length - 1; i >= 0; i--) { + if (fs[i].getName().equals(_name)) { + return fs[i]; + } + } + } + return searchField(_c.getSuperclass(), _name); + } + + public void characters(final char[] _ch, final int _start, final int _length) throws SAXException { + data_.append(_ch, _start, _length); + } + + public void endDocument() throws SAXException {} + + public void endElement(final String _namespaceURI, final String _localName, final String _element) throws SAXException { + if (isTypeArrayByte_ || isTypeArrayDouble_) { + endElementTypeArray(); + return; + } + final String data = data_.toString().trim(); + + /* if (data.length() > 0) { + trace(data); + }*/ + if ("yapod".equals(_element)) { + // la base + + } else if (("object".equals(_element)) || ("iobject".equals(_element))) { + Object o = objects_.pop(); + if (o instanceof CorbaEnum) { + final Object id = ref_.get(o); + + Object n = ((CorbaEnum) o).build(); + if (n == null) { + FuLog.error("DBO: ### failed to build enum "); + n = nullValue_; + } + o = n; + ref_.put(o, id); + obj_.put(id, o); + } + } else if ("field".equals(_element)) { + final Field f = (Field) fields_.pop(); + + if (singles_.size() != 1) { + BoonyLib.warning("singles.size!=1 (" + singles_.size() + ")"); + + } + Object r = singles_.get(0); + if (r == nullValue_) { + r = null; + + } + if (f != null) { + try { + final Object oToSet = getFinalObjectToSet(r); + f.set(objects_.peek(), oToSet); + } catch (final IllegalAccessException ex) { + FuLog.error("### no access to field " + f.getName() + " in " + objects_.peek().getClass()); + } + } + + singles_ = (List) fields_.pop(); + } else if ("null".equals(_element)) { + singles_.add(nullValue_); + } else if ("single".equals(_element)) { + endElementSingle(data); + } else if ("array".equals(_element)) { + endElementArray(); + } else if (!"reference".equals(_element)) { + BoonyLib.warning("unreconized tag: " + _element); + } + if (data_.length() > tailleStringBuffer) { +// data_ = null; + //a laisser ? + // System.gc(); + data_ = new StringBuffer(tailleStringBuffer); + } + } + + private void endElementArray() { + final Object a = arrays_.pop(); + final int l = Array.getLength(a); + if (singles_.size() != l) { + BoonyLib.warning("singles.size!=array.length (" + singles_.size() + ")"); + + } + for (int i = 0; i < l; i++) { + Object r = singles_.get(i); + if (r == nullValue_) { + r = null; + } + Array.set(a, i, getFinalObjectToSet(r)); + } + + singles_ = (List) arrays_.pop(); + singles_.add(a); + } + + private void endElementSingle(final String _data) { + Object o = nullValue_; + final Class c = normalize(singleClass_); + + if (c == Boolean.class) { + o = Boolean.valueOf(_data); + } else if (c == Character.class) { + try { + o = new Character((char) new Integer(_data).intValue()); + } catch (final NumberFormatException ex) { + BoonyLib.warning("invalid char value " + _data); + } + } else if (c == String.class) { + o = BoonyLib.fromXmlCharset(_data); + } else { // Number + try { + final Constructor x = c.getDeclaredConstructor(new Class[] { String.class }); + x.setAccessible(true); + // YapodLib.setAccessible(x, true); + o = x.newInstance(new Object[] { _data }); + } catch (final NoSuchMethodException ex) { + BoonyLib.warning("constructor(string) not found for class " + singleClass_); + } catch (final IllegalAccessException ex) { + BoonyLib.warning("constructor(string) not accessible " + singleClass_); + } catch (final InstantiationException ex) { + BoonyLib.warning("constructor(string) not instantiate " + singleClass_); + } catch (final InvocationTargetException ex) { + BoonyLib.warning("constructor(string) not target !" + singleClass_); + } + } + + // trace(o); + singles_.add(o); + } + + + + private void endElementTypeArray() { + if (isTypeArrayByte_) { + singles_.add(BoonyBase64.decode(data_.toString().getBytes())); + isTypeArrayByte_ = false; + } + else if (isTypeArrayDouble_) { + singles_.add(decodeArrayDouble(data_.toString())); + isTypeArrayDouble_ = false; + + } + if (data_.length() > tailleStringBuffer) { +// data_ = null; + // System.gc(); + data_ = new StringBuffer(tailleStringBuffer); + } + } + + private final static double[] decodeArrayDouble(final String _tab) { +// System.err.println("appel de decodeArrayDouble"); + final StringTokenizer stk = new StringTokenizer(_tab," "); + TDoubleArrayList liste = new TDoubleArrayList(_tab.length()/5); + while(stk.hasMoreElements()) { + liste.add(Double.parseDouble(stk.nextToken())); + } + return liste.toNativeArray(); + } + + public void endPrefixMapping(final String _prefix) throws SAXException {} + + public Object getFirstObject() { + if (singles_.size() == 0) { + throw new NoSuchElementException(); + } + Object r = singles_.get(0); + if (r == nullValue_) { + r = null; + } + singles_.remove(0); + return getFinalObjectToSet(r); + } + + public void ignorableWhitespace(final char[] _ch, final int _start, final int _length) throws SAXException {} + + public void processingInstruction(final String _target, final String _data) throws SAXException {} + + public void setDocumentLocator(final Locator _locator) {} + + public void skippedEntity(final String _name) throws SAXException {} + + public void startDocument() throws SAXException {} + + public void startElement(final String _namespaceURI, final String _toto, final String _element, final Attributes _atts) throws SAXException { + // public void startElement(String _element,AttributeList _atts) throws SAXException { + // trace(_element); + isTypeArrayByte_ = false; + if ("yapod".equals(_element)) {} else if (("object".equals(_element)) || (isCorba_ && ("iobject".equals(_element)))) { + final String type = _atts.getValue("type"); + final String id = _atts.getValue("id"); + Object o = nullValue_; + Class c = null; + + try { + c = getClass(type); + } catch (final ClassNotFoundException ex) { + BoonyLib.warning("class not found " + type); + } + + if (c != null) { + o = startCreateObject(type, o, c); + } + + if (id != null) { + startSaveObject(_element, id, o); + } + objects_.push(o); + } + + else if ("field".equals(_element)) { + startElementField(_atts); + } else if ("array-byte".equals(_element)) { + isTypeArrayByte_ = true; + } + else if ("array-double".equals(_element)) { + isTypeArrayDouble_ = true; + } + + /* + * else if("array-int".equals(_element)) { } + */ + else if ("null".equals(_element)) {} else if ("single".equals(_element)) { + singleClass_ = _atts.getValue("type"); + } else if ("array".equals(_element)) { + startElementArray(_atts); + } else if ("reference".equals(_element)) { + final String id = _atts.getValue("idref"); + + Object o = getObj(id); + if (o == null) { + o = nullValue_; + } + singles_.add(o); + } else { + BoonyLib.warning("unreconized tag: " + _element); + + // TMP @GDX + // if(!"".equals(data_.toString().trim())) + // warning("data should be empty: "+data_); + + // Slow on 1.4 + // data_.setLength(0); + // Change to: + } + data_ = new StringBuffer(tailleStringBuffer); + // options_.clear(); + } + + private void startElementArray(final Attributes _atts) { + final String type = _atts.getValue("type"); + final String id = _atts.getValue("id"); + final int length = Integer.parseInt(_atts.getValue("length")); + final int depth = Integer.parseInt(_atts.getValue("depth")); + + final Class c = normalize(type); + + final int[] dims = new int[depth]; + dims[0] = length; + final Object a = Array.newInstance(c, dims); + //trace(a); + + if (id != null) { + ref_.put(a, id); + obj_.put(id, a); + } + + arrays_.push(singles_); + arrays_.push(a); + singles_ = new ArrayList(10); + } + + private void startElementField(final Attributes _atts) { + + final String name = _atts.getValue("name"); + + final Object o = objects_.peek(); + final Class c = o.getClass(); + final Field f = getField(c, name); + if (f != null) { + f.setAccessible(true); + } + //trace(f); + + fields_.push(singles_); + fields_.push(f); + singles_ = new ArrayList(); + + /* if (f == null) { + FuLog.error("### field " + name + " removed in " + objects_.peek().getClass()); + }*/ + } + + private void startSaveObject(final String _element, final String _id, final Object _o) { + ref_.put(_o, _id); + obj_.put(_id, _o); + if (isCorba_ && "iobject".equals(_element)) { + saveCorbaObject(_o); + } + } + + private Object startCreateObject(final String _type, final Object _o, final Class _c) { + Object o = _o; + try { + final Constructor x = _c.getDeclaredConstructor(new Class[] {}); + x.setAccessible(true); + o = x.newInstance(new Object[] {}); + // trace(o); + } catch (final NoSuchMethodException ex) {} catch (final IllegalAccessException ex) {} catch (final InstantiationException ex) {} catch (final InvocationTargetException ex) {} + + // CORBA Enum ? + if (o == nullValue_) { + if (isCorba_ && isCorbaEnum(_c)) { + o = new CorbaEnum(_c); + // trace(o); + } + } + + if (o == nullValue_) { + BoonyLib.warning("default constructor not found for class " + _type); + } + return o; + } + + /** + * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String) + */ + public void startPrefixMapping(final String _prefix, final String _uri) throws SAXException {} + + /** + * Permet de suivre certains objet. + * + * @param _o l'objet a tracer + */ + /*public void trace(final Object _o) { + // try { System.err.println("Yapod XML trace : "+_o); } + // catch(Throwable th) { } + }*/ + + /** + * utilise une map interne pour enregistrer l'etat d'une classe. + * + * @param _c la classe a tester + * @return si corba enum + */ + public boolean isCorbaEnum(final Class _c) { + final String className = _c.getName(); + TypeData d = (TypeData) classNameTypeData_.get(className); + if (d == null) { + d = new TypeData(); + classNameTypeData_.put(className, d); + } + if (d.isCorbaEnum_ == null) { + d.isCorbaEnum_ = BoonyXmlDeserializer.isCorbaEnum(_c) ? Boolean.TRUE : Boolean.FALSE; + } + return d.isCorbaEnum_.booleanValue(); + } + + static class TypeData { + + Class c_; + Map nomField_ = new TreeMap(); + Boolean isCorbaEnum_; + } + } Property changes on: trunk/fudaa_devel/dodico/src/org/fudaa/dodico/hydraulique1d/metier/DeserializerHandlerVersion05.java ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |