org.betaconceptframework.astroboa.model.impl.SimpleCmsPropertyImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.betaconceptframework.astroboa.model.impl.SimpleCmsPropertyImpl.java

Source

/*
 * Copyright (C) 2005-2012 BetaCONCEPT Limited
 *
 * This file is part of Astroboa.
 *
 * Astroboa 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.
 *
 * Astroboa 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 Astroboa.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.betaconceptframework.astroboa.model.impl;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.betaconceptframework.astroboa.api.model.ComplexCmsProperty;
import org.betaconceptframework.astroboa.api.model.SimpleCmsProperty;
import org.betaconceptframework.astroboa.api.model.definition.ComplexCmsPropertyDefinition;
import org.betaconceptframework.astroboa.api.model.definition.SimpleCmsPropertyDefinition;
import org.betaconceptframework.astroboa.api.model.exception.CmsException;
import org.betaconceptframework.astroboa.api.model.exception.MultipleOccurenceException;
import org.betaconceptframework.astroboa.api.model.exception.SingleOccurenceException;
import org.betaconceptframework.astroboa.api.model.io.ResourceRepresentationType;
import org.betaconceptframework.astroboa.context.AstroboaClientContextHolder;
import org.betaconceptframework.astroboa.model.lazy.LazyLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Gregory Chomatas (gchomatas@betaconcept.com)
 * @author Savvas Triantafyllou (striantafyllou@betaconcept.com)
 * 
 */
public abstract class SimpleCmsPropertyImpl<T, D extends SimpleCmsPropertyDefinition<T>, P extends ComplexCmsProperty<? extends ComplexCmsPropertyDefinition, ? extends ComplexCmsProperty<?, ?>>>
        extends CmsPropertyImpl<D, P> implements SimpleCmsProperty<T, D, P>, Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 2691160236131731929L;
    // Real data for simple value
    protected List<T> values = new ArrayList<T>();

    @Override
    public void setPropertyDefinition(D propertyDefinition) {
        super.setPropertyDefinition(propertyDefinition);

        if (this.propertyDefinition != null) {

            if (this.propertyDefinition.getValueType() != getValueType())
                throw new CmsException("Incompatible value types. Definition "
                        + this.propertyDefinition.getValueType() + " , Simple Cms Property : " + getValueType());
        }

    }

    public void addSimpleTypeValue(T value) {

        if (propertyDefinition != null) {
            //In case this property is single value call method setSimpleTypeValue
            if (CollectionUtils.isNotEmpty(values) && isSingle()) {
                setSimpleTypeValue(value);

                return;
            }

            //In case value is null value it will not be added
            //in the list. Savvas was adding null values in the list and we should check whether 
            // this is required for some reason
            if (value != null) {

                if (values == null) {
                    values = new ArrayList<T>();
                }

                if (propertyDefinition.isMultiple()) {
                    values.add(value);
                } else { // allows only one value
                    if (values.size() > 0) {
                        values.set(0, value);
                    } else {
                        values.add(value);
                    }

                }
            }
        } else {
            throw new CmsException(
                    "Definition of property: '" + getFullPath() + "' is null. Value will not be added");
        }

    }

    /**
     * In cases where this property is an enumeration then all values must
     * be within the provided value range
     * @param asList
     */
    public void checkValues() {

        if (CollectionUtils.isNotEmpty(values)) {
            if (getPropertyDefinition() == null) {
                throw new CmsException("Found no property definition attached to this property " + getName());
            }

            for (T value : values) {
                if (!getPropertyDefinition().isValueValid(value)) {
                    throw new CmsException(generateMessageForInvalidValue(value));
                }
            }
        }
    }

    abstract protected String generateMessageForInvalidValue(T value);

    public T getSimpleTypeValue() throws MultipleOccurenceException {

        throwExceptionIfPropertyIsMultiple();

        if (CollectionUtils.isEmpty(values))
            return null;

        return values.get(0);
    }

    public List<T> getSimpleTypeValues() throws SingleOccurenceException {

        //Throw an exception only if property is single value and list contains
        //more than one values.
        if (CollectionUtils.isNotEmpty(values) && values.size() > 1)
            throwExceptionIfPropertyIsSingleValue();

        return values;
    }

    /**
     * Remove value located in index provided
     * @param index
     */
    public void removeSimpleTypeValue(int index) throws SingleOccurenceException {
        //Check if property is single value
        //and index is not 0
        if (index != 0)
            throwExceptionIfPropertyIsSingleValue();

        if (values != null) {
            values.remove(index);
        }
    }

    /**
     * Property is considered single valued. In any case 
     * just update or insert ONLY the first value in list
     * @param value
     */
    public void setSimpleTypeValue(T value) throws MultipleOccurenceException {
        throwExceptionIfPropertyIsMultiple();

        if (value != null) {

            if (values == null) {
                values = new ArrayList<T>();
            }

            if (values.size() > 0) {
                values.set(0, value);
            } else {
                values.add(value);
            }

        } else {
            if (values != null) {
                values.clear();
            }
        }
    }

    public void setSimpleTypeValues(List<T> values) throws SingleOccurenceException {

        if (values == null) {
            //Throw and catch an exception to log the stack trace in order to 
            //be able to check who provided a null list
            try {
                throw new Exception();
            } catch (Exception e) {
                final Logger logger = LoggerFactory.getLogger(getClass());
                logger.warn(
                        "A null list is provided as values for property {}. An empty list will be created instead "
                                + getFullPath(),
                        e);
                this.values.clear();
            }
        } else {
            this.values = values;
        }

        //Check if list contains more than value
        //and this property is single value
        if (CollectionUtils.isNotEmpty(this.values) && this.values.size() > 1)
            throwExceptionIfPropertyIsSingleValue();

    }

    public boolean hasNoValues() {
        return values == null || values.isEmpty();
    }

    public boolean hasValues() {
        return !hasNoValues();
    }

    @Override
    public void removeValues() {

        if (values != null) {
            values.clear();
        }

    }

    //Override deserialization process to inject 
    //property definition
    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {

        //Deserialize bean normally
        ois.defaultReadObject();

        //Inject Property definition
        LazyLoader lazyLoader = AstroboaClientContextHolder.getLazyLoaderForClient(authenticationToken);

        if (lazyLoader != null) {
            lazyLoader.activateClientContextForAuthenticationToken(authenticationToken);
            setPropertyDefinition((D) lazyLoader.getDefinitionService().getCmsDefinition(fullPropertyDefinitionPath,
                    ResourceRepresentationType.DEFINITION_INSTANCE, false));
        }
    }

    @Override
    public boolean swapValues(int from, int to) {

        if (values == null) {
            return false;
        }

        if (from == to || from < 0 || to < 0) {
            return false;
        }

        try {
            Collections.swap(values, from, to);
            resetPaths();
            return true;
        } catch (Exception e) {
            //Ignore exception
            return false;
        }
    }

    @Override
    public boolean changePositionOfValue(int from, int to) {

        if (values == null) {
            return false;
        }

        if (from == to || from < 0 || to < 0 || from > values.size() - 1 || to > values.size()) {
            return false;
        }

        try {
            values.add(to, values.get(from));
            if (from > to) {
                from++;
            }
            values.remove(from);
            resetPaths();
            return true;
        } catch (Exception e) {
            //Ignore exception
            return false;
        }
    }

    @Override
    public T getFirstValue() {
        if (values == null || values.isEmpty()) {
            return null;
        }

        return values.get(0);
    }

    /**
     * Useful for retrieving all values, 
     * regardless of the cardinality of the property.
     * 
     * This way you do not have to know apriori property cardinality, 
     * as in cases of {@link #getSimpleTypeValue()} or {@link #getSimpleTypeValues()}, 
     * if you do not want an exception to be thrown
     * 
     * @return
     */
    public List<T> getValues() {
        return values;
    }

}