/*
 * Created on Jun 24, 2005
 */
package org.flexdock.docking.adapter;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

/**
 * @author Christopher Butler
 * @deprecated This class will become package-private.
 */
public class MappingReader {
    private static Log log = LogFactory.getLog(MappingReader.class);

    public static final String ADAPTER_KEY = "adapter";

    public static final String CLASS_KEY = "class";

    public static final String METHOD_KEY = "method";

    public static final String FLEXDOCK_KEY = "flexdock";

    public static final String CLIENT_KEY = "client";

    public AdapterMapping[] readMappings(Document mappingDoc) {
        if (mappingDoc == null)
            return new AdapterMapping[0];

        NodeList nodes = mappingDoc.getElementsByTagName(ADAPTER_KEY);
        ArrayList mappings = new ArrayList(nodes.getLength());

        for (int i = 0; i < nodes.getLength(); i++) {
            Element elem = (Element) nodes.item(i);
            String className = elem.getAttribute(CLASS_KEY);
            if (className != null) {
                AdapterMapping mapping = createMapping(elem);
                mapping.setClassName(className);
                mappings.add(mapping);
            }
        }

        return (AdapterMapping[]) mappings.toArray(new AdapterMapping[0]);
    }

    private AdapterMapping createMapping(Element adapterElem) {
        NodeList nodes = adapterElem.getElementsByTagName(METHOD_KEY);
        String className = adapterElem.getAttribute(CLASS_KEY);
        Properties p = new Properties();
        
        for (int i = 0, len = nodes.getLength(); i < len; i++) {
            Element elem = (Element) nodes.item(i);
            String key = elem.getAttribute(FLEXDOCK_KEY);
            String value = elem.getAttribute(CLIENT_KEY);
            if (key != null && value != null)
                p.setProperty(key, value);
        }

        return createMapping(p);
    }

    private AdapterMapping createMapping(Properties props) {
        Method[] setters = AdapterMapping.class.getMethods();
        AdapterMapping mapping = new AdapterMapping();

        for (int i = 0; i < setters.length; i++) {
            String methodName = setters[i].getName();
            if (!methodName.startsWith("set"))
                continue;

            String key = Character.toLowerCase(methodName.charAt(3))
                    + methodName.substring(4);
            String clientMethod = props.getProperty(key);
            if (clientMethod == null)
                continue;

            Method setter = setters[i];
            try {
                setter.invoke(mapping, new Object[] { clientMethod });
            } catch (Exception e) {
                log.warn(e.getMessage(), e);
            }
        }

        return mapping;
    }
}
