DefaultFieldWriterFactory.java :  » Development » ivatamasks » com » ivata » mask » web » field » Java Open Source

Java Open Source » Development » ivatamasks 
ivatamasks » com » ivata » mask » web » field » DefaultFieldWriterFactory.java
/*
 * Copyright (c) 2001 - 2005 ivata limited.
 * All rights reserved.
 * -----------------------------------------------------------------------------
 * ivata masks may be redistributed under the GNU General Public
 * License as published by the Free Software Foundation;
 * version 2 of the License.
 *
 * These programs are free software; you can redistribute them and/or
 * modify them under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2 of the License.
 *
 * These programs are distributed in the hope that they will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * See the GNU General Public License in the file LICENSE.txt for more
 * details.
 *
 * If you would like a copy of the GNU General Public License write to
 *
 * Free Software Foundation, Inc.
 * 59 Temple Place - Suite 330
 * Boston, MA 02111-1307, USA.
 *
 *
 * To arrange commercial support and licensing, contact ivata at
 *                  http://www.ivata.com/contact.jsp
 * -----------------------------------------------------------------------------
 * $Log: DefaultFieldWriterFactory.java,v $
 * Revision 1.15  2005/10/11 18:54:06  colinmacleod
 * Fixed some checkstyle and javadoc issues.
 *
 * Revision 1.14  2005/10/03 10:17:25  colinmacleod
 * Fixed some style and javadoc issues.
 *
 * Revision 1.13  2005/10/02 14:06:32  colinmacleod
 * Added/improved log4j logging.
 *
 * Revision 1.12  2005/09/29 12:12:30  colinmacleod
 * Added password field type.
 *
 * Revision 1.11  2005/09/16 13:41:18  colinmacleod
 * Created new convertor class to handle timestamps.
 *
 * Revision 1.10  2005/09/14 12:54:31  colinmacleod
 * Added checking for hidden fields of
 * numeric or date types.
 *
 * Revision 1.9  2005/04/09 18:04:17  colinmacleod
 * Changed copyright text to GPL v2 explicitly.
 *
 * Revision 1.8  2005/01/19 12:51:03  colinmacleod
 * Changed Id --> Name.
 *
 * Revision 1.7  2005/01/10 19:05:12  colinmacleod
 * Removed reflection and simplified override method
 * for field writer classes.
 *
 * Revision 1.6  2005/01/07 08:08:24  colinmacleod
 * Moved up a version number.
 * Changed copyright notices to 2005.
 * Updated the documentation:
 *   - started working on multiproject:site docu.
 *   - changed the logo.
 * Added checkstyle and fixed LOADS of style issues.
 * Added separate thirdparty subproject.
 * Added struts (in web), util and webgui (in webtheme) from ivata op.
 *
 * Revision 1.5  2004/12/30 20:27:55  colinmacleod
 * Added reflection to let you override the field writer classes used.
 *
 * Revision 1.4  2004/12/29 15:30:46  colinmacleod
 * Added asserts to check parameters are not null.
 *
 * Revision 1.3  2004/11/12 15:10:41  colinmacleod
 * Moved persistence classes from ivata op as a replacement for
 * ValueObjectLocator.
 *
 * Revision 1.2  2004/11/11 13:44:04  colinmacleod
 * Added HTMLFormatter.
 *
 * Revision 1.1.1.1  2004/05/16 20:40:32  colinmacleod
 * Ready for 0.1 release
 * -----------------------------------------------------------------------------
 */
package com.ivata.mask.web.field;

import org.apache.log4j.Logger;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;

import javax.servlet.http.HttpSession;

import org.apache.commons.beanutils.PropertyUtils;

import com.ivata.mask.field.Field;
import com.ivata.mask.field.FieldValueConvertor;
import com.ivata.mask.field.date.DateFieldValueConvertor;
import com.ivata.mask.field.date.TimestampFieldValueConvertor;
import com.ivata.mask.field.number.NumberFieldValueConvertor;
import com.ivata.mask.field.valueobject.ValueObjectFieldValueConvertor;
import com.ivata.mask.persistence.PersistenceManager;
import com.ivata.mask.persistence.PersistenceSession;
import com.ivata.mask.util.SystemException;
import com.ivata.mask.valueobject.ValueObject;
import com.ivata.mask.web.field.hidden.HiddenFieldWriter;
import com.ivata.mask.web.field.text.PasswordFieldWriter;
import com.ivata.mask.web.field.text.TextAreaFieldWriter;
import com.ivata.mask.web.field.text.TextFieldWriter;
import com.ivata.mask.web.field.valueobject.ValueObjectFieldWriter;
import com.ivata.mask.web.format.HTMLFormatter;
import com.ivata.mask.web.format.LineBreakFormat;
/**
 * <p>
 * Use this utility class to generate an appropriate field writer for a given
 * mask and field.
 * </p>
 *
 * @since ivata masks 0.1 (2004-05-14)
 * @author Colin MacLeod
 * <a href='mailto:colin.macleod@ivata.com'>colin.macleod@ivata.com</a>
 * @version $Revision: 1.15 $
 */
public class DefaultFieldWriterFactory implements FieldWriterFactory {
    /**
     * Logger for this class.
     */
    private static final Logger logger = Logger
            .getLogger(DefaultFieldWriterFactory.class);

    /**
     * <copyDoc>Refer to {@link #getActionPage}.</copyDoc>
     */
    private String actionPage;
    /**
     * <p>
     * Formatter used to format all texts.
     * </p>
     */
    private HTMLFormatter formatter = new HTMLFormatter();
    /**
     * <p>
     * This object is used to retrieve lists for collection field writers.
     * </p>
     */
    private PersistenceManager persistenceManager;
    /**
     * Construct a writer factory.
     *
     * @param persistenceManagerParam
     *            used to retrieve value objects for a value
     * @param actionPageParam
     *            page of the action to which we'll link value objects to.
     */
    public DefaultFieldWriterFactory(
            final PersistenceManager persistenceManagerParam,
            final String actionPageParam) {
        this.persistenceManager = persistenceManagerParam;
        this.actionPage = actionPageParam;
        // for now, we only have one format in the formatter
        LineBreakFormat lineBreakFormat = new LineBreakFormat();
        lineBreakFormat.setConvertLineBreaks(true);
        formatter.add(lineBreakFormat);
    }
    /**
     * Page of the <strong>Struts </strong> action to which we'll link value
     * objects to. This must be a full, webapp-relative link, starting with '/'.
     *
     * @return Returns the actionPage.
     */
    protected final String getActionPage() {
        if (logger.isDebugEnabled()) {
            logger.debug("getActionPage() - start");
        }

        if (logger.isDebugEnabled()) {
            logger
                    .debug("getActionPage() - end - return value = "
                            + actionPage);
        }
        return actionPage;
    }
    /**
     * <p>
     * Get a field writer appropriate to the given field.
     * </p>
     *
     * @param session Current HTTP session we are processing.
     * @param valueObjectParam
     *            Field for which to return an appropriate field writer.
     * @param fieldParam
     *            Field for which to return an appropriate field writer.
     * @param subFieldParam
     *            Sub-field within the main field, if the field is a value
     *            object.
     * but the value stored in a hidden field.
     * @param hidden
     * If <code>true</code>, overrides the field definition, and gets a writer
     * for a hidden field.
     * @return valid field writer for the field provided.
     * @throws SystemException
     *             thrown if the writer cannot be retrieved for any reason.
     */
    public final FieldWriter getFieldWriter(
            final HttpSession session,
            final ValueObject valueObjectParam,
            final Field fieldParam, final Field subFieldParam,
            final boolean hidden)
            throws SystemException {
        if (logger.isDebugEnabled()) {
            logger.debug("getFieldWriter(HttpSession session = " + session
                    + ", ValueObject valueObjectParam = " + valueObjectParam
                    + ", Field fieldParam = " + fieldParam
                    + ", Field subFieldParam = " + subFieldParam
                    + ", boolean hidden = " + hidden + ") - start");
        }

        FieldWriter fieldWriter = null;
        Field writerField;
        if (subFieldParam == null) {
            writerField = fieldParam;
        } else {
            writerField = subFieldParam;
        }
        String type = writerField.getType();
        FieldValueConvertor fieldValueConvertor = null;
        if (Field.TYPE_RADIO.equals(type)) {
            throw new UnsupportedOperationException("ERROR: field type '"
                    + type + "' is not yet supported.");
        } else if (Field.TYPE_SELECT.equals(type)) {
            throw new UnsupportedOperationException("ERROR: field type '"
                    + type + "' is not yet supported.");
        } else if (Field.TYPE_AMOUNT.equals(type)) {
            fieldValueConvertor = new NumberFieldValueConvertor("###0.##");
        } else if (Field.TYPE_NUMBER.equals(type)) {
            fieldValueConvertor = new NumberFieldValueConvertor("###0");
        } else if (Field.TYPE_DATE.equals(type)) {
            fieldValueConvertor = new DateFieldValueConvertor("yyyy-MM-dd");
        } else if (Field.TYPE_TIMESTAMP.equals(type)) {
            fieldValueConvertor = new TimestampFieldValueConvertor();
        } else if (Field.TYPE_STRING.equals(type)) {
            fieldValueConvertor = new FieldValueConvertor();
        } else {
            // if the type was expressly set, then start looking at the class of
            // the field
            PropertyDescriptor descriptor;
            try {
                Class valueObjectClass;
                if (subFieldParam == null) {
                    valueObjectClass = valueObjectParam.getClass();
                } else {
                    if (fieldParam.getDOClass() != null) {
                        valueObjectClass = fieldParam.getDOClass();
                    } else {
                        descriptor = PropertyUtils.getPropertyDescriptor(
                                valueObjectParam, fieldParam.getPath());
                        valueObjectClass = descriptor.getPropertyType();
                        // if it is a collection, we _need_ the class
                        // specifically defined
                        if (Collection.class
                                .isAssignableFrom(valueObjectClass)) {
                            throw new NullPointerException(
                                    "ERROR: you must specify a data object "
                                            + "class for collection '"
                                            + fieldParam.getName() + "'.");
                        }
                    }
                }
                descriptor = getPropertyDescriptor(valueObjectClass,
                        writerField.getPath());
            } catch (NoSuchMethodException e) {
                logger.error("getFieldWriter - error getting property for "
                        + fieldParam,  e);
                throw new SystemException(e);
            } catch (IllegalAccessException e) {
                logger.error("getFieldWriter - error getting property for "
                        + fieldParam,  e);
                throw new SystemException(e);
            } catch (InvocationTargetException e) {
                logger.error("getFieldWriter - error getting property for "
                        + fieldParam,  e);
                throw new SystemException(e);
            }
            // if it is a value object, use a value object writer
            Class propertyType = descriptor.getPropertyType();
            if (ValueObject.class.isAssignableFrom(propertyType)
                        || Collection.class.isAssignableFrom(
                                propertyType)) {
                // if it is a hidden field, use the value object convertor
                // to put the id out
                if (hidden || writerField.isHidden()) {
                    fieldValueConvertor = new ValueObjectFieldValueConvertor();
                } else {
                    // for a collection type, you _must_ specify the value
                    // object class to use!!!
                    Class dOClass;
                    boolean multiple = Collection.class
                            .isAssignableFrom(propertyType);
                    if (writerField.getDOClass() != null) {
                        dOClass = writerField.getDOClass();
                    } else if (multiple) {
                        throw new SystemException(
                            "ERROR: for collection field '"
                            + writerField.getPath()
                            + "', you must specify attribute 'class' in the "
                            + "ivata masks configuration.");
                    } else {
                        dOClass = propertyType;
                    }
                    PersistenceSession persistenceSession = persistenceManager
                            .openSession(session);
                    try {
                        Collection allEntries = persistenceManager.findAll(
                                persistenceSession, dOClass);
                        int listHeight = 1;
                        if (multiple) {
                            listHeight =
                                FieldWriterConstants.MULTIPLE_LIST_HEIGHT;
                        }
                        fieldWriter = newValueObjectFieldWriter(writerField,
                                actionPage, allEntries, formatter, listHeight,
                                multiple);
                    } finally {
                        persistenceSession.close();
                    }
                }
            } else {
                // default to the string representation of the field
                fieldValueConvertor = new FieldValueConvertor();
            }
        }
        // if we specified a field value convertor, then either make a
        // hidden or text/textarea field (otherwise, it must have been the
        // 'special case' of a value object field writer, which is dealt
        // with above.
        if (fieldValueConvertor != null) {
            if (hidden || writerField.isHidden()) {
                fieldWriter = newHiddenFieldWriter(writerField,
                        fieldValueConvertor, formatter);
            } else if (Field.TYPE_PASSWORD.equals(type)) {
                fieldWriter = newPasswordFieldWriter(writerField,
                        fieldValueConvertor, formatter);
            } else if (Field.TYPE_TEXTAREA.equals(type)) {
                fieldWriter = newTextAreaFieldWriter(writerField,
                        fieldValueConvertor, formatter);
            } else {
                fieldWriter = newTextFieldWriter(writerField,
                        fieldValueConvertor, formatter);
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("getFieldWriter - end - return value = "
                    + fieldWriter);
        }
        return fieldWriter;
    }
    /**
     * <p>
     * Find the descriptor for the class and id provided.
     * </p>
     *
     * @param theClass
     *            class for which to find a descriptor.
     * @param name
     *            name of the property for which to find a descriptor.
     * @return valid property descriptor describing the property called
     *         <code>name</code> in class <code>theClass</code>.
     */
    private PropertyDescriptor getPropertyDescriptor(final Class theClass,
            final String name) {
        if (logger.isDebugEnabled()) {
            logger.debug("getPropertyDescriptor(Class theClass = " + theClass
                    + ", String name = " + name + ") - start");
        }

        PropertyDescriptor[] allDescriptors = PropertyUtils
                .getPropertyDescriptors(theClass);
        PropertyDescriptor descriptor = null;
        // this property might be nested
        int dotIndex = name.indexOf('.');
        String propertyName = null;
        if (dotIndex == -1) {
            propertyName = name;
        } else {
            propertyName = name.substring(0, dotIndex);
        }
        for (int i = 0; i < allDescriptors.length; i++) {
            if (propertyName.equals(allDescriptors[i].getName())) {
                descriptor = allDescriptors[i];
            }
        }
        // if this is a nested property, get the next in the chain
        if (dotIndex == -1) {
            if (logger.isDebugEnabled()) {
                logger.debug("getPropertyDescriptor - end - return value = "
                                + descriptor);
            }
            return descriptor;
        } else {
            PropertyDescriptor returnPropertyDescriptor = getPropertyDescriptor(
                    theClass, name.substring(++dotIndex));
            if (logger.isDebugEnabled()) {
                logger.debug("getPropertyDescriptor - end - return value = "
                                + returnPropertyDescriptor);
            }
            return returnPropertyDescriptor;
        }
    }
    /**
     * Override this method if you need a different field writer for passwords.
     *
     * @param field
     * <copyDoc>Refer to {@link TextAreaFieldWriter#TextAreaFieldWriter}.
     * </copyDoc>
     * @param convertor
     * <copyDoc>Refer to {@link TextAreaFieldWriter#TextAreaFieldWriter}.
     * </copyDoc>
     * @param formatterParam
     * <copyDoc>Refer to {@link TextAreaFieldWriter#TextAreaFieldWriter}.
     * </copyDoc>
     * @return valid text area field writer.
     */
    protected FieldWriter newPasswordFieldWriter(final Field field,
            final FieldValueConvertor convertor,
            final HTMLFormatter formatterParam) {
        if (logger.isDebugEnabled()) {
            logger.debug("newPasswordFieldWriter(Field field = " + field
                    + ", FieldValueConvertor convertor = " + convertor
                    + ", HTMLFormatter formatterParam = " + formatterParam
                    + ") - start");
        }

        FieldWriter returnFieldWriter = new PasswordFieldWriter(field,
                convertor, formatterParam);
        if (logger.isDebugEnabled()) {
            logger.debug("newPasswordFieldWriter - end - return value = "
                            + returnFieldWriter);
        }
        return returnFieldWriter;
    }
    /**
     * Override this method if you need a different field writer for text areas.
     *
     * @param field
     * <copyDoc>Refer to {@link TextAreaFieldWriter#TextAreaFieldWriter}.
     * </copyDoc>
     * @param convertor
     * <copyDoc>Refer to {@link TextAreaFieldWriter#TextAreaFieldWriter}.
     * </copyDoc>
     * @param formatterParam
     * <copyDoc>Refer to {@link TextAreaFieldWriter#TextAreaFieldWriter}.
     * </copyDoc>
     * @return valid text area field writer.
     */
    protected FieldWriter newTextAreaFieldWriter(final Field field,
            final FieldValueConvertor convertor,
            final HTMLFormatter formatterParam) {
        if (logger.isDebugEnabled()) {
            logger.debug("newTextAreaFieldWriter(Field field = " + field
                    + ", FieldValueConvertor convertor = " + convertor
                    + ", HTMLFormatter formatterParam = " + formatterParam
                    + ") - start");
        }

        FieldWriter returnFieldWriter = new TextAreaFieldWriter(field,
                convertor, formatterParam);
        if (logger.isDebugEnabled()) {
            logger.debug("newTextAreaFieldWriter - end - return value = "
                            + returnFieldWriter);
        }
        return returnFieldWriter;
    }
    /**
     * Override this method if you need a different field writer for hidden
     * fields.
     *
     * @param fieldParam
     * <copyDoc>Refer to {@link TextFieldWriter#TextFieldWriter}.</copyDoc>
     * @param convertorParam
     * <copyDoc>Refer to {@link TextFieldWriter#TextFieldWriter}.</copyDoc>
     * @param formatterParam
     * <copyDoc>Refer to {@link TextFieldWriter#TextFieldWriter}.</copyDoc>
     * @return valid text field writer.
     */
    protected FieldWriter newHiddenFieldWriter(final Field fieldParam,
            final FieldValueConvertor convertorParam,
            final HTMLFormatter formatterParam) {
        if (logger.isDebugEnabled()) {
            logger.debug("newHiddenFieldWriter(Field fieldParam = "
                    + fieldParam + ", FieldValueConvertor convertorParam = "
                    + convertorParam + ", HTMLFormatter formatterParam = "
                    + formatterParam + ") - start");
        }

        FieldWriter returnFieldWriter = new HiddenFieldWriter(fieldParam,
                convertorParam, formatterParam);
        if (logger.isDebugEnabled()) {
            logger.debug("newHiddenFieldWriter - end - return value = "
                            + returnFieldWriter);
        }
        return returnFieldWriter;
    }
    /**
     * Override this method if you need a different field writer for text
     * fields.
     *
     * @param fieldParam
     * <copyDoc>Refer to {@link TextFieldWriter#TextFieldWriter}.</copyDoc>
     * @param convertorParam
     * <copyDoc>Refer to {@link TextFieldWriter#TextFieldWriter}.</copyDoc>
     * @param formatterParam
     * <copyDoc>Refer to {@link TextFieldWriter#TextFieldWriter}.</copyDoc>
     * @return valid text field writer.
     */
    protected FieldWriter newTextFieldWriter(final Field fieldParam,
            final FieldValueConvertor convertorParam,
            final HTMLFormatter formatterParam) {
        if (logger.isDebugEnabled()) {
            logger.debug("newTextFieldWriter(Field fieldParam = " + fieldParam
                    + ", FieldValueConvertor convertorParam = "
                    + convertorParam + ", HTMLFormatter formatterParam = "
                    + formatterParam + ") - start");
        }

        FieldWriter returnFieldWriter = new TextFieldWriter(fieldParam,
                convertorParam, formatterParam);
        if (logger.isDebugEnabled()) {
            logger.debug("newTextFieldWriter - end - return value = "
                            + returnFieldWriter);
        }
        return returnFieldWriter;
    }
    /**
     * Override this method if you need a different field writer for value
     * objects.
     *
     * @param fieldParam
     * <copyDoc>Refer to {@link ValueObjectFieldWriter#ValueObjectFieldWriter}.
     * </copyDoc>
     * @param actionPageParam
     * <copyDoc>Refer to {@link ValueObjectFieldWriter#ValueObjectFieldWriter}.
     * </copyDoc>
     * @param allValueObjectsParam
     * <copyDoc>Refer to {@link ValueObjectFieldWriter#ValueObjectFieldWriter}.
     * </copyDoc>
     * @param formatterParam
     * <copyDoc>Refer to {@link ValueObjectFieldWriter#ValueObjectFieldWriter}.
     * </copyDoc>
     * @param listHeightParam
     * <copyDoc>Refer to {@link ValueObjectFieldWriter#ValueObjectFieldWriter}.
     * </copyDoc>
     * @param multipleParam
     * <copyDoc>Refer to {@link ValueObjectFieldWriter#ValueObjectFieldWriter}.
     * </copyDoc>
     * @return valid field writer.
     */
    protected FieldWriter newValueObjectFieldWriter(final Field fieldParam,
            final String actionPageParam,
            final Collection allValueObjectsParam,
            final HTMLFormatter formatterParam, final int listHeightParam,
            final boolean multipleParam) {
        if (logger.isDebugEnabled()) {
            logger.debug("newValueObjectFieldWriter(Field fieldParam = "
                    + fieldParam + ", String actionPageParam = "
                    + actionPageParam + ", Collection allValueObjectsParam = "
                    + allValueObjectsParam
                    + ", HTMLFormatter formatterParam = " + formatterParam
                    + ", int listHeightParam = " + listHeightParam
                    + ", boolean multipleParam = " + multipleParam
                    + ") - start");
        }

        FieldWriter returnFieldWriter = new ValueObjectFieldWriter(fieldParam,
                actionPageParam, allValueObjectsParam, formatterParam,
                listHeightParam, multipleParam);
        if (logger.isDebugEnabled()) {
            logger.debug("newValueObjectFieldWriter - end - return value = "
                            + returnFieldWriter);
        }
        return returnFieldWriter;
    }
}

java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.