no.sesat.search.datamodel.DataModelFactoryImplTest.java Source code

Java tutorial

Introduction

Here is the source code for no.sesat.search.datamodel.DataModelFactoryImplTest.java

Source

/* Copyright (2012) Schibsted ASA
 * This file is part of Possom.
 *
 *   Possom 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 3 of the License, or
 *   (at your option) any later version.
 *
 *   Possom 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 Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with Possom.  If not, see <http://www.gnu.org/licenses/>.
 *
 * DataModelFactoryImplTest.java
 *
 * Created on 30 January 2007, 15:33
 *
 */

package no.sesat.search.datamodel;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;
import no.sesat.search.datamodel.generic.DataNode;
import no.sesat.search.datamodel.generic.DataObject;
import no.sesat.search.datamodel.generic.DataObject.Property;
import no.sesat.search.site.Site;
import no.sesat.search.site.SiteContext;
import no.sesat.search.site.config.FileResourceLoader;
import no.sesat.search.site.config.PropertiesLoader;
import org.apache.commons.beanutils.MappedPropertyDescriptor;
import org.apache.log4j.Logger;
import org.testng.annotations.Test;

/** Instantiate all the nodes and objects that exist in the datamodel.
 *
 *
 * @version <tt>$Id$</tt>
 */
public final class DataModelFactoryImplTest {

    // Constants -----------------------------------------------------

    private static final Logger LOG = Logger.getLogger(DataModelFactoryImplTest.class);

    private static final String ASSERT_METHOD_NOT_GETTER_OR_SETTER = " is not either a getter or setter to this javaBean. Properties are ";

    // Attributes ----------------------------------------------------

    private final DataModelFactory factory;
    private final DataModel datamodel;

    // Static --------------------------------------------------------

    // Constructors --------------------------------------------------

    /** Creates a new instance of DataModelTest */
    public DataModelFactoryImplTest() {
        factory = new DataModelFactoryImpl(new DataModelFactory.Context() {
            public Site getSite() {
                return Site.DEFAULT;
            }

            public PropertiesLoader newPropertiesLoader(final SiteContext siteCxt, final String resource,
                    final Properties properties) {
                return FileResourceLoader.newPropertiesLoader(siteCxt, resource, properties);
            }
        });
        datamodel = factory.instantiate();
    }

    // Public --------------------------------------------------------

    /**  **/
    @Test
    public void testInstantiateDataObjects() throws Exception {

        LOG.info("testInstantiateDataObjects()");
        scan(DataObject.class, DataModel.class, new Command() {
            public void execute(Object... args) {
                try {
                    final Class<?> cls = (Class<?>) args[0];
                    testInstantiate(cls);
                } catch (IntrospectionException ie) {
                    LOG.info(ie.getMessage(), ie);
                    throw new RuntimeException(ie.getMessage(), ie);
                }
            }
        });
    }

    /**
     *
     * @throws java.lang.Exception
     */
    @Test
    public void testInstantiateDataNodes() throws Exception {

        LOG.info("testInstantiateDataNodes()");
        scan(DataNode.class, DataModel.class, new Command() {
            public void execute(Object... args) {
                try {
                    final Class<?> cls = (Class<?>) args[0];
                    testInstantiate(cls);
                } catch (IntrospectionException ie) {
                    LOG.info(ie.getMessage(), ie);
                    throw new RuntimeException(ie.getMessage(), ie);
                }
            }
        });
    }

    /**
     *
     * @throws java.lang.Exception
     */
    @Test
    public void testDataObjectGetters() throws Exception {

        LOG.info("testDataObjectGetters()");
        scan(DataObject.class, DataModel.class, new Command() {
            public void execute(Object... args) {

                try {
                    final Class<?> cls = (Class<?>) args[0];
                    final Object dataObject = testInstantiate(cls);

                    final PropertyDescriptor[] properties = Introspector.getBeanInfo(cls).getPropertyDescriptors();
                    for (PropertyDescriptor property : properties) {
                        if (null != property.getReadMethod()) {
                            final Object value = invoke(property.getReadMethod(), dataObject, new Object[0]);
                            LOG.info("        Getter on " + property.getName() + " returned " + value);
                        }
                        if (property instanceof MappedPropertyDescriptor) {
                            final MappedPropertyDescriptor mappedProperty = (MappedPropertyDescriptor) property;
                            if (null != mappedProperty.getReadMethod()) {
                                final Object value = invoke(mappedProperty.getMappedReadMethod(), dataObject, "");
                                LOG.info("        Getter on " + mappedProperty.getName() + " returned " + value);
                            }
                        }
                    }
                } catch (IntrospectionException ie) {
                    LOG.info(ie.getMessage(), ie);
                    throw new RuntimeException(ie.getMessage(), ie);
                }
            }
        });
    }

    // Package protected ---------------------------------------------

    // Protected -----------------------------------------------------

    // Private -------------------------------------------------------

    private <T> T testInstantiate(final Class<T> cls) throws IntrospectionException {

        LOG.info("    instantiating " + cls.getSimpleName());

        final PropertyDescriptor[] properties = Introspector.getBeanInfo(cls).getPropertyDescriptors();
        final Property[] props = new Property[properties.length];
        for (int i = 0; i < props.length; ++i) {
            props[i] = new Property(properties[i].getName(), null);
        }

        final T data = factory.instantiate(cls, datamodel, props);

        assert null != data : "instantiate(" + cls.getSimpleName() + ", properties) returned null";
        LOG.info("      instantiated .." + data.toString().replaceFirst("no.sesat.search.datamodel", ""));

        return data;
    }

    private void scan(final Class<? extends Annotation> type, final Class<?> cls, final Command command)
            throws IntrospectionException {

        LOG.info("scanning " + cls.getSimpleName());
        final PropertyDescriptor[] properties = Introspector.getBeanInfo(cls).getPropertyDescriptors();
        for (PropertyDescriptor property : properties) {

            final Class<?> propCls = property instanceof MappedPropertyDescriptor
                    ? ((MappedPropertyDescriptor) property).getMappedPropertyType()
                    : property.getPropertyType();

            LOG.info("  checking property " + property.getName() + " [" + propCls.getSimpleName() + ']');

            if (null != propCls.getAnnotation(type)) {
                command.execute(propCls);
            }

            if (null != propCls.getAnnotation(DataNode.class)) {
                // also descend down dataNodes in the datamodel
                scan(type, propCls, command);
            }
        }

        // repeat again on all implemented interfaces
        for (Class<?> c : cls.getInterfaces()) {
            scan(type, c, command);
        }
    }

    /** Calls the method.invoke(..) wrapping any thrown exceptions with a RuntimeException. **/
    private Object invoke(final Method method, final Object dataObject, final Object... args) {

        try {
            return method.invoke(dataObject, args);

        } catch (IllegalAccessException iae) {
            LOG.error(iae.getMessage(), iae);
            throw new RuntimeException(iae.getMessage(), iae);
        } catch (IllegalArgumentException iae) {
            LOG.info(iae.getMessage(), iae);
            throw new RuntimeException(iae.getMessage(), iae);
        } catch (InvocationTargetException ite) {
            LOG.info(ite.getMessage(), ite);
            throw new RuntimeException(ite.getMessage(), ite);
        }
    }

    // Inner classes -------------------------------------------------

    private interface Command {
        void execute(Object... args);
    }
}