Package org.gocha.xml

Source Code of org.gocha.xml.XMLDecoder

/*******************************************************************************
gocha.org-lib-java Библеотека общего назначения
(с) Камнев Георгий Павлович 2009 GPLv2

Данная программа является свободным программным обеспечением. Вы вправе
распространять ее и/или модифицировать в соответствии с условиями версии 2
либо по вашему выбору с условиями более поздней версии
Стандартной Общественной Лицензии GNU, опубликованной Free Software Foundation.

Мы распространяем данную программу в надежде на то, что она будет вам полезной,
однако НЕ ПРЕДОСТАВЛЯЕМ НА НЕЕ НИКАКИХ ГАРАНТИЙ,
в том числе ГАРАНТИИ ТОВАРНОГО СОСТОЯНИЯ ПРИ ПРОДАЖЕ
и ПРИГОДНОСТИ ДЛЯ ИСПОЛЬЗОВАНИЯ В КОНКРЕТНЫХ ЦЕЛЯХ.
Для получения более подробной информации ознакомьтесь
со Стандартной Общественной Лицензией GNU.

Вместе с данной программой вы должны были получить экземпляр
Стандартной Общественной Лицензии GNU.
Если вы его не получили, сообщите об этом в Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*******************************************************************************/

package org.gocha.xml;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.gocha.types.DefaultTypesConvertors;
import org.gocha.types.PropertyController;
import org.gocha.types.ToValueConvertor;
import org.gocha.types.TypesConverters;
import org.gocha.types.ValueController;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
* @author gocha
*/
public class XMLDecoder
{
    private static Map<String,Class> defTagMap = null;
    private static boolean debug = false;

    public static Map<String,Class> getDefaultTagMap()
    {
        if( defTagMap==null )
        {
            defTagMap = new HashMap<String, Class>();
        }

        return defTagMap;
    }

    private Map<String,Class> tagMap = null;

    public Map<String,Class> getTagMap()
    {
        if( tagMap==null )
        {
            tagMap = new HashMap<String, Class>();
            tagMap.putAll(getDefaultTagMap());
        }
        return tagMap;
    }

    private String keyMapAttribute = null;

    public String getKeyMapAttribute()
    {
        if( keyMapAttribute==null )keyMapAttribute = "key";
        return keyMapAttribute;
    }

    public void setKeyMapAttribute(String keyMapAttribute)
    {
        this.keyMapAttribute = keyMapAttribute;
    }

    private Class keyMapClass = String.class;

    public Class getKeyMapClass()
    {
        return keyMapClass;
    }

    public void setKeyMapClass(Class keyMapClass)
    {
        this.keyMapClass = keyMapClass;
    }

    private Map<Class,Map<String,CustomAttributeSetter>> customAttributeSet = null;

    public CustomAttributeSetter getAttributeSetter(Class cls,String attribute)
    {
        if( cls==null || attribute==null )return null;

        if( customAttributeSet==null )return null;
        if( !customAttributeSet.containsKey(cls) )return null;

        Map<String,CustomAttributeSetter> m = customAttributeSet.get(cls);
        if( m==null )return null;
        for( String att : m.keySet() )
        {
            if( att==null )continue;
            if( att.equalsIgnoreCase(attribute) )
                return m.get(att);
        }

        return null;
    }

    public void removeCustomAttribute(Class cls)
    {
        putAttributeSetter(cls, null, null);
    }

    public void removeCustomAttribute(Class cls,String attribute)
    {
        putAttributeSetter(cls, attribute, null);
    }

    public void putAttributeSetter(Class cls,String attribute,CustomAttributeSetter setter)
    {
        if( cls==null )return;
        if( attribute==null )
        {
            if( customAttributeSet==null )return;
            if( customAttributeSet.containsKey(cls) )
                customAttributeSet.remove(cls);
            return;
        }
        if( setter==null )
        {
            if( customAttributeSet==null )return;
            if( !customAttributeSet.containsKey(cls) )return;

            Map<String,CustomAttributeSetter> m = customAttributeSet.get(cls);
            if( m==null )return;

            ArrayList<String> toDel = new ArrayList<String>();
            for( String att : m.keySet() )
            {
                if( att==null )continue;
                if( att.equalsIgnoreCase(attribute) )toDel.add(att);
            }
            for( String k : toDel )m.remove(k);
            return;
        }

        if( customAttributeSet==null )
            customAttributeSet = new HashMap<Class, Map<String, CustomAttributeSetter>>();

        if( !customAttributeSet.containsKey(cls) )
            customAttributeSet.put(cls, new HashMap<String, CustomAttributeSetter>());

        Map<String,CustomAttributeSetter> m = customAttributeSet.get(cls);
        if( !m.containsKey(attribute.toLowerCase()) )
        {
            m.put(attribute.toLowerCase(), setter);
        }else{
            for( String k : m.keySet() )
            {
                if( k==null )continue;
                if( k.equalsIgnoreCase(attribute) )
                    m.put(k, setter);
            }
        }
    }

    public Object parseXML(String text) throws IOException, SAXException
    {
        if (text == null) {
            throw new IllegalArgumentException("text == null");
        }

        Document doc = XMLUtil.parseXML(text);
        if( doc!=null )return parse(doc);

        return null;
    }

    public Object parse(Document xmlDoc)
    {
        if (xmlDoc == null) {
            throw new IllegalArgumentException("xmlDoc == null");
        }

        Node docEl = xmlDoc.getDocumentElement();
        if( docEl!=null )
        {
            Object o = parse(docEl);
            return o;
        }

        return null;
    }

    public Object parse(Node xmlNode)
    {
        if (xmlNode == null) {
            throw new IllegalArgumentException("xmlNode == null");
        }

        if( xmlNode instanceof Element )
            return parse((Element)xmlNode);

        return null;
    }

    public Object parse(Element xmlElement)
    {
        if (xmlElement == null) {
            throw new IllegalArgumentException("xmlElement == null");
        }

        Object objTag = createObjectFromNode(xmlElement);
        if( objTag==null )return null;

        setAttributes(objTag, xmlElement);
        parseChildren(objTag, xmlElement);

        return objTag;
    }

    protected Object createObjectFromNode( Node xmlNode )
    {
        if (xmlNode == null) {
            throw new IllegalArgumentException("xmlNode == null )");
        }
        if(!(xmlNode instanceof org.w3c.dom.Element))return null;

        String name = xmlNode.getNodeName();
        if( name==null )return null;
        if( !getTagMap().containsKey(name.toLowerCase()) )return null;

        Class cls = getTagMap().get(name.toLowerCase());
        if( cls==null )return null;

        Object objTag = null;
        try {
            Object obj = cls.newInstance();
            objTag = obj;
        }
        catch (InstantiationException ex) {
            ex.printStackTrace();
        }
        catch (IllegalAccessException ex) {
            ex.printStackTrace();
        }

        onObjectCreated(objTag);

        return objTag;
    }

    protected void onObjectCreated(Object obj)
    {
    }

    protected void setAttributes( Object obj, Node node )
    {
        if( debug )System.out.println("set attributes to "+obj);

        if( !node.hasAttributes() )
        {
            onSettedAttributes(obj);
            return;
        }

        Map<String,ValueController> map1 = PropertyController.buildControllersMap(obj);
        Map<String,ValueController> map = new HashMap<String, ValueController>();
        for( String k : map1.keySet() )map.put(k.toLowerCase(), map1.get(k));

        NamedNodeMap nnm = node.getAttributes();
        if( nnm==null )
        {
            onSettedAttributes(obj);
            return;
        }

        int count = nnm.getLength();
        for( int i=0; i<count; i++ )
        {
            Node attr = nnm.item(i);

            String attrName = attr.getNodeName();
            String attrValue = attr.getNodeValue();

            setAttribute( obj, map, attrName, attrValue);
        }

        onSettedAttributes(obj);
    }

    protected void onSettedAttributes(Object obj)
    {
    }

    protected boolean customSetAttribute( Object obj, String attr, String value )
    {
        if( debug )System.out.println("custom set attribute "+attr+" = "+value);
        CustomAttributeSetter setter = getAttributeSetter(obj.getClass(), attr);
        if( setter!=null )
        {
            setter.set(obj, attr, value);
            return true;
        }
        if( debug )System.out.println("custom attr NOT setted");
        return false;
    }

    protected TypesConverters typesConverters = DefaultTypesConvertors.instance();

    public TypesConverters getTypesConvertors()
    {
        if( typesConverters==null )typesConverters = DefaultTypesConvertors.instance();
        return typesConverters;
    }

    public void setTypesConvertors(TypesConverters conv){
        typesConverters = conv;
    }

    protected void setAttribute( Object obj, Map<String,ValueController> vcMap, String attrName, String attrValue)
    {
        if( debug )System.out.println("set attribute "+attrName+" = "+attrValue);
        if( customSetAttribute(obj, attrName, attrValue) )
        {
            if( debug )System.out.println("custom attr setted");
            return;
        }else{
        }

        if( !vcMap.containsKey(attrName.toLowerCase()) )
        {
            if( debug )System.out.println("vcMap not has "+attrName.toLowerCase());
            return;
        }
        ValueController vc = vcMap.get(attrName.toLowerCase());

        ToValueConvertor conv = getTypesConvertors().toValueFor(vc.getType());

        if( conv==null )
            return;

        Object destValue = null;
        try
        {
            destValue = conv.convertToValue(attrValue);
            vc.setValue(destValue);

            if( debug )System.out.println("attr Setted");
        }
        catch(Throwable e)
        {
            e.printStackTrace();
            return;
        }
    }

    private Map<Class,CustomChildrenParser> customChildrenParsers = null;

    public CustomChildrenParser getChildrenParserForObject(Object obj)
    {
        if( customChildrenParsers==null )return null;
        if( obj==null )return null;

        Class cls = obj.getClass();
        if( !customChildrenParsers.containsKey(cls) )return null;

        CustomChildrenParser parser = customChildrenParsers.get(cls);
        return parser;
    }

    public void putChildrenParser(Class cls,CustomChildrenParser parser)
    {
        if( cls==null )return;
        if( parser==null )
        {
            if( customChildrenParsers==null )return;           
           
//            ArrayList<Class> toDel = new ArrayList<Class>();
//            for( Class c : customChildrenParsers.keySet() )
//            {
//                if( c==null )continue;
//                if( c.equals(cls) )
//                {
//                    toDel.add(c);
//                }
//            }
//
//            for( Class c : toDel )customChildrenParsers.remove(c);

            customChildrenParsers.remove(cls);
            return;
        }

        if( customChildrenParsers==null )
            customChildrenParsers = new HashMap<Class, CustomChildrenParser>();

        customChildrenParsers.put(cls, parser);
    }

    public void removeCustomChildrenParser(Class cls)
    {
        if( cls==null )return;
        putChildrenParser(cls, null);
    }

    protected boolean customParseChildren( Object parentObject, Node parentNode )
    {
        CustomChildrenParser parser = getChildrenParserForObject(parentObject);
        if( parser!=null )
        {
            parser.parse(parentObject, parentNode);
            return true;
        }

        return false;
    }

    protected void parseChildren( Object parentObject, Node parentNode )
    {
        if( customParseChildren(parentObject, parentNode) )
            return;

        if( !parentNode.hasChildNodes() )
        {
            onChildrenAdded(parentObject);
            return;
        }

        if( parentObject instanceof Collection )
        {
            parseChildrenList(parentObject, parentNode);
            return;
        }

        if( parentObject instanceof Map )
        {
            parseChildrenMap(parentObject, parentNode);
            return;
        }

        onChildrenAdded(parentObject);
    }

    protected void parseChildrenMap( Object parentObject, Node parentNode )
    {
        String keyAttr = getKeyMapAttribute();
        Class keyClass = getKeyMapClass();

        TypesConverters conv = DefaultTypesConvertors.instance();
        ToValueConvertor toValue = keyClass==null ? null : conv.toValueFor(keyClass);

        if( !parentNode.hasChildNodes() ||
            !(parentObject instanceof Map) ||
            keyAttr==null || keyAttr.length()<1 ||
            keyClass==null ||
            toValue==null
          )
        {
            onChildrenAdded(parentObject);
            return;
        }

        NodeList nl = parentNode.getChildNodes();

        int count = nl.getLength();
        for( int i=0; i<count; i++ )
        {
            Node childNode = nl.item(i);
            if( childNode==null )continue;
            if( !childNode.hasAttributes() )continue;

            Node keyNode = childNode.getAttributes().getNamedItem(keyAttr);
            if( keyNode==null )continue;

            String keyValueString = keyNode.getNodeValue();
            if( keyValueString==null )continue;

            try
            {
                Object keyObject = toValue.convertToValue(keyValueString);
                if( keyObject==null )continue;

                Object childObject = parse(childNode);
                if( childObject!=null )
                {
                    ((Map)parentObject).put(keyObject, childObject);
                }
            }
            catch(Throwable e)
            {
                e.printStackTrace();
            }
        }

        onChildrenAdded(parentObject);
    }

    protected void parseChildrenList( Object parentObject, Node parentNode )
    {
        if( !parentNode.hasChildNodes() )
        {
            onChildrenAdded(parentObject);
            return;
        }

        if( !(parentObject instanceof Collection) )
        {
            onChildrenAdded(parentObject);
            return;
        }

        NodeList nl = parentNode.getChildNodes();

        int count = nl.getLength();
        for( int i=0; i<count; i++ )
        {
            Node childNode = nl.item(i);

            Object childObject = parse(childNode);
            if( childObject!=null )
            {
                ((Collection)parentObject).add(childObject);
            }
        }

        onChildrenAdded(parentObject);
    }

    protected void onChildrenAdded(Object obj)
    {
    }
}
TOP

Related Classes of org.gocha.xml.XMLDecoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.