org.wings.plaf.AbstractComponentCG.java Source code

Java tutorial

Introduction

Here is the source code for org.wings.plaf.AbstractComponentCG.java

Source

/*
 * $Id$
 * (c) Copyright 2000 wingS development team.
 *
 * This file is part of wingS (http://j-wings.org).
 *
 * wingS 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.1
 * of the License, or (at your option) any later version.
 *
 * Please see COPYING for the complete licence.
 */

package org.wings.plaf;

import java.beans.Introspector;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wings.SComponent;
import org.wings.SConstants;
import org.wings.session.SessionManager;

/**
 * Partial CG implementation that is common to all ComponentCGs.
 * @author <a href="mailto:engels@mercatis.de">Holger Engels</a>
 * @version $Revision$
 */
public abstract class AbstractComponentCG implements ComponentCG, SConstants, Serializable {
    protected final static Log logger = LogFactory.getLog("org.wings.plaf");

    protected static final Map cache = new HashMap();

    protected AbstractComponentCG() {
        CGManager manager = SessionManager.getSession().getCGManager();
        String name = getClass().getName();
        name = name.substring(name.lastIndexOf(".") + 1);
        long start = System.currentTimeMillis();
        configure(this, name, manager);

        logger.debug("configure CG done in " + (System.currentTimeMillis() - start) + " ms");
    }

    /**
     * Install the appropriate CG for <code>component</code>.
     * @param component the component
     */
    public void installCG(SComponent component) {
        long start = System.currentTimeMillis();
        CGManager manager = component.getSession().getCGManager();
        String className = component.getClass().getName();
        className = className.substring(className.lastIndexOf(".") + 1);

        configure(component, className, manager);
        logger.debug("install CG done in " + (System.currentTimeMillis() - start) + " ms");
    }

    /**
     * Recursively configure the component and dependant objects.
     */
    protected void configure(Object object, String className, CGManager manager) {
        try {
            Class objectClass = object.getClass();

            long introspection_time = System.currentTimeMillis();
            Method[] setters = (Method[]) cache.get(objectClass);
            if (setters == null) {
                synchronized (cache) {
                    setters = (Method[]) cache.get(objectClass);
                    if (setters == null) {
                        setters = findRelevantSetters(objectClass);
                        cache.put(objectClass, setters);
                    }
                }
            }
            logger.debug(objectClass.getName() + " introspection_time "
                    + (System.currentTimeMillis() - introspection_time) + " ms");

            long configuration_time = System.currentTimeMillis();
            for (int i = 0; i < setters.length; i++) {
                Object value = null;

                String propertyName = Introspector.decapitalize(setters[i].getName().substring(3));
                String lookupName = className + "." + propertyName;
                Class propertyType = setters[i].getParameterTypes()[0];

                value = manager.getObject(lookupName, propertyType);
                boolean configurable = !propertyType.isPrimitive();

                logger.debug(lookupName + "=" + value);

                if (value != null) {
                    setters[i].invoke(object, new Object[] { value });
                    if (configurable) {
                        configure(value, lookupName, manager);
                    }
                }
            }
            logger.debug(objectClass.getName() + " configuration_time "
                    + (System.currentTimeMillis() - configuration_time) + " ms");
        } catch (Exception e) {
            logger.fatal(null, e);
        }
    }

    protected Method[] findRelevantSetters(Class clazz) {
        Method[] methods = clazz.getMethods();
        List setterList = new ArrayList(methods.length / 2);
        for (int m = 0; m < methods.length; m++) {
            Method method = methods[m];
            if (method.getName().startsWith("set") && method.getParameterTypes().length == 1
                    && !method.getParameterTypes()[0].isArray()
                    && Arrays.binarySearch(toBeSkipped, method.getName()) < 0)
                setterList.add(method);
        }
        Iterator it = setterList.iterator();
        while (it.hasNext()) {
            Method setter = (Method) it.next();
            Class type = setter.getParameterTypes()[0];
            boolean present = false;
            if (boolean.class.equals(setter.getParameterTypes()[0])) {
                String getterName = "is" + setter.getName().substring(3);
                try {
                    Method getter = clazz.getMethod(getterName, EMPTY_CLASS_ARRAY);
                    if (type.equals(getter.getReturnType()))
                        present = true;
                } catch (Exception e) {
                }
            }
            if (!present) {
                String getterName = "g" + setter.getName().substring(1);
                try {
                    Method getter = clazz.getMethod(getterName, EMPTY_CLASS_ARRAY);
                    if (type.equals(getter.getReturnType()))
                        present = true;
                } catch (Exception e) {
                }
            }
            if (!present)
                it.remove();
        }
        return (Method[]) setterList.toArray(new Method[setterList.size()]);
    }

    private static final String[] toBeSkipped = new String[] { "setAction", "setBaseTarget", "setEnabled",
            "setEscapeSpecialChars", "setLocale", "setModel", "setName", "setParent", "setShowAsFormComponent",
            "setTargetResource", "setText", "setToolTipText", "setVisible" };

    private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];

    /**
     * Uninstall the CG from <code>component</code>.
     * @param component the component
     */
    public void uninstallCG(SComponent c) {
    }
}

/*
 * Local variables:
 * c-basic-offset: 4
 * indent-tabs-mode: nil
 * compile-command: "ant -emacs -find build.xml"
 * End:
 */