/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * 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 org.dashbuilder.navigation.impl; import java.util.ArrayList; import java.util.List; import org.dashbuilder.navigation.NavDivider; import org.dashbuilder.navigation.NavFactory; import org.dashbuilder.navigation.NavGroup; import org.dashbuilder.navigation.NavItem; import org.dashbuilder.navigation.NavItemContext; import org.dashbuilder.navigation.NavTree; import org.dashbuilder.navigation.NavItemVisitor; import org.jboss.errai.common.client.api.annotations.Portable; @Portable public class NavTreeImpl implements NavTree { private NavGroup root; public NavTreeImpl() { root = NavFactory.get().createNavGroup(); } public NavTreeImpl(NavGroup root) { this.root = root; } public List<NavItem> getRootItems() { return root.getChildren(); } @Override public NavItem getItemById(String id) { return getItemById(id, root.getChildren()); } private NavItem getItemById(String id, List<NavItem> navItemList) { if (id == null) { return null; } for (NavItem navItem : navItemList) { if (navItem.getId() != null && navItem.getId().equals(id)) { return navItem; } if (navItem instanceof NavGroup) { NavItem child = getItemById(id, ((NavGroup) navItem).getChildren()); if (child != null) { return child; } } } return null; } @Override public NavTree getItemAsTree(String id) { NavItem item = getItemById(id); return id != null ? NavFactory.get().createNavTree(item) : null; } @Override public List<NavItem> searchItems(NavItemContext ctx) { return searchItems(ctx, getRootItems()); } public List<NavItem> searchItems(NavItemContext ctx, List<NavItem> navItemList) { List<NavItem> result = new ArrayList<>(); if (ctx == null) { return result; } NavItemContext niCtx = NavItemContext.create(); for (NavItem navItem : navItemList) { niCtx.init(navItem.getContext()); if (niCtx.includesPropertiesOf(ctx)) { result.add(navItem); } if (navItem instanceof NavGroup) { List<NavItem> children = searchItems(ctx, ((NavGroup) navItem).getChildren()); result.addAll(children); } } return result; } @Override public NavGroup addGroup(String id, String name, String description, String parentId, boolean modifiable) { NavGroup newNavItem = NavFactory.get().createNavGroup(); newNavItem.setId(id); newNavItem.setName(name); newNavItem.setDescription(description); newNavItem.setModifiable(modifiable); addItem(newNavItem, parentId); return newNavItem; } @Override public NavItem addItem(String id, String name, String description, String parentId, boolean modifiable, String context) { NavItem newNavItem = NavFactory.get().createNavItem(); newNavItem.setId(id); newNavItem.setName(name); newNavItem.setDescription(description); newNavItem.setModifiable(modifiable); newNavItem.setContext(context); addItem(newNavItem, parentId); return newNavItem; } @Override public NavDivider addDivider(String parentId, boolean modifiable) { NavDivider newNavItem = NavFactory.get().createDivider(); newNavItem.setId(Integer.toString(newNavItem.hashCode())); newNavItem.setModifiable(modifiable); addItem(newNavItem, parentId); return newNavItem; } private void addItem(NavItem item, String parentId) { // Ensure the parent exists (if defined) NavItem parent = getItemById(parentId); if (parentId != null && parent == null) { throw new RuntimeException("Parent '" + parentId + "' not found"); } // Ensure the parent is a group if (parent != null && !(parent instanceof NavGroup)) { throw new RuntimeException("Parent '" + parentId + "' is not a group"); } // Register the item if (parent == null) { item.setParent(null); root.getChildren().add(item); } else { ((NavGroup) parent).getChildren().add(item); item.setParent((NavGroup) parent); } } @Override public NavItem deleteItem(String id) { NavItem navItem = getItemById(id); if (navItem != null) { if (navItem.getParent() == null) { root.getChildren().remove(navItem); } else { navItem.getParent().getChildren().remove(navItem); navItem.setParent(null); } } return navItem; } @Override public NavItem setItemName(String id, String name) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } navItem.setName(name); return navItem; } @Override public NavItem setItemDescription(String id, String description) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } navItem.setDescription(description); return navItem; } @Override public NavItem setItemModifiable(String id, boolean modifiable) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } navItem.setModifiable(modifiable); return navItem; } @Override public NavItem setItemContext(String id, String context) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } navItem.setContext(context); return navItem; } @Override public NavItem moveItem(String id, String newParentId) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } // Ensure the new target parent exists NavItem newParent = getItemById(newParentId); if (newParent == null && newParentId != null) { throw new RuntimeException("Parent not found: " + newParentId); } // Ensure the parent is a group if (newParent != null && !(newParent instanceof NavGroup)) { throw new RuntimeException("Parent '" + newParentId + "' is not a group"); } // Avoid loops if (newParentId != null && newParentId.equals(id)) { throw new RuntimeException("The parent can't be the item itself: " + newParentId); } // Do not move if nothing changes String parentId = navItem.getParent() != null ? navItem.getParent().getId(): null; if ((parentId == null && newParentId == null) || (parentId != null && newParentId != null && parentId.equals(newParentId))) { return navItem; } // Do move if (navItem.getParent() != null) { navItem.getParent().getChildren().remove(navItem); } navItem.setParent(null); if (newParent != null) { ((NavGroup) newParent).getChildren().add(navItem); navItem.setParent((NavGroup) newParent); } return navItem; } @Override public void moveItemFirst(String id) { changePosition(id, true, null); } @Override public void moveItemLast(String id) { changePosition(id, false, null); } @Override public void moveItemUp(String id) { changePosition(id, true, 1); } @Override public void moveItemDown(String id) { changePosition(id, false, 1); } public void changePosition(String id, boolean up, Integer npositions) { NavItem navItem = getItemById(id); if (navItem == null) { throw new RuntimeException("Item not found: " + id); } NavGroup parent = navItem.getParent(); List<NavItem> itemList = parent != null ? parent.getChildren() : getRootItems(); int idx = itemList.indexOf(navItem); int newPos = npositions == null ? (up ? 0 : itemList.size()-1) : (up ? idx-npositions: idx+npositions); if ((up && newPos < 0) || (!up && newPos > itemList.size()-1)) { throw new RuntimeException("Item '" + id + "' position out of range (old=" + idx + ", new=" + newPos + ")"); } itemList.remove(idx); itemList.add(newPos, navItem); } @Override public void accept(NavItemVisitor visitor) { for (NavItem item : root.getChildren()) { item.accept(visitor); } } @Override public NavTree cloneTree() { NavGroup rootClone = (NavGroup) this.root.cloneItem(); rootClone.getChildren().forEach(e -> e.setParent(null)); return new NavTreeImpl(rootClone); } }