<commit_before>/*
 * This file is part of NavalPlan
 *
 * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
 *                         Desenvolvemento Tecnolóxico de Galicia
 *
 * 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.navalplanner.business.resources.entities;

import static org.navalplanner.business.i18n.I18nHelper._;

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

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.NotNull;
import org.hibernate.validator.Valid;
import org.navalplanner.business.common.IntegrationEntity;
import org.navalplanner.business.common.Registry;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.resources.daos.ICriterionDAO;

/**
 * A criterion stored in the database <br />
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 */
public class Criterion extends IntegrationEntity implements ICriterion {

    private static final String ALL_WORKERS = _("[generic all workers]");

    public static Criterion createUnvalidated(String code, String name,
        CriterionType type, Criterion parent, Boolean active) {

        Criterion criterion = create(new Criterion(), code);

        criterion.name = name;
        criterion.type = type;
        criterion.parent = parent;

        if (active != null) {
            criterion.active = active;
        }

        return criterion;

    }

    public static List<Criterion> sortByName(Collection<Criterion> criterions) {
        List<Criterion> result = new ArrayList<Criterion>(criterions);
        Collections.sort(result, new Comparator<Criterion>() {

            @Override
            public int compare(Criterion o1, Criterion o2) {
                if (o1.getName() == null) {
                    return 1;
                }
                if (o2.getName() == null) {
                    return -1;
                }
                return o1.getName().compareTo(o2.getName());
            }
        });
        return result;
    }

    public static List<Criterion> sortByTypeAndName(Collection<Criterion> criterions) {
        List<Criterion> result = new ArrayList<Criterion>(criterions);
        Collections.sort(result, new Comparator<Criterion>() {

            @Override
            public int compare(Criterion o1, Criterion o2) {
                if (o1.getName() == null || o1.getType().getName() == null) {
                    return 1;
                }
                if (o2.getName() == null || o2.getType().getName() == null) {
                    return -1;
                }
                String name1 = o1.getType().getName() + " " + o1.getName();
                String name2 = o2.getType().getName() + " " + o2.getName();
                return name1.compareTo(name2);
            }
        });
        return result;
    }

    /**
     * Returns a string of criterion names separated by comma
     *
     * @param criteria
     * @return
     */
    public static String getNames(Collection<? extends Criterion> criteria) {
        List<String> names = new ArrayList<String>();
        for (Criterion each: criteria) {
            names.add(each.getName());
        }
        return (names.isEmpty()) ? Criterion.ALL_WORKERS : StringUtils.join(names, ",");
    }

    public void updateUnvalidated(String name, Boolean active) {

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

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

    }

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

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

    public static Criterion createPredefined(String name, CriterionType type) {
        Criterion result = create(name, type);
        result.predefinedCriterionInternalName = name;
        return result;
    }

    private String name;

    private String predefinedCriterionInternalName;

    private CriterionType type;

    private Criterion parent = null;

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

    private boolean active = true;

    private Set<CriterionRequirement> criterionRequirements = new HashSet<CriterionRequirement>();
    /*
     * Just for Hibernate mapping in order to have an unique constraint with
     * name and type properties.
     */
    private Long typeId;

    public static Criterion ofType(CriterionType type) {
        return create(type);
    }

    public static Criterion withNameAndType(String name, CriterionType type) {
        return create(name, type);
    }

    /**
     * Constructor for hibernate. Do not use!
     */
    public Criterion() {
    }

    private Criterion(CriterionType type) {
        Validate.notNull(type);

        this.type = type;
    }

    private Criterion(String name, CriterionType type) {
        Validate.notEmpty(name);
        Validate.notNull(type);

        this.name = name;
        this.type = type;
    }

    @Override
    public boolean isSatisfiedBy(Resource resource) {
        return !resource.getCurrentSatisfactionsFor(this).isEmpty();
    }

    @Override
    public boolean isSatisfiedBy(Resource resource, Date start, Date end) {
        return !resource.query().from(this).enforcedInAll(
                Interval.range(start, end)).result().isEmpty();
    }

    @Override
    public boolean isSatisfiedBy(Resource resource, Date atThisDate) {
        return !resource.query().from(this).enforcedInAll(
                Interval.point(atThisDate)).result().isEmpty();
    }

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

    public String getPredefinedCriterionInternalName() {
        return predefinedCriterionInternalName;
    }

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

    @NotNull(message="criterion type not specified")
    public CriterionType getType() {
        return type;
    }

    public void setType(CriterionType type) {
        this.type = type;
    }

    public String getCompleteName() {
        return type.getName() + " :: " + name;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public Criterion getParent() {
        return parent;
    }

    public void setParent(Criterion parent) {
        this.parent = parent;
    }

    @Valid
    public Set<Criterion> getChildren() {
        return children;
    }

    public void setChildren(Set<Criterion> children) {
        this.children = children;
    }

    public void moveTo(Criterion newParent) {

        if (parent == null) {

            if (newParent != null) {
                parent = newParent;
                parent.getChildren().add(this);
            }

        } else { // parent != null

            if (!parent.equals(newParent)) {
                parent.getChildren().remove(this);
                parent = newParent;
                if (parent != null) {
                    parent.getChildren().add(this);
                }
            }

        }

    }

    public boolean isEquivalent(ICriterion criterion) {
        if (criterion instanceof Criterion) {
            Criterion other = (Criterion) criterion;
            return new EqualsBuilder().append(getName(), other.getName())
                    .append(getType(), other.getType()).isEquals();
        }
        return false;
    }

    @AssertTrue(message="a disabled resource has enabled subresources")
    public boolean checkConstraintActive() {

        if (!active) {
            for (Criterion c : children) {
                if (c.isActive()) {
                    return false;
                }
            }
        }
        return true;

    }

    public Set<CriterionRequirement> getCriterionRequirements() {
        return Collections.unmodifiableSet(criterionRequirements);
    }

    public void setCriterionRequirements(
            Set<CriterionRequirement> criterionRequirements) {
        this.criterionRequirements = criterionRequirements;
    }

    public void removeCriterionRequirement(
            CriterionRequirement criterionRequirement) {
        this.criterionRequirements.remove(criterionRequirement);
    }

    public void addCriterionRequirement(
            CriterionRequirement criterionRequirement) {
        criterionRequirement.setCriterion(this);
        this.criterionRequirements.add(criterionRequirement);
    }

    @Override
    protected ICriterionDAO getIntegrationEntityDAO() {
        return Registry.getCriterionDAO();
    }

}
<commit_msg>Fix bug<commit_after>/*
 * This file is part of NavalPlan
 *
 * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
 *                         Desenvolvemento Tecnolóxico de Galicia
 *
 * 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.navalplanner.business.resources.entities;

import static org.navalplanner.business.i18n.I18nHelper._;

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

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.NotNull;
import org.hibernate.validator.Valid;
import org.navalplanner.business.common.IntegrationEntity;
import org.navalplanner.business.common.Registry;
import org.navalplanner.business.requirements.entities.CriterionRequirement;
import org.navalplanner.business.resources.daos.ICriterionDAO;

/**
 * A criterion stored in the database <br />
 * @author <NAME> <<EMAIL>>
 * @author <NAME> <<EMAIL>>
 */
public class Criterion extends IntegrationEntity implements ICriterion {

    public static Criterion createUnvalidated(String code, String name,
        CriterionType type, Criterion parent, Boolean active) {

        Criterion criterion = create(new Criterion(), code);

        criterion.name = name;
        criterion.type = type;
        criterion.parent = parent;

        if (active != null) {
            criterion.active = active;
        }

        return criterion;

    }

    public static List<Criterion> sortByName(Collection<Criterion> criterions) {
        List<Criterion> result = new ArrayList<Criterion>(criterions);
        Collections.sort(result, new Comparator<Criterion>() {

            @Override
            public int compare(Criterion o1, Criterion o2) {
                if (o1.getName() == null) {
                    return 1;
                }
                if (o2.getName() == null) {
                    return -1;
                }
                return o1.getName().compareTo(o2.getName());
            }
        });
        return result;
    }

    public static List<Criterion> sortByTypeAndName(Collection<Criterion> criterions) {
        List<Criterion> result = new ArrayList<Criterion>(criterions);
        Collections.sort(result, new Comparator<Criterion>() {

            @Override
            public int compare(Criterion o1, Criterion o2) {
                if (o1.getName() == null || o1.getType().getName() == null) {
                    return 1;
                }
                if (o2.getName() == null || o2.getType().getName() == null) {
                    return -1;
                }
                String name1 = o1.getType().getName() + " " + o1.getName();
                String name2 = o2.getType().getName() + " " + o2.getName();
                return name1.compareTo(name2);
            }
        });
        return result;
    }

    /**
     * Returns a string of criterion names separated by comma
     *
     * @param criteria
     * @return
     */
    public static String getNames(Collection<? extends Criterion> criteria) {
        List<String> names = new ArrayList<String>();
        for (Criterion each: criteria) {
            names.add(each.getName());
        }
        return (names.isEmpty()) ? allWorkersCaption() : StringUtils.join(
                names, ",");
    }

    private static String allWorkersCaption() {
        return _("[generic all workers]");
    }

    public void updateUnvalidated(String name, Boolean active) {

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

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

    }

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

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

    public static Criterion createPredefined(String name, CriterionType type) {
        Criterion result = create(name, type);
        result.predefinedCriterionInternalName = name;
        return result;
    }

    private String name;

    private String predefinedCriterionInternalName;

    private CriterionType type;

    private Criterion parent = null;

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

    private boolean active = true;

    private Set<CriterionRequirement> criterionRequirements = new HashSet<CriterionRequirement>();
    /*
     * Just for Hibernate mapping in order to have an unique constraint with
     * name and type properties.
     */
    private Long typeId;

    public static Criterion ofType(CriterionType type) {
        return create(type);
    }

    public static Criterion withNameAndType(String name, CriterionType type) {
        return create(name, type);
    }

    /**
     * Constructor for hibernate. Do not use!
     */
    public Criterion() {
    }

    private Criterion(CriterionType type) {
        Validate.notNull(type);

        this.type = type;
    }

    private Criterion(String name, CriterionType type) {
        Validate.notEmpty(name);
        Validate.notNull(type);

        this.name = name;
        this.type = type;
    }

    @Override
    public boolean isSatisfiedBy(Resource resource) {
        return !resource.getCurrentSatisfactionsFor(this).isEmpty();
    }

    @Override
    public boolean isSatisfiedBy(Resource resource, Date start, Date end) {
        return !resource.query().from(this).enforcedInAll(
                Interval.range(start, end)).result().isEmpty();
    }

    @Override
    public boolean isSatisfiedBy(Resource resource, Date atThisDate) {
        return !resource.query().from(this).enforcedInAll(
                Interval.point(atThisDate)).result().isEmpty();
    }

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

    public String getPredefinedCriterionInternalName() {
        return predefinedCriterionInternalName;
    }

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

    @NotNull(message="criterion type not specified")
    public CriterionType getType() {
        return type;
    }

    public void setType(CriterionType type) {
        this.type = type;
    }

    public String getCompleteName() {
        return type.getName() + " :: " + name;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public Criterion getParent() {
        return parent;
    }

    public void setParent(Criterion parent) {
        this.parent = parent;
    }

    @Valid
    public Set<Criterion> getChildren() {
        return children;
    }

    public void setChildren(Set<Criterion> children) {
        this.children = children;
    }

    public void moveTo(Criterion newParent) {

        if (parent == null) {

            if (newParent != null) {
                parent = newParent;
                parent.getChildren().add(this);
            }

        } else { // parent != null

            if (!parent.equals(newParent)) {
                parent.getChildren().remove(this);
                parent = newParent;
                if (parent != null) {
                    parent.getChildren().add(this);
                }
            }

        }

    }

    public boolean isEquivalent(ICriterion criterion) {
        if (criterion instanceof Criterion) {
            Criterion other = (Criterion) criterion;
            return new EqualsBuilder().append(getName(), other.getName())
                    .append(getType(), other.getType()).isEquals();
        }
        return false;
    }

    @AssertTrue(message="a disabled resource has enabled subresources")
    public boolean checkConstraintActive() {

        if (!active) {
            for (Criterion c : children) {
                if (c.isActive()) {
                    return false;
                }
            }
        }
        return true;

    }

    public Set<CriterionRequirement> getCriterionRequirements() {
        return Collections.unmodifiableSet(criterionRequirements);
    }

    public void setCriterionRequirements(
            Set<CriterionRequirement> criterionRequirements) {
        this.criterionRequirements = criterionRequirements;
    }

    public void removeCriterionRequirement(
            CriterionRequirement criterionRequirement) {
        this.criterionRequirements.remove(criterionRequirement);
    }

    public void addCriterionRequirement(
            CriterionRequirement criterionRequirement) {
        criterionRequirement.setCriterion(this);
        this.criterionRequirements.add(criterionRequirement);
    }

    @Override
    protected ICriterionDAO getIntegrationEntityDAO() {
        return Registry.getCriterionDAO();
    }

}

{'fraction_non_alphanumeric': 0.09520871889779971, 'fraction_numerical': 0.0038042360682706148, 'mean_word_length': 2.3522316043425815, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '684928', 'n_tokens_mistral': 5261, 'n_tokens_neox': 5065, 'n_words': 1352}