diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java
index 8a4543cde..b1d5d390b 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java
@@ -211,9 +211,9 @@ public class OrderElementTreeController extends GenericForwardComposer {
snapshotOfOpenedNodes = TreeViewStateSnapshot.snapshotOpened(tree);
try {
if (tree.getSelectedCount() == 1) {
- getModel().addOrderElementAt(getSelectedNode());
+ getModel().addElementAt(getSelectedNode());
} else {
- getModel().addOrderElement();
+ getModel().addElement();
}
filterByPredicateIfAny();
} catch (IllegalStateException e) {
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java
index d2a5405dc..3245d6a8f 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeModel.java
@@ -20,116 +20,31 @@
package org.navalplanner.web.orders;
-import static org.navalplanner.web.I18nHelper._;
+import static org.navalplanner.business.i18n.I18nHelper._;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.orders.entities.OrderLine;
-import org.navalplanner.business.orders.entities.OrderLineGroup;
-import org.zkoss.ganttz.util.MutableTreeModel;
-import org.zkoss.zul.TreeModel;
+import org.navalplanner.business.trees.ITreeNode;
+import org.navalplanner.business.trees.ITreeParentNode;
+import org.navalplanner.web.orders.components.EntitiesTree;
/**
* Model for a the {@link OrderElement} tree for a {@link Order}
* @author Lorenzo Tilve Álvaro
* @author Diego Pino García
*/
-public class OrderElementTreeModel {
+public class OrderElementTreeModel extends EntitiesTree {
- private static MutableTreeModel createTreeFrom(Order order) {
- MutableTreeModel treeModel = MutableTreeModel
- .create(
- OrderElement.class, order);
- OrderElement parent = treeModel.getRoot();
- List orderElements = order.getOrderElements();
- treeModel.add(parent, orderElements);
- addChildren(treeModel, orderElements);
- return treeModel;
+ public OrderElementTreeModel(OrderElement root,
+ List rootChildren) {
+ super(OrderElement.class, root, rootChildren);
}
- private static MutableTreeModel createTreeFrom(Order order,
- List orderElements) {
- MutableTreeModel treeModel = MutableTreeModel.create(
- OrderElement.class, order);
- OrderElement parent = treeModel.getRoot();
- treeModel.add(parent, orderElements);
- addChildren(treeModel, orderElements);
- return treeModel;
- }
-
- private static void addChildren(MutableTreeModel treeModel,
- List orderElements) {
- for (OrderElement orderElement : orderElements) {
- treeModel.add(orderElement, orderElement.getChildren());
- addChildren(treeModel, orderElement.getChildren());
- }
- }
-
- private MutableTreeModel tree;
-
- public OrderElementTreeModel(Order order) {
- tree = createTreeFrom(order);
- }
-
- public OrderElementTreeModel(Order order, List orderElements) {
- tree = createTreeFrom(order, orderElements);
- }
-
- public TreeModel asTree() {
- return tree;
- }
-
- public void addOrderElement() {
- addOrderElementAtImpl(tree.getRoot());
- }
-
- private OrderElement createNewOrderElement() {
- OrderElement newOrderElement = OrderLine
- .createOrderLineWithUnfixedPercentage(0);
- newOrderElement.setName(_("New order element"));
- return newOrderElement;
- }
-
- public void addOrderElementAt(OrderElement node) {
- addOrderElementAtImpl(node);
- }
-
- private void addOrderElementAtImpl(OrderElement parent) {
- addOrderElementAt(parent, createNewOrderElement());
-
- }
-
- private void addToTree(OrderElement parentNode, OrderElement elementToAdd) {
- tree.add(parentNode, elementToAdd);
- addChildren(tree, Arrays.asList(elementToAdd));
- }
-
- private void addToTree(OrderElement parentNode, int position,
- OrderElement elementToAdd) {
- tree.add(parentNode, position, Arrays.asList(elementToAdd));
- addChildren(tree, Arrays.asList(elementToAdd));
- }
-
- private void addOrderElementAt(OrderElement parent,
- OrderElement orderElement) {
- OrderLineGroup container = turnIntoContainerIfNeeded(parent);
- container.add(orderElement);
- addToTree(toNode(container), orderElement);
- updateCriterionRequirementsInHierarchy(parent, orderElement,
- (OrderElement) container);
- }
-
- private void addOrderElementAt(OrderElement destinationNode,
- OrderElement elementToAdd, int position) {
- OrderLineGroup container = turnIntoContainerIfNeeded(destinationNode);
- container.add(position, elementToAdd);
- addToTree(toNode(container), position, elementToAdd);
- updateCriterionRequirementsInHierarchy(destinationNode, elementToAdd,
- (OrderElement) container);
+ public OrderElementTreeModel(OrderElement root) {
+ super(OrderElement.class, root);
}
private void updateCriterionRequirementsInHierarchy(
@@ -142,130 +57,19 @@ public class OrderElementTreeModel {
}
}
- private OrderElement toNode(OrderLineGroup container) {
- return container;
+ @Override
+ protected void added(ITreeNode destination,
+ ITreeNode added,
+ ITreeParentNode turnedIntoContainer) {
+ updateCriterionRequirementsInHierarchy(destination.getThis(), added
+ .getThis(), turnedIntoContainer.getThis());
}
- private OrderLineGroup turnIntoContainerIfNeeded(
- OrderElement selectedForTurningIntoContainer) {
- if (selectedForTurningIntoContainer instanceof OrderLineGroup) {
- return (OrderLineGroup) selectedForTurningIntoContainer;
- }
- OrderLineGroup parentContainer = asOrderLineGroup(getParent(selectedForTurningIntoContainer));
- OrderLineGroup asContainer = selectedForTurningIntoContainer
- .toContainer();
- parentContainer.replace(selectedForTurningIntoContainer, asContainer);
- tree.replace(selectedForTurningIntoContainer, asContainer);
- addChildren(tree, Arrays.asList((OrderElement) asContainer));
- return asContainer;
- }
-
- private OrderElement getParent(OrderElement node) {
- return tree.getParent(node);
- }
-
- public List getParents(OrderElement node) {
- return tree.getParents(node);
- }
-
- public void indent(OrderElement nodeToIndent) {
- OrderElement parentOfSelected = tree.getParent(nodeToIndent);
- int position = getChildren(parentOfSelected).indexOf(nodeToIndent);
- if (position == 0) {
- return;
- }
- OrderElement destination = (OrderElement) getChildren(parentOfSelected)
- .get(position - 1);
- move(nodeToIndent, destination, getChildren(destination).size());
- }
-
- private List getChildren(OrderElement node) {
- List result = new ArrayList();
- final int childCount = tree.getChildCount(node);
- for (int i = 0; i < childCount; i++) {
- result.add(tree.getChild(node, i));
- }
- return result;
- }
-
- public void unindent(OrderElement nodeToUnindent) {
- OrderElement parent = tree.getParent(nodeToUnindent);
- if (tree.isRoot(parent)) {
- return;
- }
- OrderElement destination = tree.getParent(parent);
- move(nodeToUnindent, destination, getChildren(destination).indexOf(
- parent) + 1);
- }
-
- public void move(OrderElement toBeMoved, OrderElement destination) {
- move(toBeMoved, destination, getChildren(destination).size());
- }
-
- public void moveToRoot(OrderElement toBeMoved) {
- move(toBeMoved, tree.getRoot(), 0);
- }
-
- private void move(OrderElement toBeMoved, OrderElement destination,
- int position) {
- if (getChildren(destination).contains(toBeMoved)) {
- return;// it's already moved
- }
- if (isGreatInHierarchy(toBeMoved, destination)) {
- return;
- }
- removeNode(toBeMoved);
- addOrderElementAt(destination, toBeMoved, position);
- }
-
- private boolean isGreatInHierarchy(OrderElement parent, OrderElement child) {
- return find(child, getChildren(parent));
- }
-
- private boolean find(OrderElement child, List children) {
- if (children.indexOf(child) >= 0) {
- return true;
- }
- for (OrderElement criterionDTO : children) {
- return find(child, getChildren(criterionDTO));
- }
- return false;
- }
-
- public void up(OrderElement node) {
- OrderLineGroup orderLineGroup = asOrderLineGroup(tree.getParent(node));
- orderLineGroup.up(node);
- tree.up(node);
- }
-
- public void down(OrderElement node) {
- OrderLineGroup orderLineGroup = asOrderLineGroup(tree.getParent(node));
- orderLineGroup.down(node);
- tree.down(node);
- }
-
- private OrderLineGroup asOrderLineGroup(OrderElement node) {
- return (OrderLineGroup) node;
- }
-
- public void removeNode(OrderElement orderElement) {
- if (orderElement == tree.getRoot()) {
- return;
- }
- OrderLineGroup parent = asOrderLineGroup(tree.getParent(orderElement));
- parent.remove(orderElement);
- tree.remove(orderElement);
- // If removed node was the last one and its parent is not the root node
- if (!tree.isRoot(parent) && tree.getChildCount(parent) == 0) {
- OrderElement asLeaf = ((OrderElement) parent).toLeaf();
- OrderElement parentContainer = getParent(toNode(parent));
- asOrderLineGroup(parentContainer).replace((OrderElement) parent,
- asLeaf);
- tree.replace((OrderElement) parent, asLeaf);
- }
- }
-
- public int[] getPath(OrderElement orderElement) {
- return tree.getPath(tree.getRoot(), orderElement);
+ @Override
+ protected OrderElement createNewElement() {
+ OrderElement newOrderElement = OrderLine
+ .createOrderLineWithUnfixedPercentage(0);
+ newOrderElement.setName(_("New order element"));
+ return newOrderElement;
}
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/components/EntitiesTree.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/components/EntitiesTree.java
new file mode 100644
index 000000000..cecd13e04
--- /dev/null
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/components/EntitiesTree.java
@@ -0,0 +1,241 @@
+/*
+ * This file is part of ###PROJECT_NAME###
+ *
+ * Copyright (C) 2009 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 .
+ */
+package org.navalplanner.web.orders.components;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.navalplanner.business.orders.entities.OrderElement;
+import org.navalplanner.business.trees.ITreeNode;
+import org.navalplanner.business.trees.ITreeParentNode;
+import org.zkoss.ganttz.util.MutableTreeModel;
+import org.zkoss.zul.TreeModel;
+
+/**
+ * @author Óscar González Fernández
+ *
+ */
+public abstract class EntitiesTree> {
+
+ protected static > MutableTreeModel createTreeFrom(
+ Class type, T tree) {
+ List children = tree.getChildren();
+ return createTreeFrom(type, tree, children);
+ }
+
+ protected static > MutableTreeModel createTreeFrom(
+ Class type, T tree, List children) {
+ MutableTreeModel treeModel = MutableTreeModel.create(type, tree);
+ T parent = treeModel.getRoot();
+ treeModel.add(parent, children);
+ addChildren(treeModel, children);
+ return treeModel;
+ }
+
+ private static > void addChildren(
+ MutableTreeModel treeModel, List children) {
+ for (T each : children) {
+ treeModel.add(each, each.getChildren());
+ addChildren(treeModel, each.getChildren());
+ }
+ }
+
+ private MutableTreeModel tree;
+
+ protected EntitiesTree(Class type, T root) {
+ tree = createTreeFrom(type, root);
+ }
+
+ protected EntitiesTree(Class type, T root, List rootChildren) {
+ tree = createTreeFrom(type, root, rootChildren);
+ }
+
+ public TreeModel asTree() {
+ return tree;
+ }
+
+ public void addElement() {
+ addElementAtImpl(tree.getRoot());
+ }
+
+ protected abstract T createNewElement();
+
+ public void addElementAt(T node) {
+ addElementAtImpl(node);
+ }
+
+ private void addElementAtImpl(T parent) {
+ addOrderElementAt(parent, createNewElement());
+
+ }
+
+ private void addToTree(ITreeNode parentNode, ITreeNode elementToAdd) {
+ tree.add(parentNode.getThis(), elementToAdd.getThis());
+ addChildren(tree, Collections.singletonList(elementToAdd.getThis()));
+ }
+
+ private void addToTree(ITreeNode parentNode, int position,
+ ITreeNode elementToAdd) {
+ List children = Collections
+ .singletonList(elementToAdd.getThis());
+ tree.add(parentNode.getThis(), position, children);
+ addChildren(tree, children);
+ }
+
+ private void addOrderElementAt(ITreeNode parent, ITreeNode element) {
+ ITreeParentNode container = turnIntoContainerIfNeeded(parent);
+ container.add(element.getThis());
+ addToTree(container.getThis(), element);
+ added(parent, element, container);
+ }
+
+ private void addOrderElementAt(ITreeNode destinationNode,
+ ITreeNode elementToAdd, int position) {
+ ITreeParentNode container = turnIntoContainerIfNeeded(destinationNode);
+ container.add(position, elementToAdd.getThis());
+ addToTree(container, position, elementToAdd);
+ added(destinationNode, elementToAdd, container);
+ }
+
+ protected abstract void added(ITreeNode destination, ITreeNode added,
+ ITreeParentNode turnedIntoContainer);
+
+ private ITreeParentNode turnIntoContainerIfNeeded(
+ ITreeNode selectedForTurningIntoContainer) {
+ if (selectedForTurningIntoContainer instanceof ITreeParentNode) {
+ return (ITreeParentNode) selectedForTurningIntoContainer;
+ }
+ ITreeParentNode parentContainer = getParent(selectedForTurningIntoContainer);
+ ITreeParentNode asContainer = selectedForTurningIntoContainer
+ .toContainer();
+ parentContainer.replace(selectedForTurningIntoContainer.getThis(),
+ asContainer.getThis());
+ tree.replace(selectedForTurningIntoContainer.getThis(), asContainer
+ .getThis());
+ addChildren(tree, Collections.singletonList(asContainer.getThis()));
+ return asContainer;
+ }
+
+ private ITreeParentNode getParent(ITreeNode node) {
+ return (ITreeParentNode) tree.getParent(node.getThis());
+ }
+
+ public List getParents(T node) {
+ return tree.getParents(node);
+ }
+
+ public void indent(T nodeToIndent) {
+ T parentOfSelected = tree.getParent(nodeToIndent);
+ int position = getChildren(parentOfSelected).indexOf(nodeToIndent);
+ if (position == 0) {
+ return;
+ }
+ T destination = getChildren(parentOfSelected)
+ .get(position - 1);
+ move(nodeToIndent, destination, getChildren(destination).size());
+ }
+
+ private List getChildren(T node) {
+ List result = new ArrayList();
+ final int childCount = tree.getChildCount(node);
+ for (int i = 0; i < childCount; i++) {
+ result.add(tree.getChild(node, i));
+ }
+ return result;
+ }
+
+ public void unindent(T nodeToUnindent) {
+ T parent = tree.getParent(nodeToUnindent);
+ if (tree.isRoot(parent)) {
+ return;
+ }
+ T destination = tree.getParent(parent);
+ move(nodeToUnindent, destination, getChildren(destination).indexOf(
+ parent) + 1);
+ }
+
+ public void move(T toBeMoved, T destination) {
+ move(toBeMoved, destination, getChildren(destination).size());
+ }
+
+ public void moveToRoot(T toBeMoved) {
+ move(toBeMoved, tree.getRoot(), 0);
+ }
+
+ private void move(T toBeMoved, T destination,
+ int position) {
+ if (getChildren(destination).contains(toBeMoved)) {
+ return;// it's already moved
+ }
+ if (isGreatInHierarchy(toBeMoved, destination)) {
+ return;
+ }
+ removeNode(toBeMoved);
+ addOrderElementAt(destination, toBeMoved, position);
+ }
+
+ private boolean isGreatInHierarchy(T parent, T child) {
+ return find(child, getChildren(parent));
+ }
+
+ private boolean find(T child, List children) {
+ if (children.indexOf(child) >= 0) {
+ return true;
+ }
+ for (T each : children) {
+ return find(child, getChildren(each));
+ }
+ return false;
+ }
+
+ public void up(T node) {
+ ITreeParentNode parent = getParent(node);
+ parent.up(node);
+ tree.up(node);
+ }
+
+ public void down(T node) {
+ ITreeParentNode parent = getParent(node);
+ parent.down(node);
+ tree.down(node);
+ }
+
+ public void removeNode(T element) {
+ if (element == tree.getRoot()) {
+ return;
+ }
+ ITreeParentNode parent = getParent(element);
+ parent.remove(element);
+ tree.remove(element);
+ // If removed node was the last one and its parent is not the root node
+ if (!tree.isRoot(parent.getThis()) && tree.getChildCount(parent) == 0) {
+ T asLeaf = parent.toLeaf();
+ ITreeParentNode parentContainer = getParent(parent.getThis());
+ parentContainer.replace(parent.getThis(), asLeaf);
+ tree.replace(parent.getThis(), asLeaf);
+ }
+ }
+
+ public int[] getPath(OrderElement orderElement) {
+ return tree.getPath(tree.getRoot(), orderElement);
+ }
+
+}