Java tutorial
/* 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); } }