.classpath
| 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
| 282 ++++++----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
| 2
3 files changed, 176 insertions(+), 112 deletions(-)
New commits:
commit 59b91a699378df0cae55ea6575760e9f4ff6db2c
Merge: 20c1c7a... 6d06818...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Oct 7 09:32:46 2010 -0400
Merge branch 'master-jay'
commit 6d06818fbee4c424aa539baaed36634aa513c785
Merge: e7acef3... b1efc02...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Oct 7 08:59:31 2010 -0400
Unfortunately ended up mixing a merge resolution with feature work:
-- Fix ResourceTree rendering for direct nav to "deep" nodes (like JmsXA).
There were a few issues here. So far there have been some changes to
ensure proper ordering of tree nodes for parent-child relationships,
and more protection against node duplication.
This should fix the rendering but we have some other
issues resulting in the attemot to add duplicate resource nodes, and also,
I think, building the tree twice prior to rendering. I'll look into
these issues now but at least the tree should render correctly.
-- Merge branch 'master' into master-jay
Conflicts:
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
diff --cc .classpath
index 0b4abf3,1a1236c..7d1cd22
--- a/.classpath
+++ b/.classpath
@@@ -252,10 -252,9 +252,9 @@@
<classpathentry exported="true" kind="var"
path="M2_REPO/com/google/gwt/gwt-user/2.0.3/gwt-user-2.0.3.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/com/google/gwt/gwt-dev/2.0.3/gwt-dev-2.0.3.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/com/smartgwt/smartgwt/2.2/smartgwt-2.2.jar"/>
-- <classpathentry exported="true" kind="var"
path="M2_REPO/com/google/code/gwt-log/gwt-log/3.0.3/gwt-log-3.0.3.jar"/>
-- <classpathentry exported="true" kind="var"
path="M2_REPO/ca/nanometrics/gflot/1.0.0/gflot-1.0.0.jar"/>
++ <classpathentry exported="true" kind="var"
path="M2_REPO/com/google/code/gwt-log/gwt-log/3.0.3/gwt-log-3.0.3.jar"/>
++ <classpathentry exported="true" kind="var"
path="M2_REPO/ca/nanometrics/gflot/1.0.0/gflot-1.0.0.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/com/jcraft/jsch/0.1.29/jsch-0.1.29.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/commons-jxpath/commons-jxpath/1.3/commons-jxpath-1.3.jar"/>
- <classpathentry exported="true" kind="var"
path="M2_REPO/com/google/code/gwt-log/gwt-log/3.0.3/gwt-log-3.0.3.jar"/>
<classpathentry kind="output" path="eclipse-classes"/>
</classpath>
diff --cc
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
index d577c4d,d577c4d..17012f8
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
@@@ -20,9 -20,9 +20,8 @@@ package org.rhq.enterprise.gui.coregui.
import java.util.ArrayList;
import java.util.EnumSet;
--import java.util.HashMap;
++import java.util.HashSet;
import java.util.List;
--import java.util.Map;
import java.util.Set;
import com.google.gwt.user.client.rpc.AsyncCallback;
@@@ -38,7 -38,7 +37,6 @@@ import com.smartgwt.client.widgets.tree
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.Resource;
--import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceSubCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
@@@ -132,7 -132,7 +130,8 @@@ public class ResourceTreeDatasource ext
return;
} else {
-- com.allen_sauer.gwt.log.client.Log.info("ResourceTreeDatasource:
Loading Resource [" + parentResourceId + "]...");
++ com.allen_sauer.gwt.log.client.Log.info("ResourceTreeDatasource:
Loading Resource [" + parentResourceId
++ + "]...");
criteria.addFilterParentResourceId(Integer.parseInt(parentResourceId));
}
@@@ -176,85 -176,85 +175,196 @@@
* @return
*/
public static TreeNode[] buildNodes(List<Resource> resources,
List<Resource> lockedData) {
-- ResourceTreeNode[] nodes = new ResourceTreeNode[resources.size()];
-- for (int i = 0; i < resources.size(); i++) {
-- Resource resource = resources.get(i);
++ List<ResourceTreeNode> resourceNodes = new
ArrayList<ResourceTreeNode>(resources.size());
++ for (Resource resource : resources) {
ResourceTreeNode node = new ResourceTreeNode(resource,
lockedData.contains(resource));
-- nodes[i] = node;
++ resourceNodes.add(node);
}
-- return introduceTypeAndCategoryNodes(nodes);
++ List<TreeNode> result = introduceTypeAndCategoryNodes(resourceNodes);
++ com.allen_sauer.gwt.log.client.Log.debug("\nSTARTING FINAL TREE\n");
++ for (TreeNode node : result) {
++ com.allen_sauer.gwt.log.client.Log.debug("Final: " + node);
++ }
++ com.allen_sauer.gwt.log.client.Log.debug("\nENDING FINAL TREE\n");
++ return result.toArray(new TreeNode[result.size()]);
}
-- private static TreeNode[] introduceTypeAndCategoryNodes(ResourceTreeNode[]
resourceNodes) {
-- List<TreeNode> updatedNodes = new ArrayList<TreeNode>();
-- // Maps category node IDs to the corresponding category nodes.
-- Map<String, SubCategoryTreeNode> subcategoryNodes = new HashMap<String,
SubCategoryTreeNode>();
-- // Maps autogroup/type node IDs to the corresponding autogroup/type nodes.
-- Map<String, AutoGroupTreeNode> autogroupNodes = new HashMap<String,
AutoGroupTreeNode>();
++ /**
++ * @param resourceNodes ordered such that referenced parent nodes have lower indexes
than the referencing child.
++ * @return a new List, properly ordered and including AG and Subcategory nodes.
++ */
++ private static List<TreeNode> introduceTypeAndCategoryNodes(final
List<ResourceTreeNode> resourceNodes) {
++ // The resulting list of nodes, including AG and SC nodes. The list is ordered
to ensure all
++ // referenced parent nodes have lower indexes than the referencing child.
++ List<TreeNode> allNodes = new
ArrayList<TreeNode>(resourceNodes.size());
++ // Keep track of the node IDs added so far to ensure we don't add the same
node more than once. Note
++ // that the list of resourceNodes passed in may have duplicates as the caller
may not be able to
++ // ensure a clean set.
++ Set<String> allNodeIds = new HashSet<String>(resourceNodes.size() *
2);
for (ResourceTreeNode resourceNode : resourceNodes) {
-- updatedNodes.add(resourceNode);
++ if (allNodeIds.contains(resourceNode.getID())) {
++ com.allen_sauer.gwt.log.client.Log.debug("skipping duplicate
resourceNode: " + resourceNode);
++ continue;
++ }
Resource resource = resourceNode.getResource();
-- ResourceType type = resource.getResourceType();
-- if (type.getCategory() != ResourceCategory.PLATFORM) {
-- String autogroupNodeId = AutoGroupTreeNode.idOf(resource);
-- if (!autogroupNodes.containsKey(autogroupNodeId)) {
-- Resource parentResource = resource.getParentResource();
-- ResourceSubCategory subcategory = type.getSubCategory();
-- if (subcategory != null) {
-- com.allen_sauer.gwt.log.client.Log.debug("Processing "
+ subcategory + "...");
-- do {
-- String subcategoryNodeId =
SubCategoryTreeNode.idOf(subcategory, parentResource);
-- if (!subcategoryNodes.containsKey(subcategoryNodeId)) {
-- SubCategoryTreeNode subcategoryNode = new
SubCategoryTreeNode(subcategory,
-- parentResource);
-- subcategoryNodes.put(subcategoryNode.getID(),
subcategoryNode);
-- com.allen_sauer.gwt.log.client.Log.debug("Adding
" + subcategoryNode + " to tree...");
-- updatedNodes.add(subcategoryNode);
-- }
-- } while ((subcategory = subcategory.getParentSubCategory()) !=
null);
-- }
-- if (!type.isSingleton()) {
-- AutoGroupTreeNode autogroupNode = new
AutoGroupTreeNode(resource);
-- autogroupNodes.put(autogroupNodeId, autogroupNode);
-- com.allen_sauer.gwt.log.client.Log.debug("Adding " +
autogroupNode + " to tree...");
-- updatedNodes.add(autogroupNode);
++ if (resourceNode.isParentSubCategory()) {
++ // If the parent node is a subcategory node, make sure the subcategory
node is in the
++ // tree prior to the resource node. Note that it could itself be a tree
of subcategories.
++ addSubCategoryNodes(allNodes, allNodeIds, resource);
++
++ } else if (resourceNode.isParentAutoGroup()) {
++
++ // If the parent node is an autogroup node, make sure the autogroup node
is in the
++ // tree prior to the resource node.
++
++ if (!allNodeIds.contains(resourceNode.getParentID())) {
++ AutoGroupTreeNode autogroupNode = new AutoGroupTreeNode(resource);
++
++ if (autogroupNode.isParentSubcategory()) {
++ // If the parent node of the autogroup node is a subcategory
node, make sure the subcategory
++ // node is in the tree prior to the autogroup node. Note that
it could itself be a
++ // tree of subcategories.
++ addSubCategoryNodes(allNodes, allNodeIds, resource);
++
}
++ allNodeIds.add(resourceNode.getParentID());
++ com.allen_sauer.gwt.log.client.Log.debug("Adding " +
autogroupNode);
++ allNodes.add(autogroupNode);
}
}
++
++ com.allen_sauer.gwt.log.client.Log.debug("Adding " + resourceNode
+ " to tree...");
++ allNodeIds.add(resourceNode.getID());
++ allNodes.add(resourceNode);
++ }
++
++ return allNodes;
++ }
++
++ // convenience routine to avoid code duplication
++ private static void addSubCategoryNodes(List<TreeNode> allNodes,
Set<String> allNodeIds, Resource resource) {
++ Resource parentResource = resource.getParentResource();
++ ResourceType type = resource.getResourceType();
++ ResourceSubCategory subCategory = type.getSubCategory();
++ String subCategoryNodeId = null;
++ int insertAt = allNodes.size();
++
++ do {
++ subCategoryNodeId = SubCategoryTreeNode.idOf(subCategory, parentResource);
++
++ if (!allNodeIds.contains(subCategoryNodeId)) {
++ SubCategoryTreeNode subCategoryNode = new
SubCategoryTreeNode(subCategory, parentResource);
++ allNodeIds.add(subCategoryNodeId);
++ com.allen_sauer.gwt.log.client.Log.debug("Adding " +
subCategoryNode);
++ allNodes.add(insertAt, subCategoryNode);
++ }
++ } while ((subCategory = subCategory.getParentSubCategory()) != null);
++ }
++
++ public static class ResourceTreeNode extends EnhancedTreeNode {
++ private Resource resource;
++ private boolean isLocked;
++ private boolean parentAutoGroup = false;
++ private boolean parentSubCategory = false;
++
++ /**
++ * The parentID will be set to the parent resource at construction. It can be
changed
++ * later (prior to tree linkage) if the resource node should logically be set to
an
++ * autogroup or subcategory parent.
++ * @param resource
++ * @param isLocked
++ */
++ private ResourceTreeNode(Resource resource, boolean isLocked) {
++ this.resource = resource;
++ this.isLocked = isLocked;
++
++ String id = idOf(resource);
++ setID(id);
++
++ // a resource node can have any of three different parent node types;
resource, subcategory or autogroup.
++ // this can be determined at construction time so set it properly now and
assume the proper node
++ // structure will be in place later.
++ Resource parentResource = resource.getParentResource();
++ String parentId = null;
++
++ if (null != parentResource) {
++ // non-singletons will always be autogrouped
++ if (!resource.getResourceType().isSingleton()) {
++ parentId = AutoGroupTreeNode.idOf(resource);
++ this.parentAutoGroup = true;
++
++ } else {
++ ResourceSubCategory subCategory =
resource.getResourceType().getSubCategory();
++ if (null != subCategory) {
++ parentId = SubCategoryTreeNode.idOf(subCategory,
parentResource);
++ this.parentSubCategory = true;
++ } else
++ parentId = ResourceTreeNode.idOf(parentResource);
++ }
++ }
++ this.setParentID(parentId);
++
++ String name = resource.getName();
++ setName(name);
++
++ setAttribute(Attributes.DESCRIPTION, resource.getDescription());
++
++ Set<ResourceType> childTypes =
resource.getResourceType().getChildResourceTypes();
++ setIsFolder((childTypes != null && !childTypes.isEmpty()));
++ }
++
++ public Resource getResource() {
++ return this.resource;
++ }
++
++ public boolean isLocked() {
++ return isLocked;
++ }
++
++ public boolean isParentAutoGroup() {
++ return parentAutoGroup;
++ }
++
++ public boolean isParentSubCategory() {
++ return parentSubCategory;
++ }
++
++ public static String idOf(Resource resource) {
++ return idOf(resource.getId());
}
-- return updatedNodes.toArray(new TreeNode[updatedNodes.size()]);
++ public static String idOf(int resourceId) {
++ return String.valueOf(resourceId);
++ }
}
/**
-- * The folder node for a Resource subcategory.
++ * The folder node for a Resource subCategory.
*/
public static class SubCategoryTreeNode extends EnhancedTreeNode {
++
public SubCategoryTreeNode(ResourceSubCategory category, Resource
parentResource) {
String id = idOf(category, parentResource);
setID(id);
-- setAttribute(Attributes.ID, id);
ResourceSubCategory parentCategory = category.getParentSubCategory();
String parentId = (parentCategory != null) ?
SubCategoryTreeNode.idOf(parentCategory, parentResource)
: ResourceTreeNode.idOf(parentResource);
setParentID(parentId);
-- setAttribute(Attributes.PARENT_ID, parentId);
-- // Note, subcategory names are typically already plural, so there's no
need to pluralize them.
++ // Note, subCategory names are typically already plural, so there's no
need to pluralize them.
String name = category.getDisplayName();
setName(name);
-- setAttribute(Attributes.NAME, name);
setAttribute(Attributes.DESCRIPTION, category.getDescription());
}
public static String idOf(ResourceSubCategory category, Resource parentResource)
{
-- return "subcat" + category.getId() + "_" +
parentResource.getId();
++ return "subcat_" + category.getId() + "_" +
parentResource.getId();
}
}
@@@ -265,6 -265,6 +375,7 @@@
private Resource parentResource;
private ResourceType resourceType;
++ private boolean parentSubcategory = false;
/**
* @param resource requires resourceType field be set. requires parentResource
field be set (null for no parent)
@@@ -276,15 -276,15 +387,21 @@@
String id = idOf(resource);
setID(id);
-- String parentId = parentIdOf(resource);
++ // parent node is either a subCategory node or a resource node
++ String parentId;
++ ResourceSubCategory subcategory = this.resourceType.getSubCategory();
++ if (subcategory != null) {
++ parentId = SubCategoryTreeNode.idOf(subcategory, this.parentResource);
++ this.parentSubcategory = true;
++ } else {
++ parentId = ResourceTreeNode.idOf(this.parentResource);
++ }
setParentID(parentId);
-- ResourceType type = resource.getResourceType();
-- String name = StringUtility.pluralize(type.getName());
++ String name = StringUtility.pluralize(this.resourceType.getName());
setName(name);
-- setAttribute(Attributes.NAME, name);
-- setAttribute(Attributes.DESCRIPTION, type.getDescription());
++ setAttribute(Attributes.DESCRIPTION, this.resourceType.getDescription());
}
public Resource getParentResource() {
@@@ -306,6 -306,6 +423,10 @@@
return this.getParentResource().getName() + " ( " +
this.getResourceType().getName() + " )";
}
++ public boolean isParentSubcategory() {
++ return parentSubcategory;
++ }
++
/**
* Given a Resource, generate a unique ID for the AGNode.
*
@@@ -328,63 -328,63 +449,6 @@@
public static String idOf(Resource parentResource, ResourceType resourceType) {
return (parentResource != null) ? "autogroup_" +
resourceType.getId() + "_" + parentResource.getId() : null;
}
--
-- // parent node is either a subcategory node or a resouce node
-- public static String parentIdOf(Resource resource) {
-- ResourceType type = resource.getResourceType();
-- ResourceSubCategory parentCategory = type.getSubCategory();
-- return (parentCategory != null) ? SubCategoryTreeNode.idOf(parentCategory,
resource.getParentResource())
-- : ResourceTreeNode.idOf(resource.getParentResource());
-- }
}
-- public static class ResourceTreeNode extends EnhancedTreeNode {
-- private Resource resource;
-- private boolean isLocked;
--
-- private ResourceTreeNode(Resource resource, boolean isLocked) {
-- this.resource = resource;
-- this.isLocked = isLocked;
--
-- String id = idOf(resource);
-- setID(id);
-- setAttribute(Attributes.ID, id);
--
-- Resource parentResource = resource.getParentResource();
-- String parentId;
-- if (parentResource != null) {
-- parentId = resource.getResourceType().isSingleton() ?
AutoGroupTreeNode.parentIdOf(resource)
-- : AutoGroupTreeNode.idOf(resource);
-- } else {
-- parentId = null;
-- }
-- setParentID(parentId);
-- setAttribute(Attributes.PARENT_ID, parentId);
--
-- String name = resource.getName();
-- setName(name);
-- setAttribute(Attributes.NAME, name);
--
-- setAttribute(Attributes.DESCRIPTION, resource.getDescription());
--
-- Set<ResourceType> childTypes =
resource.getResourceType().getChildResourceTypes();
-- setIsFolder((childTypes != null && !childTypes.isEmpty()));
-- }
--
-- public Resource getResource() {
-- return this.resource;
-- }
--
-- public boolean isLocked() {
-- return isLocked;
-- }
--
-- public static String idOf(Resource resource) {
-- return idOf(resource.getId());
-- }
--
-- public static String idOf(int resourceId) {
-- return String.valueOf(resourceId);
-- }
-- }
}
diff --cc
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
index 97a7d2f,97a7d2f..aefb031
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
@@@ -104,7 -104,7 +104,7 @@@ public class ResourceTreeView extends L
private List<ResourceSelectListener> selectListeners = new
ArrayList<ResourceSelectListener>();
// Maps autogroup/type backing group ids to the corresponding autogroup/type nodes.
-- Map<Integer, AutoGroupTreeNode> autoGroupNodeMap = new HashMap<Integer,
AutoGroupTreeNode>();
++ private Map<Integer, AutoGroupTreeNode> autoGroupNodeMap = new
HashMap<Integer, AutoGroupTreeNode>();
public ResourceTreeView(String locatorId) {
super(locatorId);
commit e7acef3bd0f3bcc2122316cbbbc96366924c69f3
Merge: 87af918... 885a5f5...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Oct 4 18:06:53 2010 -0400
Merge branch 'master' into master-jay
Conflicts:
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
commit 87af918747d582095353ede483dfa8e1c46b7a63
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Oct 4 18:03:28 2010 -0400
Initial Manual Add Work
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
index 7ad683a..8a0329e 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
@@ -68,4 +68,6 @@ public interface ResourceGWTService extends RemoteService {
void unignoreResources(Integer[] resourceIds);
+ Resource manuallyAddResource(int resourceTypeId, int parentResourceId, Configuration
pluginConfiguration);
+
}
\ No newline at end of file
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
index d6cfdba..97a7d2f 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
@@ -300,9 +300,11 @@ public class ResourceTreeView extends LocatableVLayout {
// Update breadcrumbs
if (currentViewId != null) {
currentViewId.getBreadcrumbs().clear();
- for (int i = parents.length - 1; i >= 0; i--) {
- TreeNode n = parents[i];
- adjustBreadcrumb(n, currentViewId);
+ if (null != parents) {
+ for (int i = parents.length - 1; i >= 0; i--) {
+ TreeNode n = parents[i];
+ adjustBreadcrumb(n, currentViewId);
+ }
}
adjustBreadcrumb(selectedNode, currentViewId);
CoreGUI.refreshBreadCrumbTrail();
@@ -456,13 +458,15 @@ public class ResourceTreeView extends LocatableVLayout {
for (final ResourceType childType : resourceType.getChildResourceTypes()) {
if (childType.isCreatable()) {
MenuItem createItem = new MenuItem(childType.getName());
- createChildSubMenu.addItem(createItem);
+
createItem.addClickHandler(new ClickHandler() {
public void onClick(MenuItemClickEvent event) {
ResourceFactoryCreateWizard.showCreateWizard(resource,
childType);
}
});
+ createChildSubMenu.addItem(createItem);
+
}
}
createChildMenu.setSubmenu(createChildSubMenu);
@@ -472,21 +476,30 @@ public class ResourceTreeView extends LocatableVLayout {
// Manually Add Menu
MenuItem importChildMenu = new MenuItem("Import");
Menu importChildSubMenu = new Menu();
- for (ResourceType childType : resourceType.getChildResourceTypes()) {
+ for (final ResourceType childType : resourceType.getChildResourceTypes()) {
if (childType.isSupportsManualAdd()) {
- importChildSubMenu.addItem(new MenuItem(childType.getName()));
- //todo action
+ MenuItem importItem = new MenuItem(childType.getName());
+
+ importItem.addClickHandler(new ClickHandler() {
+ public void onClick(MenuItemClickEvent event) {
+ ResourceFactoryCreateWizard.showImportWizard(resource,
childType);
+ }
+ });
+
+ importChildSubMenu.addItem(importItem);
}
}
+
if (resourceType.getCategory() == ResourceCategory.PLATFORM) {
- loadManuallyAddServersToPlatforms(importChildSubMenu);
+ loadManuallyAddServersToPlatforms(importChildSubMenu, resource);
}
+
importChildMenu.setSubmenu(importChildSubMenu);
importChildMenu.setEnabled(importChildSubMenu.getItems().length > 0);
resourceContextMenu.addItem(importChildMenu);
}
- private void loadManuallyAddServersToPlatforms(final Menu manuallyAddMenu) {
+ private void loadManuallyAddServersToPlatforms(final Menu manuallyAddMenu, final
Resource resource) {
ResourceTypeGWTServiceAsync rts = GWTServiceLookup.getResourceTypeGWTService();
ResourceTypeCriteria criteria = new ResourceTypeCriteria();
@@ -498,9 +511,16 @@ public class ResourceTreeView extends LocatableVLayout {
}
public void onSuccess(PageList<ResourceType> result) {
- for (ResourceType type : result) {
+ for (final ResourceType type : result) {
if (type.getParentResourceTypes() == null ||
type.getParentResourceTypes().isEmpty()) {
MenuItem item = new MenuItem(type.getName());
+
+ item.addClickHandler(new ClickHandler() {
+ public void onClick(MenuItemClickEvent event) {
+ ResourceFactoryCreateWizard.showImportWizard(resource,
type);
+ }
+ });
+
manuallyAddMenu.addItem(item);
}
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ConfigurationStep.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ConfigurationStep.java
index 84c6b55..5d7fbdc 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ConfigurationStep.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ConfigurationStep.java
@@ -49,6 +49,7 @@ public class ConfigurationStep extends AbstractWizardStep {
}
public boolean nextPage() {
+ wizard.execute();
return true;
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ConfigurationTemplateStep.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ConfigurationTemplateStep.java
index 0db5af8..a588010 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ConfigurationTemplateStep.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ConfigurationTemplateStep.java
@@ -20,6 +20,7 @@ package
org.rhq.enterprise.gui.coregui.client.inventory.resource.factory;
import java.util.Map;
+import com.smartgwt.client.types.TitleOrientation;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.SelectItem;
@@ -49,10 +50,17 @@ public class ConfigurationTemplateStep extends AbstractWizardStep {
form = new LocatableDynamicForm("ResFactConfigTemplate");
- TextItem nameItem = new TextItem("resourceName", "Resource
Name");
- nameItem.setRequired(true);
+ TextItem nameItem = null;
- SelectItem templateSelect = new SelectItem("template",
"Template");
+ if (!this.wizard.isImport()) {
+ nameItem = new TextItem("resourceName", "New Resource
Name");
+ nameItem.setWidth(300);
+ nameItem.setRequired(true);
+ }
+
+ SelectItem templateSelect = new SelectItem("template",
"Connection Property Templates (Choose One)");
+ templateSelect.setTitleOrientation(TitleOrientation.TOP);
+ templateSelect.setWidth(300);
ConfigurationDefinition definition = wizard.getConfigurationDefinition();
@@ -64,9 +72,14 @@ public class ConfigurationTemplateStep extends AbstractWizardStep {
templateSelect.setDisabled(true);
}
- form.setItems(nameItem, templateSelect);
+ if (null != nameItem) {
+ form.setItems(nameItem, templateSelect);
+ } else {
+ form.setItems(templateSelect);
+ }
}
+
return form;
}
@@ -75,7 +88,7 @@ public class ConfigurationTemplateStep extends AbstractWizardStep {
}
public String getName() {
- return "New Resource";
+ return "Resource Information";
}
public Configuration getConfiguration() {
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ResourceFactoryCreateWizard.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ResourceFactoryCreateWizard.java
index bad2058..7968635 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ResourceFactoryCreateWizard.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/factory/ResourceFactoryCreateWizard.java
@@ -19,14 +19,9 @@
package org.rhq.enterprise.gui.coregui.client.inventory.resource.factory;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.EnumSet;
-import java.util.List;
import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.smartgwt.client.widgets.IButton;
-import com.smartgwt.client.widgets.events.ClickEvent;
-import com.smartgwt.client.widgets.events.ClickHandler;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
@@ -48,6 +43,7 @@ public class ResourceFactoryCreateWizard extends AbstractWizard {
private ConfigurationDefinition configurationDefinition;
private Resource parentResource;
private ResourceType createType;
+ private boolean isImport; // manual add vs. create new child
private WizardView view;
@@ -55,10 +51,11 @@ public class ResourceFactoryCreateWizard extends AbstractWizard {
private ConfigurationStep configurationStep;
public ResourceFactoryCreateWizard(Resource parentResource, ResourceType createType,
- ConfigurationDefinition configurationDefinition) {
+ ConfigurationDefinition configurationDefinition, boolean isImport) {
this.parentResource = parentResource;
this.createType = createType;
this.configurationDefinition = configurationDefinition;
+ this.isImport = isImport;
assert parentResource != null;
assert createType != null;
@@ -66,8 +63,12 @@ public class ResourceFactoryCreateWizard extends AbstractWizard {
ArrayList<WizardStep> steps = new ArrayList<WizardStep>();
- configurationTemplateStep = new ConfigurationTemplateStep(this);
- steps.add(configurationTemplateStep);
+ // skip the template step if this is an import (no resource name to be gathered)
and the
+ // type has only the default template to offer for user selection.
+ if (!(this.isImport && this.configurationDefinition.getTemplates().size()
< 2)) {
+ this.configurationTemplateStep = new ConfigurationTemplateStep(this);
+ steps.add(configurationTemplateStep);
+ }
configurationStep = new ConfigurationStep(this);
steps.add(configurationStep);
@@ -76,52 +77,57 @@ public class ResourceFactoryCreateWizard extends AbstractWizard {
}
public String getWindowTitle() {
- return "Resource Create Wizard";
+ return isImport() ? "Import Resource Wizard" : "Resource Create
Wizard";
}
public String getTitle() {
- return "Create New " + createType.getName();
+ return (isImport() ? "Import Resource of Type: " : "Create New
Resource of Type: ") + createType.getName();
}
public String getSubtitle() {
return null;
}
- public List<IButton> getCustomButtons(int step) {
- switch (step) {
- case 1:
- IButton createButton = new IButton("Create");
- createButton.addClickHandler(new ClickHandler() {
- public void onClick(ClickEvent clickEvent) {
- execute();
- }
- });
- return Collections.singletonList(createButton);
- }
- return null;
- }
-
- private void execute() {
+ public void execute() {
- int parentReourceId = parentResource.getId();
+ int parentResourceId = parentResource.getId();
int createTypeId = createType.getId();
- String newResourceName = configurationTemplateStep.getResourceName();
Configuration newConfiguration = configurationStep.getConfiguration();
- GWTServiceLookup.getResourceService().createResource(parentReourceId,
createTypeId, newResourceName,
- newConfiguration, new AsyncCallback<Void>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to create new
resource", caught);
- view.closeDialog();
- }
-
- public void onSuccess(Void result) {
- CoreGUI.getMessageCenter().notify(
- new Message("Submitted request to create new resource
["
- + configurationTemplateStep.getResourceName() +
"]", Message.Severity.Info));
- view.closeDialog();
- }
- });
+ if (isImport) {
+ GWTServiceLookup.getResourceService().manuallyAddResource(createTypeId,
parentResourceId, newConfiguration,
+ new AsyncCallback<Resource>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to manually
add resource", caught);
+ view.closeDialog();
+ }
+
+ public void onSuccess(Resource result) {
+ CoreGUI.getMessageCenter().notify(
+ new Message("Submitted request to manually add [" +
createType.getName() + "]",
+ Message.Severity.Info));
+ view.closeDialog();
+ }
+ });
+
+ } else {
+ String newResourceName = configurationTemplateStep.getResourceName();
+
+ GWTServiceLookup.getResourceService().createResource(parentResourceId,
createTypeId, newResourceName,
+ newConfiguration, new AsyncCallback<Void>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to create new
resource", caught);
+ view.closeDialog();
+ }
+
+ public void onSuccess(Void result) {
+ CoreGUI.getMessageCenter().notify(
+ new Message("Submitted request to create new resource
["
+ + configurationTemplateStep.getResourceName() +
"]", Message.Severity.Info));
+ view.closeDialog();
+ }
+ });
+ }
}
public void display() {
@@ -135,7 +141,19 @@ public class ResourceFactoryCreateWizard extends AbstractWizard {
new ResourceTypeRepository.TypeLoadedCallback() {
public void onTypesLoaded(ResourceType type) {
ResourceFactoryCreateWizard wizard = new
ResourceFactoryCreateWizard(parentResource, type, type
- .getResourceConfigurationDefinition());
+ .getResourceConfigurationDefinition(), false);
+ wizard.display();
+ }
+ });
+ }
+
+ public static void showImportWizard(final Resource parentResource, ResourceType
childType) {
+ ResourceTypeRepository.Cache.getInstance().getResourceTypes(childType.getId(),
+
EnumSet.of(ResourceTypeRepository.MetadataType.pluginConfigurationDefinition),
+ new ResourceTypeRepository.TypeLoadedCallback() {
+ public void onTypesLoaded(ResourceType type) {
+ ResourceFactoryCreateWizard wizard = new
ResourceFactoryCreateWizard(parentResource, type, type
+ .getPluginConfigurationDefinition(), true);
wizard.display();
}
});
@@ -146,7 +164,8 @@ public class ResourceFactoryCreateWizard extends AbstractWizard {
}
public Configuration getConfiguration() {
- return configurationTemplateStep.getConfiguration();
+ return (null == configurationTemplateStep) ?
this.configurationDefinition.getDefaultTemplate()
+ .createConfiguration() : configurationTemplateStep.getConfiguration();
}
public Resource getParentResource() {
@@ -157,6 +176,10 @@ public class ResourceFactoryCreateWizard extends AbstractWizard {
return createType;
}
+ public boolean isImport() {
+ return isImport;
+ }
+
public void cancel() {
// TODO: revert back to original state
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index 4e14b75..d256222 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@ -202,7 +202,7 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl
implements Re
platform.setChildren(servers);
}
- return platforms;
+ return SerialUtility.prepare(platforms,
"ResourceService.findRecentlyAddedResources");
} catch (Exception e) {
throw new RuntimeException(ThrowableUtil.getAllMessages(e));
}
@@ -281,4 +281,13 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl
implements Re
}
}
+ public Resource manuallyAddResource(int resourceTypeId, int parentResourceId,
Configuration pluginConfiguration) {
+ try {
+ Resource result = discoveryBoss.manuallyAddResource(getSessionSubject(),
resourceTypeId, parentResourceId,
+ pluginConfiguration);
+ return SerialUtility.prepare(result,
"ResourceService.manuallyAddResource");
+ } catch (Exception e) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(e));
+ }
+ }
}
\ No newline at end of file
commit f4c316bed1ed30f33cc6365421f051b945710870
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Oct 4 15:06:46 2010 -0400
Disable the experimental browser window logging out of the box
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
index ed2ce42..93d7ecb 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
@@ -38,7 +38,7 @@
2. In hosted mode, the windows are not automatically closed,
although you can easily close them manually in the usual way
-->
- <set-property name="log_WindowLogger" value="ENABLED" />
+ <set-property name="log_WindowLogger" value="DISABLED" />
<!--
You probably will want to disable the default `DivLogger` as well:
commit 3e06a613d311af3100a6d0a605a43a07564c9406
Merge: e68906f... 614e969...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Oct 1 21:12:36 2010 -0400
Merge branch 'master' into master-jay
commit e68906f5c7e3048921143a9d029a9e421c019f1d
Merge: a524764... 54400ac...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Oct 1 18:18:10 2010 -0400
Merge branch 'master' into master-jay
Conflicts:
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
diff --cc .classpath
index 0a567d7,0a567d7..9a892fa
--- a/.classpath
+++ b/.classpath
@@@ -255,5 -255,5 +255,6 @@@
<classpathentry exported="true" kind="var"
path="M2_REPO/ca/nanometrics/gflot/1.0.0/gflot-1.0.0.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/com/jcraft/jsch/0.1.29/jsch-0.1.29.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/commons-jxpath/commons-jxpath/1.3/commons-jxpath-1.3.jar"/>
++ <classpathentry exported="true" kind="var"
path="M2_REPO/com/google/code/gwt-log/gwt-log/3.0.3/gwt-log-3.0.3.jar"/>
<classpathentry kind="output" path="eclipse-classes"/>
</classpath>
commit a5247649b27165b9f2356a2d0d8dc983eaf7f8db
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Oct 1 18:00:25 2010 -0400
Reverting a change made in 6415ed10e3b0d967b712a7be0aa0a3fcf4ce95cb, it
breaks rendering of single-element paths (like "#Bundles or #Reports).
The BookmarkableView's renderView needs to be invoked.
I didn't see any ill effect of adding this back in, so I'm not sure of the
intent of the original change. May need more work.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
index 34cf23e..d685c41 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
@@ -300,12 +300,19 @@ public class CoreGUI implements EntryPoint,
ValueChangeHandler<String> {
}
if (this.currentCanvas instanceof BookmarkableView) {
- viewPath.next();
- if (!viewPath.isEnd()) {
- ((BookmarkableView) this.currentCanvas).renderView(viewPath);
- }
+ ((BookmarkableView) this.currentCanvas).renderView(viewPath.next());
}
+ // reverting this is as it breaks rendering of single-element paths (like
"#Bundles or
+ // #Reports. the BookmarkableView's renderView needs to be invoked.
+ //
+ //if (this.currentCanvas instanceof BookmarkableView) {
+ // viewPath.next();
+ // if (!viewPath.isEnd()) {
+ // ((BookmarkableView) this.currentCanvas).renderView(viewPath);
+ // }
+ //}
+
refreshBreadCrumbTrail();
}
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java
index fb382fa..4dc2182 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/bundle/list/BundleView.java
@@ -45,6 +45,7 @@ import org.rhq.enterprise.gui.coregui.client.Breadcrumb;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.ViewId;
import org.rhq.enterprise.gui.coregui.client.ViewPath;
+import org.rhq.enterprise.gui.coregui.client.bundle.BundleTopView;
import org.rhq.enterprise.gui.coregui.client.bundle.deploy.BundleDeployWizard;
import org.rhq.enterprise.gui.coregui.client.bundle.deployment.BundleDeploymentView;
import
org.rhq.enterprise.gui.coregui.client.bundle.destination.BundleDestinationListView;
@@ -98,7 +99,7 @@ public class BundleView extends LocatableVLayout implements
BookmarkableView {
this.bundle = bundle;
- addMember(new BackButton(extendLocatorId("BackButton"), "Back to
All Bundles", "Bundles"));
+ addMember(new BackButton(extendLocatorId("BackButton"), "Back to
All Bundles", BundleTopView.VIEW_ID));
headerLabel = new HeaderLabel("subsystems/bundle/Bundle_24.png",
bundle.getName());
commit fe8861d6f05baadd45f2ee9cad1deec2236970bf
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Oct 1 16:27:38 2010 -0400
add jxpath test dep lib
diff --git a/.classpath b/.classpath
index c13d973..0a567d7 100644
--- a/.classpath
+++ b/.classpath
@@ -254,5 +254,6 @@
<classpathentry exported="true" kind="var"
path="M2_REPO/com/smartgwt/smartgwt/2.2/smartgwt-2.2.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/ca/nanometrics/gflot/1.0.0/gflot-1.0.0.jar"/>
<classpathentry exported="true" kind="var"
path="M2_REPO/com/jcraft/jsch/0.1.29/jsch-0.1.29.jar"/>
+ <classpathentry exported="true" kind="var"
path="M2_REPO/commons-jxpath/commons-jxpath/1.3/commons-jxpath-1.3.jar"/>
<classpathentry kind="output" path="eclipse-classes"/>
</classpath>
commit 346c2223929d9d776a5bdc280fe87fcd159e2cb2
Merge: af34961... 77a5659...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Oct 1 10:04:07 2010 -0400
Merge branch 'master' into master-jay
commit 77a56598165197564c6e165211a04ec31a9979f8
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Sep 28 12:35:44 2010 -0400
AutoGroup/ResourceTree work
- Fix up breadcrumbs for AutoGroup selections and also fix up some path
- issues that were happening when selecting AG resources.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
index bb39f2d..34cf23e 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
@@ -254,10 +254,13 @@ public class CoreGUI implements EntryPoint,
ValueChangeHandler<String> {
if (viewPath.matches("(" + ResourceTopView.VIEW_ID + "|"
+ ResourceGroupTopView.VIEW_ID + ")/[^/]*")) {
// e.g. "Resource/10001"
if (!currentViewPath.startsWith(viewPath)) {
- // The Resource that was selected is not the same Resource that was
previously selected -
- // grab the end portion of the previous history URL and append it to
the new history URL,
- // so the same tab is selected for the new Resource.
- String suffix =
currentViewPath.replaceFirst("^[^/]*/[^/]*", "");
+ // The Node that was selected is not the same Node that was
previously selected - it
+ // may not even be the same node type. For example, the user could
have moved from a
+ // resource to an autogroup in the same tree. Try to keep the tab
selection sticky as best as
+ // possible while moving from one view to another by grabbing the end
portion of the previous
+ // history URL and append it to the new history URL. The suffix is
assumed to follow the
+ // ID (numeric) portion of the currentViewPath.
+ String suffix = currentViewPath.replaceFirst("\\D*[^/]*",
"");
viewPath += suffix;
}
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
index 6a7cba9..0d16bea 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
@@ -236,7 +236,6 @@ public class ResourceTreeView extends LocatableVLayout {
// get back to this node given the id of the backing
group (from the viewpath)
autoGroupNodeMap.put(result.getId(), agNode);
callback.onSuccess(result);
- //renderAutoGroup(result);
}
});
} else {
@@ -302,6 +301,23 @@ public class ResourceTreeView extends LocatableVLayout {
}
}
+ private void adjustBreadcrumb(TreeNode node, ViewId viewId) {
+ if (node instanceof ResourceTreeNode) {
+ Resource nr = ((ResourceTreeNode) node).getResource();
+ String display = node.getName() + " <span
class=\"subtitle\">" + nr.getResourceType().getName() +
"</span>";
+ String icon = "types/" +
nr.getResourceType().getCategory().getDisplayName() + "_up_16.png";
+
+ viewId.getBreadcrumbs().add(new Breadcrumb(node.getAttribute("id"),
display, icon, true));
+
+ } else if (node instanceof AutoGroupTreeNode) {
+ String name = ((AutoGroupTreeNode) node).getBackingGroupName();
+ String display = node.getName() + " <span
class=\"subtitle\">" + name + "</span>";
+ String icon = "types/" + ((AutoGroupTreeNode)
node).getResourceType().getCategory() + "_up_16.png";
+
+ viewId.getBreadcrumbs().add(new Breadcrumb(node.getAttribute("id"),
display, icon, true));
+ }
+ }
+
private void showContextMenu(AutoGroupTreeNode agNode) {
getAutoGroupBackingGroup(agNode, new AsyncCallback<ResourceGroup>() {
public void onFailure(Throwable caught) {
@@ -680,23 +696,6 @@ public class ResourceTreeView extends LocatableVLayout {
}
}
- private void adjustBreadcrumb(TreeNode node, ViewId viewId) {
- if (node instanceof ResourceTreeNode) {
-
- Resource nr = ((ResourceTreeNode) node).getResource();
- String display = node.getName() + " <span
class=\"subtitle\">" + nr.getResourceType().getName() +
"</span>";
- String icon = "types/" +
nr.getResourceType().getCategory().getDisplayName() + "_up_16.png";
-
- viewId.getBreadcrumbs().add(new Breadcrumb(node.getAttribute("id"),
display, icon, true));
-
- } else {
-
- // if (node.getName() != null) {
- // viewId.getBreadcrumbs().add(new
Breadcrumb(node.getAttribute("id"), node.getName(), null, true));
- // }
- }
- }
-
/*private List<Resource> preload(final List<Resource> lineage) {
final ArrayList<Resource> list = new
ArrayList<Resource>(lineage);
@@ -730,8 +729,9 @@ public class ResourceTreeView extends LocatableVLayout {
currentViewId = viewPath.getCurrent();
String currentViewIdPath = currentViewId.getPath();
if ("AutoGroup".equals(currentViewIdPath)) {
- ViewId nextViewId = viewPath.getNext();
- Integer autoGroupId = Integer.parseInt(nextViewId.getPath());
+ // Move the currentViewId to the ID portion to play better with other code
+ currentViewId = viewPath.getNext();
+ Integer autoGroupId = Integer.parseInt(currentViewId.getPath());
setSelectedAutoGroup(autoGroupId);
} else {
Integer resourceId = Integer.parseInt(currentViewId.getPath());
commit af349612d16eb487345a7bf9d9b2921c7854e475
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Oct 1 09:57:45 2010 -0400
ResourceTree Authz work
- support for locked nodes
- support for autogroups for non-inventory managers. Now that AGs are
backed by compat groups it's necessary for non-inv-managers
to be able to create and access the private groups that they own. Private
groups (aka subject-owned groups) are new, they are basically groups
that are tagged with the creating subjectId. Those groups can be
created (via a new slsb call) and fetched (via a new ResourceGroupCriteria
filter) w/o inventory manager perms.
- note: i had to move rhq_subject to auth-schema from authz-schema and
slightly change the dbsetup order to make it ok for rhq_resource_group to
reference rhq_subject.
- schema spec bumped to 2.97
- added ResourceLineageComposite to combine Resource and locked/viewable
info.
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 02aa606..4035ed5 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -22,7 +22,7 @@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.96</db.schema.version>
+ <db.schema.version>2.97</db.schema.version>
</properties>
<dependencies>
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
index f4993e5..b0ee520 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
@@ -39,7 +39,7 @@ To run the default target, you must set one of the following properties
to true:
<property name="dbsetup.scripts.dir"
value="${basedir}/src/main/scripts/dbsetup" />
<property name="dbsetup.output.dir"
value="${basedir}/target/dbsetup" /> <!-- away from classes so it
doesn't go into the jar -->
<!-- define the setup creation processing order. note, removals are done in the
reverse order -->
- <property name="dbsetup.subsystems"
value="config,cluster,inventory,auth,authz,search,dashboard,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
+ <property name="dbsetup.subsystems"
value="config,cluster,auth,inventory,authz,search,dashboard,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
<property name="dbsetup.combined.schema"
value="${dbsetup.output.dir}/all-schema.xml" />
<property name="dbsetup.combined.data"
value="${dbsetup.output.dir}/all-data.xml" />
<property name="dbsetup.tstamp.file"
value="${dbsetup.output.dir}/dbsetup-combine.tstamp" />
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/auth-schema.xml
b/modules/core/dbutils/src/main/scripts/dbsetup/auth-schema.xml
index d24b386..9b77256 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/auth-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/auth-schema.xml
@@ -16,5 +16,24 @@
</index>
</table>
+
+ <table name="RHQ_SUBJECT">
+ <column name="ID" default="sequence-only"
initial="10001"
+ primarykey="true" required="true"
type="INTEGER"/>
+ <column name="NAME" required="true" size="100"
type="VARCHAR2"/>
+ <column name="CONFIGURATION_ID" type="INTEGER"
references="RHQ_CONFIG"/>
+ <column name="FIRST_NAME" required="false"
size="100" type="VARCHAR2"/>
+ <column name="LAST_NAME" required="false"
size="100" type="VARCHAR2"/>
+ <column name="EMAIL_ADDRESS" size="100"
type="VARCHAR2"/>
+ <column name="SMS_ADDRESS" size="100"
type="VARCHAR2"/>
+ <column name="PHONE_NUMBER" size="100"
type="VARCHAR2"/>
+ <column name="DEPARTMENT" size="100"
type="VARCHAR2"/>
+ <column name="FACTIVE" required="true"
type="BOOLEAN" default="true"/>
+ <column name="FSYSTEM" required="true"
type="BOOLEAN" default="false"/>
+
+ <index name="RHQ_SUBJECT_AUTH_KEY" unique="true">
+ <field ref="NAME"/>
+ </index>
+ </table>
</dbsetup>
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/authz-schema.xml
b/modules/core/dbutils/src/main/scripts/dbsetup/authz-schema.xml
index 8d9f738..b1385e9 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/authz-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/authz-schema.xml
@@ -50,25 +50,6 @@
</constraint>
</table>
- <table name="RHQ_SUBJECT">
- <column name="ID" default="sequence-only"
initial="10001"
- primarykey="true" required="true"
type="INTEGER"/>
- <column name="NAME" required="true" size="100"
type="VARCHAR2"/>
- <column name="CONFIGURATION_ID" type="INTEGER"
references="RHQ_CONFIG"/>
- <column name="FIRST_NAME" required="false"
size="100" type="VARCHAR2"/>
- <column name="LAST_NAME" required="false"
size="100" type="VARCHAR2"/>
- <column name="EMAIL_ADDRESS" size="100"
type="VARCHAR2"/>
- <column name="SMS_ADDRESS" size="100"
type="VARCHAR2"/>
- <column name="PHONE_NUMBER" size="100"
type="VARCHAR2"/>
- <column name="DEPARTMENT" size="100"
type="VARCHAR2"/>
- <column name="FACTIVE" required="true"
type="BOOLEAN" default="true"/>
- <column name="FSYSTEM" required="true"
type="BOOLEAN" default="false"/>
-
- <index name="RHQ_SUBJECT_AUTH_KEY" unique="true">
- <field ref="NAME"/>
- </index>
- </table>
-
<table name="RHQ_SUBJECT_ROLE_MAP">
<column name="SUBJECT_ID" required="true"
type="INTEGER" references="RHQ_SUBJECT"/>
<column name="ROLE_ID" required="true"
type="INTEGER" references="RHQ_ROLE"/>
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml
b/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml
index 6246880..5d89c2d 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml
@@ -168,11 +168,14 @@
<column name="CATEGORY" type="VARCHAR2"
size="20" required="true"/>
+ <!-- This is only set if this is a subject-owned group (like an autogroup)
-->
+ <column name="SUBJECT_ID" type="INTEGER"
references="RHQ_SUBJECT"/>
+
<!-- These two only set if this is a backing group for a resource
auto-cluster -->
<column name="CLUSTER_KEY" type="VARCHAR2"
size="4000" required="false"/>
<column name="CLUSTER_RESOURCE_GROUP_ID" type="INTEGER"
references="RHQ_RESOURCE_GROUP"/>
- <!-- This only set if this is a backing group for a resource auto-group
-->
+ <!-- This is only set if this is a backing group for a resource auto-group
-->
<column name="AUTO_GROUP_PARENT_RESOURCE_ID"
type="INTEGER" references="RHQ_RESOURCE"/>
<column name="VISIBLE" type="BOOLEAN"/>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index f0940ab..b477b09 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3226,9 +3226,21 @@
REFERENCES RHQ_RESOURCE (ID)
</statement>
</schema-directSQL>
-
</schemaSpec>
-
+
+ <schemaSpec version="2.97">
+ <!-- Support subject-owned groups (e.g. autogroups) -->
+ <schema-addColumn table="RHQ_RESOURCE_GROUP"
column="SUBJECT_ID" columnType="INTEGER" />
+ <schema-directSQL>
+ <statement desc="Creating RHQ_RESOURCE_GROUP foreign key
relation to RHQ_SUBJECT for owned groups">
+ ALTER TABLE RHQ_RESOURCE_GROUP
+ ADD CONSTRAINT RHQ_RG_SUBJECT_ID_FK
+ FOREIGN KEY (SUBJECT_ID)
+ REFERENCES RHQ_SUBJECT (ID)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
+
</dbupgrade>
</target>
</project>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
index 477a128..4a93c1f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/auth/Subject.java
@@ -24,11 +24,13 @@ package org.rhq.core.domain.auth;
import java.io.Serializable;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@@ -37,6 +39,7 @@ import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.QueryHint;
import javax.persistence.SequenceGenerator;
@@ -47,6 +50,7 @@ import org.jetbrains.annotations.NotNull;
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.util.Recordizable;
/**
@@ -271,6 +275,10 @@ public class Subject implements Serializable, Recordizable {
@ManyToMany
private java.util.Set<Role> ldapRoles;
+ // When a subject is removed any owned groups should also be removed
+ @OneToMany(mappedBy = "subject", fetch = FetchType.LAZY)
+ private List<ResourceGroup> ownedGroups = null;
+
@Transient
private Integer sessionId = null;
@@ -448,6 +456,14 @@ public class Subject implements Serializable, Recordizable {
getLdapRoles().remove(role);
}
+ public List<ResourceGroup> getOwnedGroups() {
+ return ownedGroups;
+ }
+
+ public void setOwnedGroups(List<ResourceGroup> ownedGroups) {
+ this.ownedGroups = ownedGroups;
+ }
+
@Override
public String toString() {
return "org.rhq.core.domain.auth.Subject[id=" + id + ",name="
+ name + "]";
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/ResourceGroupCriteria.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/ResourceGroupCriteria.java
index 2278c7f..835821a 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/ResourceGroupCriteria.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/ResourceGroupCriteria.java
@@ -46,6 +46,7 @@ public class ResourceGroupCriteria extends TaggedCriteria {
private Boolean filterRecursive;
private Integer filterResourceTypeId; // requires overrides
private String filterResourceTypeName; // requires overrides
+ private Integer filterSubjectId; // requires overrides
private Integer filterAutoGroupParentResourceId; // requires overrides
private String filterPluginName; // requires overrides
private GroupCategory filterGroupCategory;
@@ -56,6 +57,7 @@ public class ResourceGroupCriteria extends TaggedCriteria {
private Integer filterExplicitResourceTypeId; // requires overrides
private String filterExplicitResourceTypeName; // requires overrides
private Integer filterGroupDefinitionId; // requires overrides
+ private Boolean filterPrivate; /* if true, show only private groups for the calling
user */
private Boolean filterVisible = true; /* only show visible groups by default */
private boolean fetchExplicitResources;
@@ -74,6 +76,7 @@ public class ResourceGroupCriteria extends TaggedCriteria {
filterOverrides.put("resourceTypeId", "resourceType.id =
?");
filterOverrides.put("resourceTypeName", "resourceType.name like
?");
filterOverrides.put("autoGroupParentResourceId",
"autoGroupParentResource.id = ?");
+ filterOverrides.put("subjectId", "subject.id = ?");
filterOverrides.put("pluginName", "resourceType.plugin like
?");
filterOverrides.put("downMemberCount", "" //
+ "id IN ( SELECT implicitGroup.id " //
@@ -148,6 +151,14 @@ public class ResourceGroupCriteria extends TaggedCriteria {
this.filterResourceTypeName = filterResourceTypeName;
}
+ /**
+ * Requires MANAGE_INVENTORY. Use addFilterPrivate(true) to filter on the
caller's private groups.
+ * @param filterSubjectId.
+ */
+ public void addFilterSubjectId(Integer filterSubjectId) {
+ this.filterSubjectId = filterSubjectId;
+ }
+
public void addFilterAutoGroupParentResourceId(Integer
filterAutoGroupParentResourceId) {
this.filterAutoGroupParentResourceId = filterAutoGroupParentResourceId;
}
@@ -199,6 +210,14 @@ public class ResourceGroupCriteria extends TaggedCriteria {
this.filterGroupDefinitionId = filterGroupDefinitionId;
}
+ public void addFilterPrivate(Boolean filterPrivate) {
+ this.filterPrivate = filterPrivate;
+ }
+
+ public boolean isFilterPrivate() {
+ return (Boolean.TRUE.equals(this.filterPrivate));
+ }
+
public void addFilterVisible(Boolean filterVisible) {
this.filterVisible = filterVisible;
}
@@ -258,8 +277,8 @@ public class ResourceGroupCriteria extends TaggedCriteria {
@Override
public boolean isInventoryManagerRequired() {
- // presently only inventory managers can view/manage group definitions
- return this.filterGroupDefinitionId != null;
+ // presently only inventory managers can view/manage group definitions or see
other user's private groups
+ return this.filterGroupDefinitionId != null || this.filterSubjectId != null;
}
}
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ResourceLineageComposite.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ResourceLineageComposite.java
new file mode 100644
index 0000000..713a558
--- /dev/null
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ResourceLineageComposite.java
@@ -0,0 +1,51 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2010 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.rhq.core.domain.resource.composite;
+
+import java.io.Serializable;
+
+import org.rhq.core.domain.resource.Resource;
+
+/**
+ * @author jay shaughnessy
+ */
+public class ResourceLineageComposite implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private Resource resource;
+ private boolean isLocked;
+
+ // for gwt serialization
+ @SuppressWarnings("unused")
+ private ResourceLineageComposite() {
+ }
+
+ public ResourceLineageComposite(Resource resource, boolean isLocked) {
+ this.resource = resource;
+ this.isLocked = isLocked;
+ }
+
+ public Resource getResource() {
+ return resource;
+ }
+
+ public boolean isLocked() {
+ return isLocked;
+ }
+}
\ No newline at end of file
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
index 46d6bcb..5250c11 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/ResourceGroup.java
@@ -55,6 +55,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import org.jetbrains.annotations.NotNull;
import org.rhq.core.domain.alert.AlertDefinition;
+import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.bundle.BundleDestination;
import org.rhq.core.domain.configuration.group.AbstractGroupConfigurationUpdate;
@@ -432,6 +433,12 @@ public class ResourceGroup extends Group {
@ManyToOne
private ResourceType resourceType; // if non-null, it implies a compatible group
+ // The group owner. Certain groups (like autogroups) are not associated with Roles.
Instead, they
+ // are bound to specific owners. Subject-Owned groups defer to member-level
authorization as needed.
+ @JoinColumn(name = "SUBJECT_ID", referencedColumnName = "ID",
nullable = true)
+ @ManyToOne
+ private Subject subject = null;
+
@Column(name = "CLUSTER_KEY", nullable = true)
private String clusterKey;
@@ -612,6 +619,25 @@ public class ResourceGroup extends Group {
}
}
+ public Subject getSubject() {
+ return subject;
+ }
+
+ public void setSubject(Subject subject) {
+ if (this.id > 0 && null != this.subject) {
+ throw new IllegalStateException("The group owner can not be changed
after the group is created.");
+ }
+
+ this.subject = subject;
+ }
+
+ /**
+ * @return true if this is a subject-owned group, private to the set subject
+ */
+ public boolean isPrivateGroup() {
+ return (null != this.subject);
+ }
+
public String getClusterKey() {
return clusterKey;
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
index b282e41..7ad683a 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
@@ -32,6 +32,7 @@ import org.rhq.core.domain.resource.composite.DisambiguationReport;
import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.core.domain.resource.composite.ResourceLineageComposite;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -44,9 +45,7 @@ public interface ResourceGWTService extends RemoteService {
PageList<ResourceComposite> findResourceCompositesByCriteria(ResourceCriteria
criteria);
- List<Resource> getResourceLineage(int resourceId);
-
- List<Resource> getResourceLineageAndSiblings(int resourceId);
+ List<ResourceLineageComposite> getResourceLineageAndSiblings(int resourceId);
List<RecentlyAddedResourceComposite> findRecentlyAddedResources(long ctime, int
maxItems);
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGroupGWTService.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGroupGWTService.java
index d968e19..f48fd96 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGroupGWTService.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGroupGWTService.java
@@ -37,6 +37,14 @@ public interface ResourceGroupGWTService extends RemoteService {
GroupDefinition createGroupDefinition(GroupDefinition groupDefinition);
+ /**
+ * The owner will be set to the session subject.
+ * @param group
+ * @param resourceIds initial members
+ * @return
+ */
+ ResourceGroup createPrivateResourceGroup(ResourceGroup group, int[] resourceIds);
+
ResourceGroup createResourceGroup(ResourceGroup group, int[] resourceIds);
void deleteGroupDefinitions(int[] groupDefinitionIds);
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/AbstractTwoLevelTabSetView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/AbstractTwoLevelTabSetView.java
index 50700f2..33b22e9 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/AbstractTwoLevelTabSetView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/AbstractTwoLevelTabSetView.java
@@ -243,4 +243,9 @@ public abstract class AbstractTwoLevelTabSetView<T, U extends
Layout> extends Lo
public String getSubTabName() {
return subTabName;
}
+
+ public String getBaseViewPath() {
+ return baseViewPath;
+ }
+
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupDetailView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupDetailView.java
index e5bfc72..90388fc 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupDetailView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/ResourceGroupDetailView.java
@@ -271,7 +271,12 @@ public class ResourceGroupDetailView extends
AbstractTwoLevelTabSetView<Resource
ResourceGroupCriteria criteria = new ResourceGroupCriteria();
criteria.addFilterId(groupId);
- criteria.addFilterVisible(null);
+
+ // for autogroups we need to add more criteria
+ if (AUTO_GROUP_VIEW_PATH.equals(getBaseViewPath())) {
+ criteria.addFilterVisible(null);
+ criteria.addFilterPrivate(true);
+ }
GWTServiceLookup.getResourceGroupService().findResourceGroupCompositesByCriteria(criteria,
new AsyncCallback<PageList<ResourceGroupComposite>>() {
@@ -281,6 +286,11 @@ public class ResourceGroupDetailView extends
AbstractTwoLevelTabSetView<Resource
}
public void onSuccess(PageList<ResourceGroupComposite> result) {
+ if (result.isEmpty()) {
+ CoreGUI.getErrorHandler().handleError(
+ "Failed to load group composite for group with id "
+ groupId);
+ }
+
groupComposite = result.get(0);
loadResourceType(groupComposite, viewPath, globalPermissions);
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/CustomResourceTreeGrid.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/CustomResourceTreeGrid.java
index 71e6c61..f1dad07 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/CustomResourceTreeGrid.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/CustomResourceTreeGrid.java
@@ -23,6 +23,7 @@ import com.smartgwt.client.widgets.tree.TreeNode;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.resource.Resource;
+import
org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.ResourceTreeDatasource.ResourceTreeNode;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableTreeGrid;
/**
@@ -40,15 +41,19 @@ public class CustomResourceTreeGrid extends LocatableTreeGrid {
if (record instanceof TreeNode) {
boolean open = getTree().isOpen((TreeNode) record);
- if (record instanceof ResourceTreeDatasource.ResourceTreeNode) {
- Resource resource = ((ResourceTreeDatasource.ResourceTreeNode)
record).getResource();
+ if (record instanceof ResourceTreeNode) {
+ ResourceTreeNode node = (ResourceTreeNode) record;
- boolean up = resource.getCurrentAvailability().getAvailabilityType() ==
AvailabilityType.UP;
+ if (node.isLocked()) {
+ return "global/Locked_16.png";
- String category =
resource.getResourceType().getCategory().getDisplayName();
-
- return "types/" + category + "_" + (up ?
"up" : "down") + "_16.png";
+ } else {
+ Resource resource = ((ResourceTreeDatasource.ResourceTreeNode)
record).getResource();
+ String category =
resource.getResourceType().getCategory().getDisplayName();
+ boolean up = resource.getCurrentAvailability().getAvailabilityType()
== AvailabilityType.UP;
+ return "types/" + category + "_" + (up ?
"up" : "down") + "_16.png";
+ }
} else {
return "resources/folder_group_" + (open ? "opened" :
"closed") + ".png";
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
index 3ad6835..5f9e07c 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeDatasource.java
@@ -30,7 +30,6 @@ import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.DataSourceField;
-import com.smartgwt.client.data.fields.DataSourceImageField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.types.DSDataFormat;
@@ -38,8 +37,6 @@ import com.smartgwt.client.types.DSProtocol;
import com.smartgwt.client.widgets.tree.TreeNode;
import org.rhq.core.domain.criteria.ResourceCriteria;
-import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.domain.measurement.ResourceAvailability;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceSubCategory;
@@ -61,15 +58,17 @@ import org.rhq.enterprise.gui.coregui.client.util.StringUtility;
*/
public class ResourceTreeDatasource extends DataSource {
private List<Resource> initialData;
+ private List<Resource> lockedData;
private ResourceGWTServiceAsync resourceService =
GWTServiceLookup.getResourceService();
- public ResourceTreeDatasource(List<Resource> initialData) {
+ public ResourceTreeDatasource(List<Resource> initialData, List<Resource>
lockedData) {
setClientOnly(false);
setDataProtocol(DSProtocol.CLIENTCUSTOM);
setDataFormat(DSDataFormat.CUSTOM);
this.initialData = initialData;
+ this.lockedData = (null != lockedData) ? lockedData : new
ArrayList<Resource>();
DataSourceField idDataField = new DataSourceTextField("id",
"ID");
idDataField.setPrimaryKey(true);
@@ -80,22 +79,12 @@ public class ResourceTreeDatasource extends DataSource {
DataSourceTextField descriptionDataField = new
DataSourceTextField("description", "Description");
descriptionDataField.setCanEdit(false);
- DataSourceImageField availabilityDataField = new
DataSourceImageField("currentAvailability", "Availability");
- descriptionDataField.setCanEdit(false);
-
DataSourceTextField parentIdField = new DataSourceTextField("parentId",
"Parent ID");
parentIdField.setForeignKey("id");
- // parentIdField.setRootValue(rootId);
-
- // DataSourceTextField parentKeyField = new
DataSourceTextField("parentKey", "Parent KEY");
- // parentKeyField.setForeignKey("id");
- // parentKeyField.setRootValue(rootId);
-
- // nameDataField.setType(FieldType.);
setDropExtraFields(false);
- setFields(idDataField, nameDataField, descriptionDataField,
availabilityDataField);
+ setFields(idDataField, nameDataField, descriptionDataField);
}
@Override
@@ -127,7 +116,7 @@ public class ResourceTreeDatasource extends DataSource {
}
public void executeFetch(final String requestId, final DSRequest request, final
DSResponse response) {
- final long start = System.currentTimeMillis();
+ //final long start = System.currentTimeMillis();
String parentResourceId =
request.getCriteria().getAttribute("parentId");
// System.out.println("All attributes: " +
Arrays.toString(request.getCriteria().getAttributes()));
@@ -173,7 +162,7 @@ public class ResourceTreeDatasource extends DataSource {
ResourceTypeRepository.MetadataType.subCategory),
new ResourceTypeRepository.ResourceTypeLoadedCallback() {
public void onResourceTypeLoaded(List<Resource> result) {
- TreeNode[] treeNodes = buildNodes(result);
+ TreeNode[] treeNodes = buildNodes(result, lockedData);
response.setData(treeNodes);
processResponse(requestId, response);
response.setStatus(DSResponse.STATUS_SUCCESS);
@@ -187,11 +176,11 @@ public class ResourceTreeDatasource extends DataSource {
* @param resources
* @return
*/
- public static TreeNode[] buildNodes(List<Resource> resources) {
+ public static TreeNode[] buildNodes(List<Resource> resources,
List<Resource> lockedData) {
ResourceTreeNode[] nodes = new ResourceTreeNode[resources.size()];
for (int i = 0; i < resources.size(); i++) {
Resource resource = resources.get(i);
- ResourceTreeNode node = new ResourceTreeNode(resource);
+ ResourceTreeNode node = new ResourceTreeNode(resource,
lockedData.contains(resource));
nodes[i] = node;
}
@@ -350,9 +339,11 @@ public class ResourceTreeDatasource extends DataSource {
public static class ResourceTreeNode extends EnhancedTreeNode {
private Resource resource;
+ private boolean isLocked;
- private ResourceTreeNode(Resource resource) {
+ private ResourceTreeNode(Resource resource, boolean isLocked) {
this.resource = resource;
+ this.isLocked = isLocked;
String id = idOf(resource);
setID(id);
@@ -369,21 +360,12 @@ public class ResourceTreeDatasource extends DataSource {
setParentID(parentId);
setAttribute(Attributes.PARENT_ID, parentId);
- // System.out.println(id + " / " + parentId);
- // setAttribute("parentKey",
resource.getParentResource() == null ? 0 : (resource.getParentResource().getId() +
resource.getResourceType().getName()));
-
String name = resource.getName();
setName(name);
setAttribute(Attributes.NAME, name);
setAttribute(Attributes.DESCRIPTION, resource.getDescription());
- ResourceAvailability currentAvail = resource.getCurrentAvailability();
- setAttribute(
- "currentAvailability",
- (null != currentAvail && currentAvail.getAvailabilityType() ==
AvailabilityType.UP) ? "/images/icons/availability_green_16.png"
- : "/images/icons/availability_red_16.png");
-
Set<ResourceType> childTypes =
resource.getResourceType().getChildResourceTypes();
setIsFolder((childTypes != null && !childTypes.isEmpty()));
}
@@ -392,6 +374,10 @@ public class ResourceTreeDatasource extends DataSource {
return this.resource;
}
+ public boolean isLocked() {
+ return isLocked;
+ }
+
public static String idOf(Resource resource) {
return idOf(resource.getId());
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
index 0d16bea..4cea21b 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
@@ -63,6 +63,7 @@ import org.rhq.core.domain.operation.OperationDefinition;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.composite.ResourceLineageComposite;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.Breadcrumb;
@@ -142,14 +143,20 @@ public class ResourceTreeView extends LocatableVLayout {
if (!selectionEvent.isRightButtonDown() &&
selectionEvent.getState()) {
ListGridRecord selectedRecord = treeGrid.getSelectedRecord();
if (selectedRecord instanceof ResourceTreeNode) {
- System.out.println("AutoGroup Node selected in tree: "
+ selectedRecord);
-
ResourceTreeNode resourceNode = (ResourceTreeNode)
selectedRecord;
- selectedNodeId = resourceNode.getID();
- String viewPath = "Resource/" +
resourceNode.getResource().getId();
- String currentViewPath = History.getToken();
- if (!currentViewPath.startsWith(viewPath)) {
- CoreGUI.goToView(viewPath);
+
+ if (!resourceNode.isLocked()) {
+ System.out.println("Resource Node selected in tree:
" + selectedRecord);
+
+ selectedNodeId = resourceNode.getID();
+ String viewPath = "Resource/" +
resourceNode.getResource().getId();
+ String currentViewPath = History.getToken();
+ if (!currentViewPath.startsWith(viewPath)) {
+ CoreGUI.goToView(viewPath);
+ }
+ } else {
+ // TODO: Can we select the previous node? Or do we need a
"Locked" hover etc...
+ treeGrid.deselectAllRecords();
}
} else if (selectedRecord instanceof AutoGroupTreeNode) {
System.out.println("AutoGroup Node selected in tree: "
+ selectedRecord);
@@ -183,7 +190,9 @@ public class ResourceTreeView extends LocatableVLayout {
if (event.getNode() instanceof AutoGroupTreeNode) {
showContextMenu((AutoGroupTreeNode) event.getNode());
} else if (event.getNode() instanceof ResourceTreeNode) {
- showContextMenu((ResourceTreeNode) event.getNode());
+ if (!((ResourceTreeNode) event.getNode()).isLocked()) {
+ showContextMenu((ResourceTreeNode) event.getNode());
+ }
}
}
});
@@ -207,6 +216,7 @@ public class ResourceTreeView extends LocatableVLayout {
// get the backing group if it exists, otherwise create the group
ResourceGroupCriteria criteria = new ResourceGroupCriteria();
+ criteria.addFilterPrivate(true);
criteria.addFilterResourceTypeId(agNode.getResourceType().getId());
criteria.addFilterAutoGroupParentResourceId(agNode.getParentResource().getId());
criteria.addFilterVisible(false);
@@ -224,8 +234,7 @@ public class ResourceTreeView extends LocatableVLayout {
backingGroup.setAutoGroupParentResource(agNode.getParentResource());
backingGroup.setResourceType(agNode.getResourceType());
backingGroup.setVisible(false);
- backingGroup.setRecursive(false);
- resourceGroupService.createResourceGroup(backingGroup, childIds,
+ resourceGroupService.createPrivateResourceGroup(backingGroup,
childIds,
new AsyncCallback<ResourceGroup>() {
public void onFailure(Throwable caught) {
CoreGUI.getErrorHandler().handleError("Failed to
create resource autogroup", caught);
@@ -596,65 +605,79 @@ public class ResourceTreeView extends LocatableVLayout {
selectedNodeId = ResourceTreeNode.idOf(selectedResourceId);
final ResourceGWTServiceAsync resourceService =
GWTServiceLookup.getResourceService();
- // This is an expensive call, but loads all nodes that are visible in the tree
given a selected resource
- resourceService.getResourceLineageAndSiblings(selectedResourceId, new
AsyncCallback<List<Resource>>() {
- public void onFailure(Throwable caught) {
- CoreGUI.getErrorHandler().handleError("Failed to lookup platform for
tree", caught);
- }
- public void onSuccess(List<Resource> result) {
- Resource root = result.get(0);
+ // This is an expensive call, but loads all nodes that are visible in the tree
given a selected resource
+ resourceService.getResourceLineageAndSiblings(selectedResourceId,
+ new AsyncCallback<List<ResourceLineageComposite>>() {
- if (!root.equals(ResourceTreeView.this.rootResource)) {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to lookup platform
for tree", caught);
+ }
- if (treeGrid != null) {
- treeGrid.destroy();
- }
- buildTree();
+ public void onSuccess(List<ResourceLineageComposite> result) {
+ Resource root = result.get(0).getResource();
- setRootResource(root);
+ final List<Resource> lineage = new
ArrayList<Resource>(result.size());
+ final List<Resource> lockedData = new
ArrayList<Resource>();
- // seed datasource with initial resource list
- ResourceTreeDatasource dataSource = new
ResourceTreeDatasource(result);
- treeGrid.setDataSource(dataSource);
+ for (ResourceLineageComposite r : result) {
+ lineage.add(r.getResource());
+ if (r.isLocked()) {
+ lockedData.add(r.getResource());
+ }
+ }
- addMember(treeGrid);
+ if (!root.equals(ResourceTreeView.this.rootResource)) {
- treeGrid.fetchData(treeGrid.getCriteria(), new DSCallback() {
- public void execute(DSResponse response, Object rawData,
DSRequest request) {
- System.out.println("Done fetching data for
tree.");
- updateSelection();
+ if (treeGrid != null) {
+ treeGrid.destroy();
}
- });
+ buildTree();
- updateSelection();
+ setRootResource(root);
- } else {
- ResourceTypeRepository.Cache.getInstance().loadResourceTypes(
- result,
- EnumSet.of(ResourceTypeRepository.MetadataType.operations,
- ResourceTypeRepository.MetadataType.children,
- ResourceTypeRepository.MetadataType.subCategory),
- new ResourceTypeRepository.ResourceTypeLoadedCallback() {
- public void onResourceTypeLoaded(List<Resource> result)
{
-
treeGrid.getTree().linkNodes(ResourceTreeDatasource.buildNodes(result));
-
- TreeNode selectedNode =
treeGrid.getTree().findById(selectedNodeId);
- if (selectedNode != null) {
- updateSelection();
-
- } else {
- CoreGUI.getMessageCenter().notify(
- new Message("Failed to select Resource
[" + selectedResourceId + "] in tree.",
- Message.Severity.Warning));
- }
+ // seed datasource with initial resource list and which ancestor
resources are locked
+ ResourceTreeDatasource dataSource = new
ResourceTreeDatasource(lineage, lockedData);
+ treeGrid.setDataSource(dataSource);
+ addMember(treeGrid);
+
+ treeGrid.fetchData(treeGrid.getCriteria(), new DSCallback() {
+ public void execute(DSResponse response, Object rawData,
DSRequest request) {
+ System.out.println("Done fetching data for
tree.");
+ updateSelection();
}
});
+ updateSelection();
+
+ } else {
+ ResourceTypeRepository.Cache.getInstance().loadResourceTypes(
+ lineage,
+ EnumSet.of(ResourceTypeRepository.MetadataType.operations,
+ ResourceTypeRepository.MetadataType.children,
+ ResourceTypeRepository.MetadataType.subCategory),
+ new ResourceTypeRepository.ResourceTypeLoadedCallback() {
+ public void onResourceTypeLoaded(List<Resource>
result) {
+ treeGrid.getTree()
+
.linkNodes(ResourceTreeDatasource.buildNodes(lineage, lockedData));
+
+ TreeNode selectedNode =
treeGrid.getTree().findById(selectedNodeId);
+ if (selectedNode != null) {
+ updateSelection();
+
+ } else {
+ CoreGUI.getMessageCenter().notify(
+ new Message("Failed to select Resource
[" + selectedResourceId
+ + "] in tree.",
Message.Severity.Warning));
+ }
+
+ }
+ });
+
+ }
}
- }
- });
+ });
}
public void setSelectedAutoGroup(final Integer selectedAutoGroupId) {
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index 66a25be..2e2f6d6 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@ -39,6 +39,7 @@ import org.rhq.core.domain.resource.composite.DisambiguationReport;
import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
+import org.rhq.core.domain.resource.composite.ResourceLineageComposite;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.util.IntExtractor;
@@ -167,13 +168,8 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl
implements Re
}
};
- public List<Resource> getResourceLineage(int resourceId) {
- return SerialUtility.prepare(resourceManager.getResourceLineage(resourceId),
- "ResourceService.getResourceLineage");
- }
-
- public List<Resource> getResourceLineageAndSiblings(int resourceId) {
- return
SerialUtility.prepare(resourceManager.getResourceLineageAndSiblings(resourceId),
+ public List<ResourceLineageComposite> getResourceLineageAndSiblings(int
resourceId) {
+ return
SerialUtility.prepare(resourceManager.getResourceLineageAndSiblings(getSessionSubject(),
resourceId),
"ResourceService.getResourceLineageAndSiblings");
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGroupGWTServiceImpl.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGroupGWTServiceImpl.java
index 1ddecc3..2015091 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGroupGWTServiceImpl.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGroupGWTServiceImpl.java
@@ -87,6 +87,17 @@ public class ResourceGroupGWTServiceImpl extends AbstractGWTServiceImpl
implemen
}
}
+ public ResourceGroup createPrivateResourceGroup(ResourceGroup group, int[]
resourceIds) {
+ try {
+ Subject user = getSessionSubject();
+ group = groupManager.createPrivateResourceGroup(user, group);
+ groupManager.setAssignedResources(user, group.getId(), resourceIds, true);
+ return SerialUtility.prepare(group,
"ResourceGroupService.createResourceGroup");
+ } catch (Throwable t) {
+ throw new RuntimeException(ThrowableUtil.getAllMessages(t));
+ }
+ }
+
public ResourceGroup createResourceGroup(ResourceGroup group, int[] resourceIds) {
try {
Subject user = getSessionSubject();
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
index 4e1a53d..37ec2c9 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/auth/SubjectManagerBean.java
@@ -48,6 +48,7 @@ import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.criteria.SubjectCriteria;
+import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.server.PersistenceUtility;
@@ -58,6 +59,7 @@ import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.authz.RequiredPermission;
import org.rhq.enterprise.server.core.CustomJaasDeploymentServiceMBean;
import org.rhq.enterprise.server.exception.LoginException;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
import org.rhq.enterprise.server.system.SystemManagerLocal;
import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
import org.rhq.enterprise.server.util.CriteriaQueryRunner;
@@ -69,7 +71,6 @@ import org.rhq.enterprise.server.util.CriteriaQueryRunner;
*/
@Stateless
public class SubjectManagerBean implements SubjectManagerLocal, SubjectManagerRemote {
- @SuppressWarnings("unused")
private final Log log = LogFactory.getLog(SubjectManagerBean.class);
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
@@ -79,6 +80,10 @@ public class SubjectManagerBean implements SubjectManagerLocal,
SubjectManagerRe
private AuthorizationManagerLocal authorizationManager;
@EJB
+ @IgnoreDependency
+ private ResourceGroupManagerLocal resourceGroupManager;
+
+ @EJB
private SystemManagerLocal systemManager;
@EJB
@@ -508,6 +513,25 @@ public class SubjectManagerBean implements SubjectManagerLocal,
SubjectManagerRe
deletePrincipal(subject, doomedSubject);
}
+ // one more thing, delete any owned groups
+ List<ResourceGroup> ownedGroups = doomedSubject.getOwnedGroups();
+ if (!ownedGroups.isEmpty()) {
+ int size = ownedGroups.size();
+ int[] ownedGroupIds = new int[size];
+ for (int i = 0; (i < size); ++i) {
+ ownedGroupIds[i] = ownedGroups.get(i).getId();
+ }
+ try {
+ resourceGroupManager.deleteResourceGroups(subject, ownedGroupIds);
+ } catch (Throwable t) {
+ if (log.isDebugEnabled()) {
+ log.error("Error deleting owned group " +
ownedGroupIds, t);
+ } else {
+ log.error("Error deleting owned group " + ownedGroupIds
+ ": " + t.getMessage());
+ }
+ }
+ }
+
deleteSubject(subject, doomedSubject);
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
index d675177..1a14a56 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/authz/AuthorizationManagerBean.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.server.authz;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
@@ -32,6 +33,8 @@ import javax.persistence.Query;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.authz.Permission.Target;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.enterprise.server.RHQConstants;
/**
@@ -117,12 +120,33 @@ public class AuthorizationManagerBean implements
AuthorizationManagerLocal {
return true;
}
- Query query =
entityManager.createNamedQuery(Subject.QUERY_HAS_GROUP_PERMISSION);
- query.setParameter("subject", subject);
- query.setParameter("permission", permission);
- query.setParameter("groupId", groupId);
- long count = (Long) query.getSingleResult();
- return (count != 0);
+ ResourceGroup group = entityManager.find(ResourceGroup.class, groupId);
+ Subject owner = group.getSubject();
+
+ if (null == owner) {
+ // role-owned group
+ Query query =
entityManager.createNamedQuery(Subject.QUERY_HAS_GROUP_PERMISSION);
+ query.setParameter("subject", subject);
+ query.setParameter("permission", permission);
+ query.setParameter("groupId", groupId);
+ long count = (Long) query.getSingleResult();
+ return (count != 0);
+
+ } else {
+ // don't let a user other than the owner do anything with this group
+ if (!subject.equals(owner)) {
+ return false;
+ }
+
+ // subject-owned group, requires perm check against each group member
+ Set<Resource> members = group.getExplicitResources();
+ List<Integer> memberIds = new
ArrayList<Integer>(members.size());
+ for (Resource member : members) {
+ memberIds.add(member.getId());
+ }
+
+ return hasResourcePermission(owner, permission, memberIds);
+ }
}
public boolean hasResourcePermission(Subject subject, Permission permission, int
resourceId) {
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index 0528b06..bf213c0 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -94,6 +94,7 @@ import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceHealthComposite;
import org.rhq.core.domain.resource.composite.ResourceIdFlyWeight;
import org.rhq.core.domain.resource.composite.ResourceInstallCount;
+import org.rhq.core.domain.resource.composite.ResourceLineageComposite;
import org.rhq.core.domain.resource.composite.ResourcePermission;
import org.rhq.core.domain.resource.composite.ResourceWithAvailability;
import org.rhq.core.domain.resource.flyweight.FlyweightCache;
@@ -721,27 +722,68 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
return resourceLineage;
}
- public List<Resource> getResourceLineageAndSiblings(int resourceId) {
- List<Resource> resourceLineage = getResourceLineage(resourceId);
- List<Resource> result = new LinkedList<Resource>();
+ public List<ResourceLineageComposite> getResourceLineageAndSiblings(Subject
subject, int resourceId) {
+ boolean isInventoryManager = authorizationManager.isInventoryManager(subject);
- Resource platform = resourceLineage.get(0);
- result.add(platform);
- for (Resource resource : resourceLineage) {
- if (resource.getParentResource() != null) {
- // This ensures Hibernate actually fetches the parent Resource.
- resource.getParentResource().getId();
- }
- Set<Resource> childResources = resource.getChildResources();
- result.addAll(childResources);
- for (Resource childResource : childResources) {
- // This ensures Hibernate actually fetches the parent Resource.
- childResource.getParentResource().getId();
- Set<Resource> grandchildResources =
childResource.getChildResources();
- result.addAll(grandchildResources);
- for (Resource grandchildResource : grandchildResources) {
+ // get the raw resource lineage up to the platform. We'll check the auth
below
+ List<Resource> rawResourceLineage = getResourceLineage(resourceId);
+ int depth = rawResourceLineage.size();
+ Resource parent = (depth > 1) ? rawResourceLineage.get(depth - 2) : null;
+
+ // record which of the raw ancestry is locked from view
+ List<ResourceLineageComposite> resourceLineage = new
ArrayList<ResourceLineageComposite>(rawResourceLineage
+ .size());
+ for (Resource resource : rawResourceLineage) {
+ resourceLineage.add(new ResourceLineageComposite(resource,
!authorizationManager.canViewResource(subject,
+ resource.getId())));
+ }
+
+ // fill out the tree, including only the direct ancestors and all viewable
relations
+ List<ResourceLineageComposite> result = new
LinkedList<ResourceLineageComposite>();
+
+ for (ResourceLineageComposite ancestor : resourceLineage) {
+ // always include a direct ancestor
+ result.add(ancestor);
+
+ // if the ancestor is not locked, include relevant children. Also, always
show viewable
+ // siblings of the target resource.
+ if (!ancestor.isLocked() || ancestor.getResource() == parent) {
+
+ // get children
+ Set<Resource> children =
ancestor.getResource().getChildResources();
+ // only add the viewable children
+ List<Resource> viewableChildren = new
ArrayList<Resource>(children.size());
+ for (Resource child : children) {
+ boolean isCommitted = (child.getInventoryStatus() ==
InventoryStatus.COMMITTED);
+ boolean isViewable = (isInventoryManager ||
authorizationManager.canViewResource(subject, child
+ .getId()));
+ if (isCommitted && isViewable) {
+ // if not a direct ancestor add to the list (direct ancestors
already added by default)
+ if (!rawResourceLineage.contains(child)) {
+ child.getParentResource().getId();
+ result.add(new ResourceLineageComposite(child, false));
+ }
+ viewableChildren.add(child);
+ }
+ }
+
+ // get grandchildren
+ for (Resource child : viewableChildren) {
// This ensures Hibernate actually fetches the parent Resource.
- grandchildResource.getParentResource().getId();
+ child.getParentResource().getId();
+ Set<Resource> grandChildren = child.getChildResources();
+ for (Resource grandChild : grandChildren) {
+ boolean isCommitted = (grandChild.getInventoryStatus() ==
InventoryStatus.COMMITTED);
+ boolean isViewable = (isInventoryManager ||
authorizationManager.canViewResource(subject,
+ grandChild.getId()));
+ if (isCommitted && isViewable) {
+ // if not a direct ancestor add to the list (direct ancestors
already added by default)
+ if (!rawResourceLineage.contains(grandChild)) {
+ grandChild.getParentResource().getId();
+ result.add(new ResourceLineageComposite(grandChild,
false));
+ }
+ }
+ }
}
}
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
index 78ece78..6f2ae41 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
@@ -43,6 +43,7 @@ import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceHealthComposite;
import org.rhq.core.domain.resource.composite.ResourceIdFlyWeight;
import org.rhq.core.domain.resource.composite.ResourceInstallCount;
+import org.rhq.core.domain.resource.composite.ResourceLineageComposite;
import org.rhq.core.domain.resource.composite.ResourceWithAvailability;
import org.rhq.core.domain.resource.flyweight.ResourceFlyweight;
import org.rhq.core.domain.resource.group.ResourceGroup;
@@ -156,11 +157,13 @@ public interface ResourceManagerLocal {
/**
* Returns the lineage of a resource plus all the siblings of the resources in the
lineage. This is
- * useful for prepopulating all the resources visible in an expanded tree.
+ * useful for prepopulating all the resources visible in an expanded tree. Composites
are returned
+ * that indicate whether the resource is viewable or should be locked in the tree.
+ *
* @param resourceId id of resource
- * @return resoure lineage and siblings
+ * @return resource lineage and siblings
*/
- List<Resource> getResourceLineageAndSiblings(int resourceId);
+ List<ResourceLineageComposite> getResourceLineageAndSiblings(Subject subject,
int resourceId);
/**
* Looks up the root of a subtree in the inventory. This will generally find the
platform on which
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerBean.java
index 0e7500f..f75d32d 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerBean.java
@@ -146,6 +146,15 @@ public class ResourceGroupManagerBean implements
ResourceGroupManagerLocal, Reso
}
}
+ public ResourceGroup createPrivateResourceGroup(Subject subject, //
+ @XmlJavaTypeAdapter(ResourceGroupAdapter.class) ResourceGroup group) {
+
+ group.setSubject(subject);
+ group.setRecursive(false);
+
+ return resourceGroupManager.createResourceGroup(subjectManager.getOverlord(),
group);
+ }
+
@RequiredPermission(Permission.MANAGE_INVENTORY)
public ResourceGroup createResourceGroup(Subject user, //
@XmlJavaTypeAdapter(ResourceGroupAdapter.class) ResourceGroup group) {
@@ -1017,8 +1026,9 @@ public class ResourceGroupManagerBean implements
ResourceGroupManagerLocal, Reso
*/
public PageList<ResourceGroupComposite>
findResourceGroupCompositesByCriteria(Subject subject,
ResourceGroupCriteria criteria) {
- CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject,
criteria);
- ;
+
+ CriteriaQueryGenerator generator = getCriteriaQueryGenerator(subject, criteria);
+
String replacementSelectList = ""
+ " new
org.rhq.core.domain.resource.group.composite.ResourceGroupComposite( "
+ " ( SELECT COUNT(avail) FROM resourcegroup.explicitResources res
JOIN res.currentAvailability avail ) AS explicitCount,"
@@ -1028,17 +1038,6 @@ public class ResourceGroupManagerBean implements
ResourceGroupManagerLocal, Reso
+ " resourcegroup ) ";
generator.alterProjection(replacementSelectList);
- if (criteria.isSecurityManagerRequired()
- && !authorizationManager.hasGlobalPermission(subject,
Permission.MANAGE_SECURITY)) {
- throw new PermissionException("Subject [" + subject.getName()
- + "] requires SecurityManager permission for requested query
criteria.");
- }
-
- if (authorizationManager.isInventoryManager(subject) == false) {
-
generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.GROUP,
null,
- subject.getId());
- }
-
CriteriaQueryRunner<ResourceGroupComposite> queryRunner = new
CriteriaQueryRunner<ResourceGroupComposite>(
criteria, generator, entityManager);
PageList<ResourceGroupComposite> results = queryRunner.execute();
@@ -1299,18 +1298,35 @@ public class ResourceGroupManagerBean implements
ResourceGroupManagerLocal, Reso
public void setAssignedResources(Subject subject, int groupId, int[] resourceIds,
boolean setType)
throws ResourceGroupDeleteException {
+ ResourceGroup group = entityManager.find(ResourceGroup.class, groupId);
+ if (group.isPrivateGroup()) {
+ List<Integer> ids = new ArrayList<Integer>(resourceIds.length);
+ for (int id : resourceIds) {
+ ids.add(id);
+ }
+ if (!authorizationManager.canViewResources(subject, ids)) {
+ throw new PermissionException("Subject [" + subject.getName()
+ + "] does not have VIEW permission for all specified
resources.");
+ }
+ } else {
+ if (!authorizationManager.isInventoryManager(subject)) {
+ throw new PermissionException("Subject [" + subject.getName()
+ + "] is not authorized for [ MANAGE_INVENTORY ]. Required for
changing group membership ");
+ }
+ }
+
List<Integer> currentMembers =
resourceManager.findExplicitResourceIdsByResourceGroup(groupId);
List<Integer> newMembers = ArrayUtils.wrapInList(resourceIds); // members
needing addition
newMembers.removeAll(currentMembers);
if (newMembers.size() > 0) {
- addResourcesToGroup(subject, groupId,
ArrayUtils.unwrapCollection(newMembers));
+ addResourcesToGroup(subjectManager.getOverlord(), groupId,
ArrayUtils.unwrapCollection(newMembers));
}
List<Integer> extraMembers = new ArrayList<Integer>(currentMembers);
// members needing removal
extraMembers.removeAll(ArrayUtils.wrapInList(resourceIds));
if (extraMembers.size() > 0) {
- removeResourcesFromGroup(subject, groupId,
ArrayUtils.unwrapCollection(extraMembers));
+ removeResourcesFromGroup(subjectManager.getOverlord(), groupId,
ArrayUtils.unwrapCollection(extraMembers));
}
// As a result of the membership change ensure that the group type is set
correctly.
@@ -1461,28 +1477,45 @@ public class ResourceGroupManagerBean implements
ResourceGroupManagerLocal, Reso
@SuppressWarnings("unchecked")
public PageList<ResourceGroup> findResourceGroupsByCriteria(Subject subject,
ResourceGroupCriteria criteria) {
- CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject,
criteria);
- ;
+ CriteriaQueryGenerator generator = getCriteriaQueryGenerator(subject, criteria);
+
+ CriteriaQueryRunner<ResourceGroup> queryRunner = new
CriteriaQueryRunner(criteria, generator, entityManager);
+ PageList<ResourceGroup> result = queryRunner.execute();
+ return result;
+ }
+
+ private CriteriaQueryGenerator getCriteriaQueryGenerator(Subject subject,
ResourceGroupCriteria criteria) {
if (criteria.isSecurityManagerRequired()
&& !authorizationManager.hasGlobalPermission(subject,
Permission.MANAGE_SECURITY)) {
throw new PermissionException("Subject [" + subject.getName()
+ "] requires SecurityManager permission for requested query
criteria.");
}
- if (criteria.isInventoryManagerRequired()
- && !authorizationManager.hasGlobalPermission(subject,
Permission.MANAGE_INVENTORY)) {
+ boolean isInventoryManager = authorizationManager.isInventoryManager(subject);
+ boolean groupAuthzRequired = (!(criteria.isFilterPrivate() ||
isInventoryManager));
+
+ if (criteria.isInventoryManagerRequired() && !isInventoryManager) {
throw new PermissionException("Subject [" + subject.getName()
+ "] requires InventoryManager permission for requested query
criteria.");
}
- if (authorizationManager.isInventoryManager(subject) == false) {
+ // if we're searching for private groups set the subject filter to the
current user's subjectId
+ // setting it here prevents the caller from spoofing a different user. This is
why the subject and
+ // private filters are different. The suject filter can specifiy any use and
therefore requires
+ // inventory manager.
+ if (criteria.isFilterPrivate()) {
+ criteria.addFilterPrivate(null);
+ criteria.addFilterSubjectId(subject.getId());
+ }
+
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(subject,
criteria);
+ if (groupAuthzRequired) {
generator.setAuthorizationResourceFragment(CriteriaQueryGenerator.AuthorizationTokenType.GROUP,
null,
subject.getId());
}
- CriteriaQueryRunner<ResourceGroup> queryRunner = new
CriteriaQueryRunner(criteria, generator, entityManager);
- return queryRunner.execute();
+ return generator;
}
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerLocal.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerLocal.java
index de96dbf..a0481b1 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerLocal.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/group/ResourceGroupManagerLocal.java
@@ -42,6 +42,28 @@ import org.rhq.core.domain.util.PageList;
@Local
public interface ResourceGroupManagerLocal {
+ /**
+ * NOTE: This is only used to support AutoGroups currently but the idea may be
expanded in the future.
+ *
+ * Creates a private, "user-owned" (aka "subject-owned") resource
group. This group differs from a role-owned
+ * group in that it can not be assigned to a role, instead it is owned by the user
that creates it. It comprises
+ * only a set of resources for which the user has, minimally, view permission. Since
a user's view permissions
+ * can change, membership and authz checking must be performed as needed when taking
any action on the group.
+ * <br/><br/>
+ * A user does not need MANAGE_INVENTORY to create a sub-group because it is private
to his view.
+ * <br/><br/>
+ * This call does not populate the group with members, it only creates the group. The
group is automatically set
+ * to be non-recursive.
+ * <br/><br/>
+ * All user-owned groups are deleted if the the user is deleted.
+ *
+ * @param user The user for which the group will be created.
+ * @param group The group characteristics. Any membership defined here is ignored.
The recursivity setting is
+ * ignored.
+ * @return The new group.
+ */
+ ResourceGroup createPrivateResourceGroup(Subject user, ResourceGroup group);
+
ResourceGroup getResourceGroupById(Subject user, int id, GroupCategory category)
throws ResourceGroupNotFoundException;
@@ -108,7 +130,10 @@ public interface ResourceGroupManagerLocal {
/**
* This method ensures that the explicit group membership is set to the specified
resources. Members
* will be added or removed as necessary. Make sure you pass the correct value for
the <setType>
- * parameter.
+ * parameter.
+ * <br/><br/>
+ * For global groups requires MANAGE_INVENTORY. For private groups requires VIEW
permission on all specified
+ * resources.
*
* @param subject
* @param groupId
commit 400635fb9e3cf30ac7d55d98330e4ad4e5c120b9
Merge: 1d94af7... 64abb7e...
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Sep 28 12:45:20 2010 -0400
Merge branch 'master' into master-jay
commit 1d94af7604a60412da8017e721ef0bb36504d8fd
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Sep 28 12:35:44 2010 -0400
AutoGroup/ResourceTree work
- Fix up breadcrumbs for AutoGroup selections and also fix up some path
- issues that were happening when selecting AG resources.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
index b59edba..7c895e0 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
@@ -339,10 +339,13 @@ public class CoreGUI implements EntryPoint,
ValueChangeHandler<String> {
if (viewPath.matches("(Resource|ResourceGroup)/[^/]*")) {
// e.g. "Resource/10001"
if (!currentViewPath.startsWith(viewPath)) {
- // The Resource that was selected is not the same Resource that was
previously selected -
- // grab the end portion of the previous history URL and append it to
the new history URL,
- // so the same tab is selected for the new Resource.
- String suffix =
currentViewPath.replaceFirst("^[^/]*/[^/]*", "");
+ // The Node that was selected is not the same Node that was
previously selected - it
+ // may not even be the same node type. For example, the user could
have moved from a
+ // resource to an autogroup in the same tree. Try to keep the tab
selection sticky as best as
+ // possible while moving from one view to another by grabbing the end
portion of the previous
+ // history URL and append it to the new history URL. The suffix is
assumed to follow the
+ // ID (numeric) portion of the currentViewPath.
+ String suffix = currentViewPath.replaceFirst("\\D*[^/]*",
"");
viewPath += suffix;
}
}
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
index 6a7cba9..0d16bea 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceTreeView.java
@@ -236,7 +236,6 @@ public class ResourceTreeView extends LocatableVLayout {
// get back to this node given the id of the backing
group (from the viewpath)
autoGroupNodeMap.put(result.getId(), agNode);
callback.onSuccess(result);
- //renderAutoGroup(result);
}
});
} else {
@@ -302,6 +301,23 @@ public class ResourceTreeView extends LocatableVLayout {
}
}
+ private void adjustBreadcrumb(TreeNode node, ViewId viewId) {
+ if (node instanceof ResourceTreeNode) {
+ Resource nr = ((ResourceTreeNode) node).getResource();
+ String display = node.getName() + " <span
class=\"subtitle\">" + nr.getResourceType().getName() +
"</span>";
+ String icon = "types/" +
nr.getResourceType().getCategory().getDisplayName() + "_up_16.png";
+
+ viewId.getBreadcrumbs().add(new Breadcrumb(node.getAttribute("id"),
display, icon, true));
+
+ } else if (node instanceof AutoGroupTreeNode) {
+ String name = ((AutoGroupTreeNode) node).getBackingGroupName();
+ String display = node.getName() + " <span
class=\"subtitle\">" + name + "</span>";
+ String icon = "types/" + ((AutoGroupTreeNode)
node).getResourceType().getCategory() + "_up_16.png";
+
+ viewId.getBreadcrumbs().add(new Breadcrumb(node.getAttribute("id"),
display, icon, true));
+ }
+ }
+
private void showContextMenu(AutoGroupTreeNode agNode) {
getAutoGroupBackingGroup(agNode, new AsyncCallback<ResourceGroup>() {
public void onFailure(Throwable caught) {
@@ -680,23 +696,6 @@ public class ResourceTreeView extends LocatableVLayout {
}
}
- private void adjustBreadcrumb(TreeNode node, ViewId viewId) {
- if (node instanceof ResourceTreeNode) {
-
- Resource nr = ((ResourceTreeNode) node).getResource();
- String display = node.getName() + " <span
class=\"subtitle\">" + nr.getResourceType().getName() +
"</span>";
- String icon = "types/" +
nr.getResourceType().getCategory().getDisplayName() + "_up_16.png";
-
- viewId.getBreadcrumbs().add(new Breadcrumb(node.getAttribute("id"),
display, icon, true));
-
- } else {
-
- // if (node.getName() != null) {
- // viewId.getBreadcrumbs().add(new
Breadcrumb(node.getAttribute("id"), node.getName(), null, true));
- // }
- }
- }
-
/*private List<Resource> preload(final List<Resource> lineage) {
final ArrayList<Resource> list = new
ArrayList<Resource>(lineage);
@@ -730,8 +729,9 @@ public class ResourceTreeView extends LocatableVLayout {
currentViewId = viewPath.getCurrent();
String currentViewIdPath = currentViewId.getPath();
if ("AutoGroup".equals(currentViewIdPath)) {
- ViewId nextViewId = viewPath.getNext();
- Integer autoGroupId = Integer.parseInt(nextViewId.getPath());
+ // Move the currentViewId to the ID portion to play better with other code
+ currentViewId = viewPath.getNext();
+ Integer autoGroupId = Integer.parseInt(currentViewId.getPath());
setSelectedAutoGroup(autoGroupId);
} else {
Integer resourceId = Integer.parseInt(currentViewId.getPath());