Package name.abuchen.portfolio.ui.views.taxonomy

Source Code of name.abuchen.portfolio.ui.views.taxonomy.TaxonomyNode$ClassificationNode

package name.abuchen.portfolio.ui.views.taxonomy;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import name.abuchen.portfolio.model.Adaptable;
import name.abuchen.portfolio.model.Attributable;
import name.abuchen.portfolio.model.Classification;
import name.abuchen.portfolio.model.Classification.Assignment;
import name.abuchen.portfolio.model.InvestmentVehicle;
import name.abuchen.portfolio.model.Named;
import name.abuchen.portfolio.model.Security;
import name.abuchen.portfolio.ui.util.Colors;
import name.abuchen.portfolio.ui.views.taxonomy.TaxonomyModel.NodeVisitor;

public abstract class TaxonomyNode implements Adaptable
{
    /* protected */static class ClassificationNode extends TaxonomyNode
    {
        private Classification classification;

        public ClassificationNode(TaxonomyNode parent, Classification classification)
        {
            super(parent);
            this.classification = classification;
        }

        @Override
        public Classification getClassification()
        {
            return classification;
        }

        @Override
        public Assignment getAssignment()
        {
            return null;
        }

        @Override
        public int getWeight()
        {
            return classification.getWeight();
        }

        @Override
        public void setWeight(int weight)
        {
            classification.setWeight(weight);
        }

        @Override
        public int getRank()
        {
            return classification.getRank();
        }

        @Override
        public void setRank(int rank)
        {
            classification.setRank(rank);
        }

        @Override
        public String getName()
        {
            return classification.getName();
        }

        @Override
        public void setName(String name)
        {
            classification.setName(name);
        }

        @Override
        public String getId()
        {
            return classification.getId();
        }

        @Override
        public String getColor()
        {
            return classification.getColor();
        }

        @Override
        public <T> T adapt(Class<T> type)
        {
            if (type == Named.class)
                return type.cast(classification);
            else
                return super.adapt(type);
        }
    }

    /* protected */static class AssignmentNode extends TaxonomyNode
    {
        private Assignment assignment;

        public AssignmentNode(TaxonomyNode parent, Assignment assignment)
        {
            super(parent);
            this.assignment = assignment;
        }

        @Override
        public Security getBackingSecurity()
        {
            if (assignment.getInvestmentVehicle() instanceof Security)
                return (Security) assignment.getInvestmentVehicle();
            else
                return null;
        }

        @Override
        public Classification getClassification()
        {
            return null;
        }

        @Override
        public Assignment getAssignment()
        {
            return assignment;
        }

        @Override
        public int getWeight()
        {
            return assignment.getWeight();
        }

        @Override
        public void setWeight(int weight)
        {
            assignment.setWeight(weight);
        }

        @Override
        public int getRank()
        {
            return assignment.getRank();
        }

        @Override
        public void setRank(int rank)
        {
            assignment.setRank(rank);
        }

        @Override
        public String getName()
        {
            return assignment.getInvestmentVehicle().getName();
        }

        @Override
        public void setName(String name)
        {
            assignment.getInvestmentVehicle().setName(name);
        }

        @Override
        public String getId()
        {
            return assignment.getInvestmentVehicle().getUUID();
        }

        @Override
        public String getColor()
        {
            if (assignment.getInvestmentVehicle() instanceof Security)
                return Colors.EQUITY.asHex();
            else
                return Colors.CASH.asHex();
        }

        @Override
        public <T> T adapt(Class<T> type)
        {
            if (type == Named.class)
                return type.cast(assignment.getInvestmentVehicle());
            else
                return super.adapt(type);
        }
    }

    /* protected */static class UnassignedContainerNode extends ClassificationNode
    {
        public UnassignedContainerNode(TaxonomyNode parent, Classification classification)
        {
            super(parent, classification);
            setWeight(0);
        }

        @Override
        public boolean isUnassignedCategory()
        {
            return true;
        }

        @Override
        public String getColor()
        {
            return Colors.OTHER_CATEGORY.asHex();
        }
    }

    private TaxonomyNode parent;

    private List<TaxonomyNode> children = new ArrayList<TaxonomyNode>();
    private long actual;
    private long target;

    /* package */TaxonomyNode(TaxonomyNode parent)
    {
        this.parent = parent;
    }

    public TaxonomyNode getParent()
    {
        return parent;
    }

    public boolean isRoot()
    {
        return parent == null;
    }

    public List<TaxonomyNode> getChildren()
    {
        return children;
    }

    public TaxonomyNode getChildByInvestmentVehicle(InvestmentVehicle investmentVehicle)
    {
        for (TaxonomyNode child : children)
        {
            if (child.isAssignment() && investmentVehicle.equals(child.getAssignment().getInvestmentVehicle()))
                return child;
        }

        return null;
    }

    public Security getBackingSecurity()
    {
        return null;
    }

    public boolean isClassification()
    {
        return getClassification() != null;
    }

    public abstract Classification getClassification();

    public boolean isAssignment()
    {
        return getAssignment() != null;
    }

    public abstract Assignment getAssignment();

    public boolean isUnassignedCategory()
    {
        return false;
    }

    public long getActual()
    {
        return actual;
    }

    public void setActual(long actual)
    {
        this.actual = actual;
    }

    public long getTarget()
    {
        return target;
    }

    public void setTarget(long target)
    {
        this.target = target;
    }

    public abstract String getId();

    public abstract String getName();

    public abstract void setName(String name);

    public abstract int getWeight();

    public abstract void setWeight(int weight);

    public abstract int getRank();

    public abstract void setRank(int rank);

    public abstract String getColor();

    public List<TaxonomyNode> getPath()
    {
        LinkedList<TaxonomyNode> path = new LinkedList<TaxonomyNode>();

        TaxonomyNode item = this;
        while (item != null)
        {
            path.addFirst(item);
            item = item.getParent();
        }

        return path;
    }

    @Override
    public <T> T adapt(Class<T> type)
    {
        if (type == Security.class)
            return type.cast(getBackingSecurity());
        else if (type == Attributable.class)
            return type.cast(getBackingSecurity());
        else
            return null;
    }

    /* package */TaxonomyNode addChild(Classification newClassification)
    {
        Classification classification = getClassification();
        if (classification == null)
            return null;

        newClassification.setWeight(Classification.ONE_HUNDRED_PERCENT - classification.getChildrenWeight());
        newClassification.setParent(classification);
        classification.addChild(newClassification);

        TaxonomyNode newChild = new ClassificationNode(this, newClassification);

        int insertAt = isRoot() ? children.size() - 1 : children.size();
        children.add(insertAt, newChild);
        for (int ii = 0; ii < children.size(); ii++)
            children.get(ii).setRank(ii);

        return newChild;
    }

    /* package */TaxonomyNode addChild(Assignment newAssignment)
    {
        Classification classification = getClassification();
        if (classification == null)
            return null;

        classification.addAssignment(newAssignment);

        TaxonomyNode newChild = new AssignmentNode(this, newAssignment);
        newChild.setRank(getTopRank() + 1);
        children.add(newChild);
        return newChild;
    }

    /* package */void removeChild(TaxonomyNode node)
    {
        Classification classification = getClassification();
        if (classification == null)
            throw new UnsupportedOperationException();

        if (node.isClassification())
            classification.getChildren().remove(node.getClassification());
        else
            classification.getAssignments().remove(node.getAssignment());

        children.remove(node);
    }

    /* package */void moveTo(TaxonomyNode target)
    {
        moveTo(-1, target);
    }

    private void moveTo(int index, TaxonomyNode target)
    {
        Classification classification = target.getClassification();
        if (classification == null)
            throw new UnsupportedOperationException();

        // if node is assignment *and* target contains assignment for same
        // investment vehicle *then* merge nodes

        if (isAssignment())
        {
            InvestmentVehicle investmentVehicle = getAssignment().getInvestmentVehicle();
            TaxonomyNode sibling = target.getChildByInvestmentVehicle(investmentVehicle);

            if (sibling != null)
            {
                sibling.absorb(this);
                return;
            }
        }

        // change parent, update children collections and rank

        this.getParent().removeChild(this);
        this.parent = target;

        if (isClassification())
        {
            getClassification().setParent(classification);
            classification.getChildren().add(getClassification());
        }
        else
        {
            classification.getAssignments().add(getAssignment());
        }
        List<TaxonomyNode> siblings = target.getChildren();

        if (index == -1)
            index = siblings.size();

        int insertAt = target.isRoot() ? Math.min(index, siblings.size() - 1) : index;
        siblings.add(insertAt, this);

        for (int ii = 0; ii < siblings.size(); ii++)
            siblings.get(ii).setRank(ii);
    }

    /* package */void insertAfter(TaxonomyNode target)
    {
        moveRelativeTo(target, 1);
    }

    /* package */void insertBefore(TaxonomyNode target)
    {
        moveRelativeTo(target, 0);
    }

    private void moveRelativeTo(TaxonomyNode target, int offset)
    {
        if (target.isRoot())
            return;

        if (target.getParent() == getParent())
        {
            List<TaxonomyNode> siblings = getParent().getChildren();
            siblings.remove(this);

            int targetAt = siblings.indexOf(target) + offset;
            int insertAt = target.getParent().isRoot() ? Math.min(targetAt, siblings.size() - 1) : targetAt;

            siblings.add(insertAt, this);

            for (int ii = 0; ii < siblings.size(); ii++)
                siblings.get(ii).setRank(ii);
        }
        else
        {
            int index = target.getParent().getChildren().indexOf(target);
            moveTo(index + offset, target.getParent());
        }
    }

    private void absorb(TaxonomyNode node)
    {
        if (!node.getAssignment().getInvestmentVehicle().equals(getAssignment().getInvestmentVehicle()))
            throw new UnsupportedOperationException();

        node.getParent().removeChild(node);

        int weight = Math.min(getWeight() + node.getWeight(), Classification.ONE_HUNDRED_PERCENT);
        setWeight(weight);
    }

    /* package */int getTopRank()
    {
        if (children.isEmpty())
            return -1;
        return children.get(children.size() - 1).getRank();
    }

    public void accept(NodeVisitor visitor)
    {
        visitor.visit(this);

        for (TaxonomyNode child : new ArrayList<TaxonomyNode>(children))
            child.accept(visitor);
    }
}
TOP

Related Classes of name.abuchen.portfolio.ui.views.taxonomy.TaxonomyNode$ClassificationNode

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.