Package org.libreplan.business.resources.entities

Source Code of org.libreplan.business.resources.entities.CriterionType

/*
* This file is part of LibrePlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
*                         Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.libreplan.business.resources.entities;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.validation.Valid;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotNull;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.hibernate.validator.constraints.NotEmpty;
import org.libreplan.business.advance.entities.AdvanceAssignment;
import org.libreplan.business.common.IHumanIdentifiable;
import org.libreplan.business.common.IntegrationEntity;
import org.libreplan.business.common.Registry;
import org.libreplan.business.common.entities.EntitySequence;
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
import org.libreplan.business.resources.daos.ICriterionTypeDAO;
import org.springframework.stereotype.Component;
/**
* Base implementation of {@link ICriterionType} <br />

* @author Diego Pino García <dpino@igalia.com>
* @author Fernando Bellas Permuy <fbellas@udc.es>
*/
@Component
public class CriterionType extends IntegrationEntity implements
        ICriterionType<Criterion>, IHumanIdentifiable {

    public static CriterionType create() {
        return create(new CriterionType());
    }

    public static CriterionType create(String code) {
        return create(new CriterionType(), code);
    }

    public static CriterionType createUnvalidated(String code, String name,
        String description, Boolean allowHierarchy,
        Boolean allowSimultaneousCriterionsPerResource, Boolean enabled,
        ResourceEnum resource) {

        CriterionType criterionType = create(new CriterionType(), code);

        criterionType.name = name;
        criterionType.description = description;

        if (allowHierarchy != null) {
            criterionType.allowHierarchy = allowHierarchy;
        }

        if (allowSimultaneousCriterionsPerResource != null) {
            criterionType.allowSimultaneousCriterionsPerResource =
                allowSimultaneousCriterionsPerResource;
        }

        if (enabled != null) {
            criterionType.enabled = enabled;
        }

        if (resource != null) {
            criterionType.resource = resource;
        }

        return criterionType;

    }

    public void updateUnvalidated(String name, String description,
        Boolean allowHierarchy, Boolean allowSimultaneousCriterionsPerResource,
        Boolean enabled, ResourceEnum resource) {

        if (!StringUtils.isBlank(name)) {
            this.name = name;
        }

        if (!StringUtils.isBlank(description)) {
            this.description = description;
        }

        if (allowHierarchy != null) {
            this.allowHierarchy = allowHierarchy;
        }

        if (allowSimultaneousCriterionsPerResource != null) {
            this.allowSimultaneousCriterionsPerResource =
                allowSimultaneousCriterionsPerResource;
        }

        if (enabled != null) {
            this.enabled = enabled;
        }

        if (resource != null) {
            this.resource = resource;
        }

    }

    public static CriterionType create(String name,String description) {
        return create(new CriterionType(name,description));
    }

    public static CriterionType create(String name,String description,
            boolean allowHierarchy,boolean allowSimultaneousCriterionsPerResource,
            boolean enabled,ResourceEnum resource) {

        return create(new CriterionType(name,description, allowHierarchy,
            allowSimultaneousCriterionsPerResource,enabled,resource));

    }

    private String name;

    /**
     * The original name of the criterion type. It only exists for
     * CriterionTypes created from {@link PredefinedCriterionTypes}. Important:
     * This value must <strong>not</strong> be editable and should only be set
     * at creation time
     */
    private String predefinedTypeInternalName;

    private String description;

    private Boolean allowHierarchy = true;

    private Boolean allowSimultaneousCriterionsPerResource = true;

    private Boolean enabled = true;

    private ResourceEnum resource = ResourceEnum.getDefault();

    private Set<Criterion> criterions = new HashSet<Criterion>();

    private Integer lastCriterionSequenceCode = 0;
    /**
     * Constructor for hibernate. Do not use!
     */
    public CriterionType() {

    }

    private CriterionType(String name,String description) {
        this.name = name;
        this.description = description;
    }

    private CriterionType(String name,String description, boolean allowHierarchy,
            boolean allowSimultaneousCriterionsPerResource, boolean enabled,
            ResourceEnum resource) {

        this.allowHierarchy = allowHierarchy;
        this.allowSimultaneousCriterionsPerResource = allowSimultaneousCriterionsPerResource;
        this.enabled = enabled;
        this.name = name;
        this.description = description;
        this.resource = resource;
    }

    public static CriterionType fromPredefined(
            PredefinedCriterionTypes predefinedType) {
        CriterionType result = asCriterionType(predefinedType);
        result.predefinedTypeInternalName = predefinedType.getName();
        return result;
    }

    public static CriterionType asCriterionType(ICriterionType<?> criterionType) {
        return create(criterionType.getName(),criterionType.getDescription(),
                criterionType.allowHierarchy(), criterionType
        .isAllowSimultaneousCriterionsPerResource(),
                criterionType.isEnabled(),
                CriterionType.getResource(criterionType));
    }

    private static ResourceEnum getResource(ICriterionType<?> criterionType) {
        for (ResourceEnum resource : ResourceEnum.values()) {
            if (criterionType.criterionCanBeRelatedTo(resource.asClass())) {
                return resource;
            }
        }

        return ResourceEnum.getDefault();
    }

    @Override
    @NotEmpty(message="criterion type name not specified")
    public String getName() {
        return name;
    }

    public String getPredefinedTypeInternalName() {
        return predefinedTypeInternalName;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Valid
    public Set<Criterion> getCriterions() {
        return criterions;
    }

    public List<Criterion> getSortCriterions() {
        List<Criterion> criterions = new ArrayList<Criterion>(getCriterions());
        Collections.sort(criterions, new Comparator<Criterion>() {
            @Override
            public int compare(Criterion o1, Criterion o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
        return criterions;
    }

    public void setCriterions(Set<Criterion> criterions) {
        this.criterions = criterions;
    }

    @Override
    public boolean allowHierarchy() {
        return allowHierarchy == null ? false : allowHierarchy;
    }

    public void setAllowHierarchy(boolean allowHierarchy) {
        this.allowHierarchy = allowHierarchy;
    }

    @Override
    public boolean isAllowSimultaneousCriterionsPerResource() {
        return allowSimultaneousCriterionsPerResource == null ? false : allowSimultaneousCriterionsPerResource;
    }

    public void setAllowSimultaneousCriterionsPerResource(boolean allowSimultaneousCriterionsPerResource) {
        this.allowSimultaneousCriterionsPerResource = allowSimultaneousCriterionsPerResource;
    }

    public ResourceEnum getResource() {
        return resource;
    }

    public void setResource(ResourceEnum resource) {
        this.resource = resource;
    }

    @Override
    public Criterion createCriterion(String name) {
        return Criterion.withNameAndType(name, this);
    }

    public static Criterion createCriterion(
            PredefinedCriterionTypes predefinedCriterionType, String name) {

        CriterionType criterionType = CriterionType
                .fromPredefined(predefinedCriterionType);

        return Criterion.withNameAndType(name, criterionType);
    }

    @Override
    public Criterion createCriterionWithoutNameYet() {
        return Criterion.ofType(this);
    }

    @Override
    public boolean contains(ICriterion criterion) {
        if (criterion instanceof Criterion) {
            Criterion c = (Criterion) criterion;
            return this.equals(c.getType());
        } else {
            return false;
        }
    }

    /**
     * A {@link CriterionType} can be related with {@link Resource} matching
     * attribute resource and it's always related with resource of type RESOURCE
     */
    @Override
    public boolean criterionCanBeRelatedTo(Class<? extends Resource> klass) {
        return getResource().isAssignableFrom(klass);
    }


    /**
     * Two criterion types are equals if they both got the same name
     *
     * @param o
     * @return
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof CriterionType)) {
            return false;
        }

        CriterionType criterionType = (CriterionType) o;

        return new EqualsBuilder().append(criterionType.getName(),
                this.getName()).isEquals();
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + (this.name != null ? this.name.hashCode() : 0);
        return hash;
    }

    @Override
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    @Override
    public boolean isEnabled() {
        return enabled == null ? false : enabled;
    }

    @Override
    public boolean isImmutable(){
        return !isEnabled();
    }


    public int getNumCriterions(){
        return criterions.size();
    }

    public Criterion getCriterion(String criterionName)
        throws InstanceNotFoundException {

        for (Criterion c : criterions) {
            if (c.getName().equalsIgnoreCase(criterionName)) {
                return c;
            }
        }

        throw new InstanceNotFoundException(criterionName,
            Criterion.class.getName());

    }

    public Criterion getCriterionByCode(String code)
        throws InstanceNotFoundException {

        if (StringUtils.isBlank(code)) {
            throw new InstanceNotFoundException(code,
                 Criterion.class.getName());
        }

        for (Criterion c : criterions) {
            if (c.getCode().equalsIgnoreCase(StringUtils.trim(code))) {
                return c;
            }
        }

        throw new InstanceNotFoundException(code,
            Criterion.class.getName());

    }

    public Criterion getExistingCriterionByCode(String code) {

        try {
            return getCriterionByCode(code);
        } catch (InstanceNotFoundException e) {
            throw new RuntimeException(e);
        }

    }

    public boolean existsCriterionByCode(String code) {

        try {
            getCriterionByCode(code);
            return true;
        } catch (InstanceNotFoundException e) {
            return false;
        }

    }

    @AssertTrue(message="criterion codes must be unique inside a criterion " +
        " type")
    public boolean isConstraintNonRepeatedCriterionCodesConstraint() {
        return getFirstRepeatedCode(criterions) == null;
    }

    @AssertTrue(message="criterion names must be unique inside a criterion " +
        " type")
    public boolean isNonRepeatedCriterionNamesConstraint() {

        Set<String> criterionNames = new HashSet<String>();

        for (Criterion c : criterions) {
            if (!StringUtils.isBlank(c.getName())) {
                if (criterionNames.contains(c.getName().toLowerCase())) {
                    return false;
                } else {
                    criterionNames.add(c.getName().toLowerCase());
                }
            }
        }

        return true;

    }

    @AssertTrue(message="Criterion Type name is already being used")
    public boolean isUniqueCriterionTypeNameConstraint() {

        /* Check if it makes sense to check the constraint .*/
        if (!isNameSpecified()) {
            return true;
        }

        /* Check the constraint. */
        ICriterionTypeDAO criterionTypeDAO = Registry.getCriterionTypeDAO();

        if (isNewObject()) {
            return !criterionTypeDAO.existsByNameAnotherTransaction(this);
        } else {
            try {
                CriterionType c =
                    criterionTypeDAO.findUniqueByNameAnotherTransaction(name);
                return c.getId().equals(getId());
            } catch (InstanceNotFoundException e) {
                return true;
            }

        }

    }

    @AssertTrue(message="criterion type does not allow hierarchy")
    public boolean isAllowHierarchyConstraint() {

        if (!allowHierarchy) {
            for (Criterion c : criterions) {
                if (c.getParent() != null) {
                    return false;
                }
            }
        }

        return true;

    }

    @AssertTrue(message="resource type does not allow enabled criteria")
    public boolean isEnabledConstraint() {

        if (!enabled) {
            for (Criterion c : criterions) {
                if (c.isActive()) {
                    return false;
                }
            }
        }

        return true;

    }

    private boolean isNameSpecified() {
        return !StringUtils.isBlank(name);
    }


    @Override
    protected ICriterionTypeDAO getIntegrationEntityDAO() {
        return Registry.getCriterionTypeDAO();
    }

    /**
     * It checks there are no {@link AdvanceAssignment} any criteria of this
     * {@link CriterionType} has been assigned to any {@link Resource}
     * @throws ChangeTypeCriterionTypeException
     */
    @AssertTrue(message = "Criteria of this criterion type have been assigned to some resource.")
    protected boolean isChangeTypeConstraint() {
        /* Check the constraint. */
        ICriterionTypeDAO criterionTypeDAO = Registry.getCriterionTypeDAO();

        if (isNewObject()) {
            return true;
        }

        if (!criterionTypeDAO.hasDiferentTypeSaved(getId(), getResource())) {
            return true;
        }

        return (!(criterionTypeDAO
                .checkChildrenAssignedToAnyResource(this)));
    }

    @NotNull(message = "last criterion sequence code not specified")
    public Integer getLastCriterionSequenceCode() {
        return lastCriterionSequenceCode;
    }

    public void incrementLastCriterionSequenceCode() {
        if (this.lastCriterionSequenceCode == null) {
            this.lastCriterionSequenceCode = 0;
        }
        this.lastCriterionSequenceCode++;
    }

    public void setGenerateCode(Criterion criterion, int numberOfDigits) {
        if ((criterion.getCode() == null) || (criterion.getCode().isEmpty())
                || (!criterion.getCode().startsWith(getCode()))) {
            incrementLastCriterionSequenceCode();
            String criterionCode = EntitySequence.formatValue(numberOfDigits,
                    getLastCriterionSequenceCode());
            criterion.setCode(getCode()
                    + EntitySequence.CODE_SEPARATOR_CHILDREN + criterionCode);
        }
    }

    public String toString() {
        return name;
    }

    @Override
    public String getHumanId() {
        return name;
    }

}
TOP

Related Classes of org.libreplan.business.resources.entities.CriterionType

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.