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

Java tutorial

Introduction

Here is the source code for no.sesat.search.datamodel.DataModelFactoryImpl.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/>.
 *
 * DataModelFactoryImpl.java
 *
 * Created on 27 January 2007, 22:49
 *
 */

package no.sesat.search.datamodel;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Collections;
import no.sesat.commons.reflect.ConcurrentProxy;
import no.sesat.search.datamodel.access.ControlLevel;
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.datamodel.generic.MapDataObjectSupport;
import org.apache.commons.beanutils.MappedPropertyDescriptor;
import org.apache.log4j.Logger;

/** Default implementation of the DataModelFactory.
 *
 *
 * @version <tt>$Id$</tt>
 */
final class DataModelFactoryImpl extends DataModelFactory {

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

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

    private static final String ERR_ONLY_DATA_NODE_OR_OBJECT = "DataModelFactory can only instantiate DataObject or DataNode classes";
    private static final String ERR_ONLY_JAVA_BEAN_DATA_OBJECT = "DataModelFactory can only instantiate DataObjects following a JavaBean pattern";

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

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

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

    DataModelFactoryImpl(final Context cxt) {
        super(cxt);
    }

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

    @SuppressWarnings("unchecked")
    public DataModel instantiate() {

        try {
            final Class<DataModel> cls = DataModel.class;

            final PropertyDescriptor[] propDescriptors = Introspector.getBeanInfo(DataModel.class)
                    .getPropertyDescriptors();
            final Property[] properties = new Property[propDescriptors.length];
            for (int i = 0; i < properties.length; ++i) {
                properties[i] = new Property(propDescriptors[i].getName(),
                        propDescriptors[i] instanceof MappedPropertyDescriptor
                                ? new MapDataObjectSupport(Collections.EMPTY_MAP)
                                : null);
            }

            final InvocationHandler handler = new BeanDataModelInvocationHandler(
                    new BeanDataModelInvocationHandler.PropertyInitialisor(DataModel.class, properties));

            return (DataModel) ConcurrentProxy.newProxyInstance(cls.getClassLoader(), new Class[] { cls }, handler);

        } catch (IntrospectionException ie) {
            throw new IllegalStateException("Need to introspect DataModel properties before instantiation");
        }
    }

    @SuppressWarnings("unchecked")
    public <T> T instantiate(final Class<T> cls, final DataModel datamodel, final Property... properties) {

        try {
            final InvocationHandler handler;

            if (null != cls.getAnnotation(DataNode.class)) {
                handler = BeanDataNodeInvocationHandler.instanceOf(cls, datamodel, properties);

            } else if (null != cls.getAnnotation(DataObject.class)) {
                handler = BeanDataObjectInvocationHandler.instanceOf(cls, properties);

            } else {
                throw new IllegalArgumentException(ERR_ONLY_DATA_NODE_OR_OBJECT);
            }

            return (T) ConcurrentProxy.newProxyInstance(cls.getClassLoader(), new Class[] { cls }, handler);

        } catch (IntrospectionException ie) {
            throw new IllegalArgumentException(ERR_ONLY_JAVA_BEAN_DATA_OBJECT);
        }
    }

    public DataModel assignControlLevel(final DataModel datamodel, final ControlLevel controlLevel) {

        final BeanDataModelInvocationHandler handler = (BeanDataModelInvocationHandler) Proxy
                .getInvocationHandler(datamodel);

        handler.setControlLevel(controlLevel);

        return datamodel;
    }

    public ControlLevel currentControlLevel(final DataModel datamodel) {

        final BeanDataModelInvocationHandler handler = (BeanDataModelInvocationHandler) Proxy
                .getInvocationHandler(datamodel);

        return ((BeanDataModelInvocationHandler.DataModelBeanContextSupport) handler.context).getControlLevel();
    }

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

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

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

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

}