Package eu.scape_project.planning.plato.wf

Source Code of eu.scape_project.planning.plato.wf.IdentifyRequirements

/*******************************************************************************
* Copyright 2006 - 2012 Vienna University of Technology,
* Department of Software Technology and Interactive Systems, IFS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package eu.scape_project.planning.plato.wf;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateful;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;

import org.slf4j.Logger;

import eu.scape_project.planning.exception.PlanningException;
import eu.scape_project.planning.manager.CriteriaManager;
import eu.scape_project.planning.manager.StorageException;
import eu.scape_project.planning.model.DigitalObject;
import eu.scape_project.planning.model.PlanState;
import eu.scape_project.planning.model.measurement.Measure;
import eu.scape_project.planning.model.policy.ControlPolicy;
import eu.scape_project.planning.model.policy.PreservationCase;
import eu.scape_project.planning.model.tree.Leaf;
import eu.scape_project.planning.model.tree.Node;
import eu.scape_project.planning.model.tree.ObjectiveTree;
import eu.scape_project.planning.model.tree.TreeNode;
import eu.scape_project.planning.xml.ProjectExporter;
import eu.scape_project.planning.xml.TreeLoader;

/**
* Business logic for workflow step Identify Requirements
*
* @author Markus Hamm, Michael Kraxner
*/
@Stateful
@ConversationScoped
public class IdentifyRequirements extends AbstractWorkflowStep {

    private static final long serialVersionUID = 1014116842177860229L;

    @Inject
    private Logger log;

    @Inject
    private TreeLoader treeLoader;

    @Inject
    private ProjectExporter projectExporter;

    @Inject
    private CriteriaManager criteriaManager;
   
    /**
     * Nodes to delete after accepting the performed changes (before save).
     */
    private List<TreeNode> nodesToDelete = new ArrayList<TreeNode>();
   
    /**
     * @see Leaf  measure
     */
    private List<Measure> measuresToDelete = new ArrayList<Measure>();

    public IdentifyRequirements() {
        this.requiredPlanState = PlanState.RECORDS_CHOSEN;
        this.correspondingPlanState = PlanState.TREE_DEFINED;
    }

    /**
     * Adds a new Leaf to the given Node.
     *
     * @param Node
     *            to attach the Leaf to.
     * @return New attached Leaf.
     */
    public Leaf addNewLeaf(Node node) {
        Leaf newLeaf = new Leaf();
        node.addChild(newLeaf);
        // this node has been changed()
        node.touch();
        return newLeaf;
    }

    /**
     * Adds a new Node to the given Node.
     *
     * @param Node
     *            to attach the Node to.
     * @return New attached Node.
     */
    public Node addNewNode(Node node) {
        Node newNode = new Node();
        node.addChild(newNode);
        // this node has been changed()
        node.touch();
        return newNode;
    }

    /**
     * Method responsible for removing a given node from its objective tree.
     *
     * @param node
     *            Node to remove.
     */
    public void removeTreeNode(TreeNode node) {
        if (node.getParent() != null) {
            // parent has been changed
            ((Node) node.getParent()).touch();
            ((Node) node.getParent()).removeChild(node);
        }
        nodesToDelete.add(node);
    }

    /**
     * Converts a given leaf to a node.
     *
     * @param leaf
     *            Leaf to convert.
     */
    public void convertToNode(Leaf leaf) {
        leaf.getParent().convertToNode(leaf);
    }

    /**
     * Converts a given node to a leaf.
     *
     * @param node
     *            Node to convert.
     */
    public void convertToLeaf(Node node) {
        node.getParent().convertToLeaf(node);
    }

    /**
     * Method responsible for retrieving a copy of a previously uploaded file
     * including its data.
     *
     * @param digitalObject
     *            DigitalObject stored in file system for which the data should
     *            be retrieved.
     * @return Copy of the given DigitalObject including its data
     * @throws StorageException
     *             is thrown if any error occurs at retrieving the result file.
     */
    public DigitalObject fetchAttachedFile(DigitalObject digitalObject) throws StorageException {
        return digitalObjectManager.getCopyOfDataFilledDigitalObject(digitalObject);
    }

    /**
     * Method responsible for attaching additional documentation files.
     *
     * @param digitalObject
     *            Digital object to attach
     * @throws StorageException
     *             is thrown if any error occurs at storing the given file.
     */
    public void attachFile(DigitalObject digitalObject) throws StorageException {
        digitalObjectManager.moveDataToStorage(digitalObject);
        plan.getRequirementsDefinition().getUploads().add(digitalObject);
        plan.getRequirementsDefinition().touch();

        addedBytestreams.add(digitalObject.getPid());
    }

    /**
     * Method responsible for removing a previously attached file.
     *
     * @param digitalObject
     *            Digital object to remove.
     */
    public void removeAttachedFile(DigitalObject digitalObject) {
        plan.getRequirementsDefinition().getUploads().remove(digitalObject);
        plan.getRequirementsDefinition().touch();

        bytestreamsToRemove.add(digitalObject.getPid());
    }

    /**
     * Method responsible for importing a requirements tree from a given
     * FreeMind file.
     *
     * @param file
     *            FreeMind file to import
     * @param includesUnits
     *            Indicates if the given FreeMind tree includes units
     * @return True if import was successful. False otherwise
     */
    public boolean importTreeFromFreeMind(DigitalObject file, boolean includesUnits) {
        log.debug("Start FreeMind import.");
        log.debug("FileName: " + file.getFullname());
        log.debug("HasUnits is: " + includesUnits);

        InputStream istream = new ByteArrayInputStream(file.getData().getData());
        ObjectiveTree newtree = treeLoader.loadFreeMindObjectiveTree(istream, includesUnits, true);

        if (newtree == null) {
            log.error("File is corrupted and new Tree cannot be built out of it.");
            return false;
        }

        // delete old tree
        nodesToDelete.add(plan.getTree().getRoot());

        // set new tree as plan tree
        plan.getTree().setRoot(newtree.getRoot());

        // make sure all scales are set according to measurement infos
        plan.getTree().adjustScalesToMeasurements();
        plan.getTree().setWeightsInitialized(false);

        log.debug("Imported FreeMind file successfully.");

        return true;
    }


    /**
     * Method responsible for exporting the current requirements tree as
     * FreeMind XML.
     *
     * @return Current requirements tree in FreeMind XML representation. A
     *         String including the XML-data is returned.
     */
    public String exportTreeAsFreeMindXML() {
        return projectExporter.exportTreeToFreemind(plan);
    }

    /**
     * Assigns the values of the given measure to the leaf. For this a copy of
     * the measure is created, the original measure is left unchanged.
     *
     * @param measure
     * @param leaf
     */
    public void assignMeasureToLeaf(final Measure measure, Leaf leaf) {
        Measure oldMeasure = leaf.getMeasure();
        if ((oldMeasure == null) || (!oldMeasure.getUri().equals(measure.getUri()))) {
            // schedule removal of old measure
            if (oldMeasure != null) {
                measuresToDelete.add(oldMeasure);
            }
            // and apply the new one
            leaf.applyMeasure(measure);
        }
    }

    /**
     * Method responsible for detaching a criterion from a leaf.
     *
     * @param leaf
     *            Leaf to detach the criterion from
     */
    public void detachCriterionFromLeaf(Leaf leaf) {
        leaf.setMeasure(null);
        leaf.touch();
    }

    @Override
    protected void saveStepSpecific() {
        resetTransformers();
        resetLeafValues();

        // this means the reference to the root has been changed, e.g. by
        // useTemplate (I think thats the only case, actually) -
        // so we need to get this ID back (otherwise, each subsequent SAVE will
        // result in a new entity persist)
        // simplest way: reload
        if (plan.getTree().getRoot().getId() == 0) {
            plan.getTree().setRoot(em.merge(plan.getTree().getRoot()));
        }

        prepareChangesForPersist.prepare(plan);

        saveEntity(plan.getRequirementsDefinition());
        saveEntity(plan.getTree());
        deleteOrphanedEntities();
    }

    @Override
    public void discard() throws PlanningException {
        super.discard();
        // We have to extend the standard discard function by the mandatory
        // clean-up of "nodes to delete"
        nodesToDelete.clear();
    }

    /**
     * Resets the transformer of all leaves to the default transformer.
     *
     * @see eu.scape_project.planning.IdentifyRequirements.workflow.IdentifyRequirementsAction#resetTransformers()
     */
    private void resetTransformers() {
        TreeNode root = plan.getTree().getRoot();
        for (Leaf leaf : root.getAllLeaves()) {
            /*
             * maybe the scaletype is not set yet -> leaf.setDefaultTransformer
             * has to handle null-values itself
             */
            if ((leaf.getScale() == null) || (leaf.getScale().isDirty())) {
                leaf.setDefaultTransformer();
            }
        }
    }

    /**
     * Method responsible for resetting leaf values.
     */
    private void resetLeafValues() {
        for (Leaf leaf : plan.getTree().getRoot().getAllLeaves()) {
            leaf.resetValues(plan.getAlternativesDefinition().getConsideredAlternatives());
        }
    }

    /**
     * deletes orphaned entities which are not removed by persistence provider automatically, namely:
     * - nodes
     * - measures
     */
    private void deleteOrphanedEntities() {
        for (TreeNode n : nodesToDelete) {
            if (n.getId() != 0) {
                removeEntity(n);
            }
        }
        nodesToDelete.clear();
       
        for (Measure m : measuresToDelete) {
            if (m.getId() != 0) {
                removeEntity(m);
            }
        }
        measuresToDelete.clear();
    }
    public boolean createTreeFromPreservationCase(PreservationCase preservationCase) {

        ObjectiveTree newTree = new ObjectiveTree();

        Node root = new Node();
        root.setName(preservationCase.getName());

        newTree.setRoot(root);

        for (ControlPolicy cp : preservationCase.getControlPolicies()) {

            Measure m = criteriaManager.getMeasure(cp.getMeasure().getUri());

            List<String> criteriaHierarchy = criteriaManager.getCategoryHierachy(m.getUri());

            Leaf leaf = createLeafInCriteriaHierarchy(newTree.getRoot(), criteriaHierarchy);

            if (leaf != null) {
                assignMeasureToLeaf(m, leaf);
            }

            log.info(criteriaHierarchy.toString());
        }

        nodesToDelete.add(plan.getTree().getRoot());

        // set new tree as plan tree
        plan.getTree().setRoot(newTree.getRoot());

        // make sure all scales are set according to measurement infos
        plan.getTree().adjustScalesToMeasurements();
        plan.getTree().setWeightsInitialized(false);

        log.debug("Tree created successfully.");

        return true;
    }

    private Leaf createLeafInCriteriaHierarchy(TreeNode node, List<String> criteriaHierarchy) {

        if (criteriaHierarchy.size() > 0) {

            for (TreeNode n : node.getChildren()) {
                if (n.getName().equalsIgnoreCase(criteriaHierarchy.get(0))) {
                    criteriaHierarchy.remove(0);
                    return createLeafInCriteriaHierarchy(n, criteriaHierarchy);
                }
            }

            Node newNode = new Node();
            newNode.setName(criteriaHierarchy.get(0));
            ((Node) node).addChild(newNode);

            criteriaHierarchy.remove(0);

            return createLeafInCriteriaHierarchy(newNode, criteriaHierarchy);
        } else {

            Leaf leaf = new Leaf();
            ((Node) node).addChild(leaf);

            return leaf;
        }
    }   
}
TOP

Related Classes of eu.scape_project.planning.plato.wf.IdentifyRequirements

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.