Package eu.planets_project.pp.plato.model.tree

Source Code of eu.planets_project.pp.plato.model.tree.ObjectiveTree

/*******************************************************************************
* Copyright (c) 2006-2010 Vienna University of Technology,
* Department of Software Technology and Interactive Systems
*
* All rights reserved. This program and the accompanying
* materials are made available under the terms of the
* Apache License, Version 2.0 which accompanies
* this distribution, and is available at
* http://www.apache.org/licenses/LICENSE-2.0
*******************************************************************************/

package eu.planets_project.pp.plato.model.tree;

import java.io.Serializable;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Transient;

import org.apache.commons.logging.Log;
import org.hibernate.validator.Valid;

import eu.planets_project.pp.plato.evaluation.MeasurementsDescriptor;
import eu.planets_project.pp.plato.model.Alternative;
import eu.planets_project.pp.plato.model.Values;
import eu.planets_project.pp.plato.model.scales.Scale;
import eu.planets_project.pp.plato.model.values.Value;
import eu.planets_project.pp.plato.util.MeasurementInfoUri;
import eu.planets_project.pp.plato.util.PlatoLogger;

/**
* This class is the container of the ObjectiveTree
* @author Christoph Becker
* @author Florian Motlik
* @author Kevin Stadler
* @see TreeNode
* @see Node
* @see Leaf
*/
@Entity
public class ObjectiveTree implements Serializable {

    private static Log log = PlatoLogger.getLogger(ObjectiveTree.class);

    private static final long serialVersionUID = -4894131307261590502L;

    /**
     * indicates where the initial balancing of weights in the objective tree
     * has been performed yet.
     * @see #initWeights()
     */
    private boolean weightsInitialized = false;

    /**
     * Checks if weights have been initialised ({@link #weightsInitialized}),
     * and if not, performs initialisation and sets {@link #weightsInitialized} to true.
     * The initialisation sets the weights of all leaves in the tree, i.e.
     * distributes all weights equally.
     * @see TreeNode#initWeights()
     * @see #weightsInitialized
     */
    public void initWeights() {
        if (this.isWeightsInitialized()) {
            log.debug("Weights already initialized");
        } else {
            log.debug("Initializing weights for the first time");
            root.setWeight(1.0);
            root.initWeights();
            this.setWeightsInitialized(true);
        }
    }
    /**
     * inits the value objects throughout the tree.
     * @see #initValues(List, int, boolean)
     * @param list of Alternatives
     * @param records number of samples
     */
    public void initValues(List<Alternative> list, int records) {
        initValues(list, records, false);
    }

    /**
     * inits the value objects throughout the tree.
     * @see Leaf#initValues(List, int, boolean)
     * @param list
     * @param records
     * @param initLinkage
     */
    public void initValues(List<Alternative> list, int records, boolean initLinkage) {
        root.initValues(list, records, initLinkage);
    }

    /**
     * reference to the root node of the objective tree.
     */
    @Valid
    @OneToOne(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    private TreeNode root;

    @Id @GeneratedValue
    private int id;
   
   
    @Transient
    private boolean mappingExistent;   

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    /**
     * empty default constructor
     *
     */
    public ObjectiveTree() {
    }

    /**
     * Checks the whole tree whether evaluation values for the given records and alternative exist.
     * This function is used then asking the user before removing
     * a record or alternative and the values associated with it from the objective tree.
     * @param records indices of sample records in the records list that should be checked
     * @param a the Alternative, or null if all alternatives should be checked
     * @return true if any leaf of the tree contains a value for the given records and alternative
     */
    public boolean hasValues(int records[], Set<String> checkAlternatives) {

        List<Leaf> list = root.getAllLeaves();

        if (list.size() > 0 && records.length > 0) {

            for (Leaf l : list) {
                for (String alt : checkAlternatives) {
                    if (hasValuesForRecords(l.getValues(alt), records)) {
                        return true;
                    }
                }
            }

        }

        return false;
    }

    /**
     * Checks whether the given Values-Object contains values for the specified records
     * @param values the Values-Object to be checked
     * @param records an array of record-indices
     * @return true if the Values-Object contains values at any of the indices
     */
    private boolean hasValuesForRecords(Values values, int records[]) {
        if (values != null) {
            List<Value> list = values.getList();
            for (int record : records) {
                if (record < list.size() && list.get(record) != null) {
                    return true;
                }
            }
        }
        return false;
    }

    public void setRoot(TreeNode root) {
        this.root = root;
    }

    public TreeNode getRoot() {
        return root;
    }

    /**
     * prints debug information for the whole tree
     */
    public void debug() {
        debug(root);
    }

    /**
     * recursively prints debug information on the provided node and its children
     */
    private void debug(TreeNode node) {
        if (node instanceof Leaf) {
            Leaf l = (Leaf)node;
            log.debug( "leaf: " + node.getName() + " has " + l.getValueMap().size() + " values.");
            for (String a : l.getValueMap().keySet()) {
                log.debug( "---" + a);
            }
        }
        for ( TreeNode n : node.getChildren() ) {
            debug(n);
        }
    }

    /**
     * removes associated evaluation {@link Values} for a given list of alternatives
     * and a give record index from all leaves in this tree.
     * @param list list of Alternatives for which values shall be removed
     * @param record index of the record for which  values shall be removed
     * @see Leaf#removeValues(List, int)
     */
    public void removeValues(List<Alternative> list, int record) {
        for (Leaf l : root.getAllLeaves())  {
           l.removeValues(list, record);
        }
    }
   
   
    /**
     * Removes all evaluation-values associated with the given alternative
     * from all leaves of the tree
     */
    public void removeValues(Alternative a) {
        for (Leaf l : root.getAllLeaves()) {
           l.getValueMap().remove(a.getName());
        }
    }
   

    /**
     * checks if this tree is specifed completely (i.e. all nodes have some leaves as
     * children and all leaves have a scale)
     * @param errorMessages the list to which error messages are appended
     * @see TreeNode#isCompletelySpecified(List)
     * @see Leaf#isCompletelySpecified(List)
     */
    public boolean isCompletelySpecified(List<String> errorMessages){
        return root.isCompletelySpecified(errorMessages);
    }

    /**
     * checks if this tree is evaluated completely (i.e. all leaves have
     * evaluation values for all alternatives and records)
     * @param inputList the list to which error messages are appended
     * @see TreeNode#isCompletelyEvaluated(List, List, List)
     * @see Leaf#isCompletelyEvaluated(List, List, List)
     */
    boolean isCompletelyEvaluated(List<Alternative> inputList){
        return false;
    }

    public boolean isWeightsInitialized() {
        return weightsInitialized;
    }

    public void setWeightsInitialized(boolean weightsInitialized) {
        this.weightsInitialized = weightsInitialized;
    }

    public boolean isMappingExistent() {
        for (Leaf leaf : getRoot().getAllLeaves()) {
            if (leaf.isMapped())
                return true;
        }
        return false;
    }

    /**
     * this method iterates through all leaves and updates the value maps,
     * changing the name of the alternative to the new one.
     * @param oldName old name to be updated
     * @param newName new name to be used instead of oldName
     * @see Leaf#updateAlternativeName(String, String)
     */
    public void updateAlternativeName(String oldName, String newName) {
        for (Leaf leaf: root.getAllLeaves()) {
            leaf.updateAlternativeName(oldName,newName);
        }
    }

    /**
     * <ul>
     * <li>
     * removes all {@link Values} from all leaves which are not mapped by one of the
     * names provided in the list
     * </li>
     * <li>
     * removes all {@link Value} objects in the {@link Values} which are out of the index of
     * the sample records (which should not happen, but apparently we have some projects where this
     * is the case), or where a leaf is single and there is more than one {@link Value}
     * </li>
     * </ul>
     * @param alternatives list of names of alternatives
     * @param records number of records in the project
     * @return number of {@link Values} and {@link Value} objects removed (sum of instances)
     * @see Leaf#removeLooseValues(List)
     */
    public int removeLooseValues(List<String> alternatives, int records) {
        int number = 0;
        for (Leaf l: getRoot().getAllLeaves()) {
            number += l.removeLooseValues(alternatives, records);
        }
        return number;
    }

    /**
     * This makes sure that the scales of all leaves match the scales implied by the measurement info uri
     * Can e.g. be used after freemind import, to complete the measurement info
     */
    public void adjustScalesToMeasurements(MeasurementsDescriptor descriptor) {
        for (Leaf l : getRoot().getAllLeaves()) {
            MeasurementInfoUri mInfo = l.getMeasurementInfo().toMeasurementInfoUri();
            if (mInfo.getAsURI() != null) {
                Scale s = descriptor.getMeasurementScale(mInfo);
                if (s != null) {
                    l.adjustScale(s);
                }
            }
        }
    }   
   
}
TOP

Related Classes of eu.planets_project.pp.plato.model.tree.ObjectiveTree

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.