/*
* RHQ Management Platform
* Copyright (C) 2005-2008 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.enterprise.gui.inventory.resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;
import org.jvnet.inflector.Pluralizer;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.gui.util.FacesContextUtility;
import org.rhq.enterprise.gui.common.framework.PagedDataTableUIBean;
import org.rhq.enterprise.gui.common.paging.PageControlView;
import org.rhq.enterprise.gui.common.paging.PagedListDataModel;
import org.rhq.enterprise.gui.util.CustomEnglishPluralizer;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* The JSF managed bean for the Child Resources section of the Resource Inventory page
* (/rhq/resource/inventory/view.xhtml).
*
* @author Ian Springer
*/
public class ListChildResourcesUIBean extends PagedDataTableUIBean {
public static final String MANAGED_BEAN_NAME = "ListChildResourcesUIBean";
private static final String FORM_ID = "childResourcesForm";
private static final String CHILD_TYPE_FILTER_INPUT_ID = "childTypeFilter";
private static final String CHILD_TYPE_FILTER_INPUT_CLIENT_ID = FORM_ID + ':' + CHILD_TYPE_FILTER_INPUT_ID;
private static final String CHILD_TYPE_FILTER_VALUE_ALL = "ALL";
private static final String NBSP = " ";
private static final String DEFAULT_RESOURCE_TYPE_ID = "SELECT_TYPE";
private ResourceTypeManagerLocal resourceTypeManager = LookupUtil.getResourceTypeManager();
private ResourceManagerLocal resourceManager = LookupUtil.getResourceManager();
private String childTypeFilter;
private List<ResourceType> utilizedChildServerTypes;
private List<ResourceType> utilizedChildServiceTypes;
private int utilizedChildTypesCount;
private List<ResourceType> childServerTypes;
private List<ResourceType> childServiceTypes;
private int childTypesCount;
private List<ResourceType> creatableChildServerTypes;
private List<ResourceType> creatableChildServiceTypes;
private int creatableChildTypesCount;
private List<ResourceType> manuallyAddableChildServerTypes;
private List<ResourceType> manuallyAddableChildServiceTypes;
private int manuallyAddableChildTypesCount;
private String manuallyAddResourceTypeId;
private String createNewResourceTypeId;
public ListChildResourcesUIBean() {
this.utilizedChildServerTypes = this.resourceTypeManager.getUtilizedChildResourceTypesByCategory(
EnterpriseFacesContextUtility.getSubject(), EnterpriseFacesContextUtility.getResource(),
ResourceCategory.SERVER);
this.utilizedChildServiceTypes = this.resourceTypeManager.getUtilizedChildResourceTypesByCategory(
EnterpriseFacesContextUtility.getSubject(), EnterpriseFacesContextUtility.getResource(),
ResourceCategory.SERVICE);
this.utilizedChildTypesCount = this.utilizedChildServerTypes.size() + this.utilizedChildServiceTypes.size();
this.childServerTypes = this.resourceTypeManager.getChildResourceTypesByCategory(EnterpriseFacesContextUtility
.getSubject(), EnterpriseFacesContextUtility.getResource(), ResourceCategory.SERVER);
this.childServiceTypes = this.resourceTypeManager.getChildResourceTypesByCategory(EnterpriseFacesContextUtility
.getSubject(), EnterpriseFacesContextUtility.getResource(), ResourceCategory.SERVICE);
this.childTypesCount = this.childServerTypes.size() + this.childServiceTypes.size();
// TODO: Singleton resource types already represented in the resource's children should not be listed in the
// Manually Add and Create New pulldown menus. (ips, 09/10/07)
this.creatableChildServerTypes = getCreatableResourceTypes(this.childServerTypes);
this.creatableChildServiceTypes = getCreatableResourceTypes(this.childServiceTypes);
this.creatableChildTypesCount = this.creatableChildServerTypes.size() + this.creatableChildServiceTypes.size();
this.manuallyAddableChildServerTypes = getManuallyAddableResourceTypes(this.childServerTypes);
this.manuallyAddableChildServiceTypes = getManuallyAddableResourceTypes(this.childServiceTypes);
this.manuallyAddableChildTypesCount = this.manuallyAddableChildServerTypes.size()
+ this.manuallyAddableChildServiceTypes.size();
this.manuallyAddResourceTypeId = DEFAULT_RESOURCE_TYPE_ID;
this.createNewResourceTypeId = DEFAULT_RESOURCE_TYPE_ID;
}
public String getClearStaleBeans() {
try {
// RHQ-1933: remove session-cached UIBeans, whose navigation filters through /rhq/resource/inventory/view.xhtml
FacesContextUtility.removeSessionScopedBean(CreateNewConfigurationChildResourceUIBean.class);
FacesContextUtility.removeSessionScopedBean(CreateNewPackageChildResourceUIBean.class);
FacesContextUtility.removeSessionScopedBean(UploadNewChildPackageUIBean.class);
FacesContextUtility.removeSessionScopedBean(ManuallyAddChildResourceUIBean.class);
} catch (Throwable t) {
// if any error happens whatsoever, continue processing as if this code didn't exist
}
return null;
}
public List<SelectItem> getUtilizedChildServerTypes() {
List<SelectItem> utilizedChildServerTypes = convertToSelectItems(this.utilizedChildServerTypes, true);
if (!this.utilizedChildServerTypes.isEmpty()) {
utilizedChildServerTypes.add(0, createSelectItemForResourceCategory(ResourceCategory.SERVER, false));
}
return utilizedChildServerTypes;
}
public List<SelectItem> getUtilizedChildServiceTypes() {
List<SelectItem> utilizedChildServiceTypes = convertToSelectItems(this.utilizedChildServiceTypes, true);
if (!this.utilizedChildServiceTypes.isEmpty()) {
utilizedChildServiceTypes.add(0, createSelectItemForResourceCategory(ResourceCategory.SERVICE, false));
}
return utilizedChildServiceTypes;
}
public int getUtilizedChildTypesCount() {
return this.utilizedChildTypesCount;
}
public List<SelectItem> getChildServerTypes() {
List<SelectItem> childServerTypes = convertToSelectItems(this.childServerTypes, false);
if (!this.childServerTypes.isEmpty()) {
childServerTypes.add(0, createSelectItemForResourceCategory(ResourceCategory.SERVER, true));
}
return childServerTypes;
}
public List<SelectItem> getChildServiceTypes() {
List<SelectItem> childServiceTypes = convertToSelectItems(this.childServiceTypes, false);
if (!this.childServiceTypes.isEmpty()) {
childServiceTypes.add(0, createSelectItemForResourceCategory(ResourceCategory.SERVICE, true));
}
return childServiceTypes;
}
public int getChildTypesCount() {
return this.childTypesCount;
}
public List<SelectItem> getCreatableChildServerTypes() {
// TODO: jdobies, Jun 27, 2007: Add authz check to make sure the user can create
List<SelectItem> creatableChildServerTypes = convertToSelectItems(this.creatableChildServerTypes, false);
if (!this.creatableChildServerTypes.isEmpty()) {
// add label...
creatableChildServerTypes.add(0, createSelectItemForResourceCategory(ResourceCategory.SERVER, true));
}
return creatableChildServerTypes;
}
public List<SelectItem> getCreatableChildServiceTypes() {
// TODO: jdobies, Jun 27, 2007: Add authz check to make sure the user can create
List<SelectItem> creatableChildServiceTypes = convertToSelectItems(this.creatableChildServiceTypes, false);
if (!this.creatableChildServiceTypes.isEmpty()) {
// add label...
creatableChildServiceTypes.add(0, createSelectItemForResourceCategory(ResourceCategory.SERVICE, true));
}
return creatableChildServiceTypes;
}
public List<SelectItem> getManuallyAddableChildServerTypes() {
List<SelectItem> manuallyAddableChildServerTypes = convertToSelectItems(this.manuallyAddableChildServerTypes,
false);
if (!this.manuallyAddableChildServerTypes.isEmpty()) {
// add label...
manuallyAddableChildServerTypes.add(0, createSelectItemForResourceCategory(ResourceCategory.SERVER, true));
}
return manuallyAddableChildServerTypes;
}
public List<SelectItem> getManuallyAddableChildServiceTypes() {
List<SelectItem> manuallyAddableChildServiceTypes = convertToSelectItems(this.manuallyAddableChildServiceTypes,
false);
if (!this.manuallyAddableChildServiceTypes.isEmpty()) {
// add label...
manuallyAddableChildServiceTypes
.add(0, createSelectItemForResourceCategory(ResourceCategory.SERVICE, true));
}
return manuallyAddableChildServiceTypes;
}
public int getCreatableChildTypesCount() {
return this.creatableChildTypesCount;
}
public int getManuallyAddableChildTypesCount() {
return this.manuallyAddableChildTypesCount;
}
public String getChildTypeFilter() {
return this.childTypeFilter;
}
public void setChildTypeFilter(String childTypeFilter) {
this.childTypeFilter = childTypeFilter;
}
@Override
public DataModel getDataModel() {
if (this.dataModel == null) {
this.dataModel = new ListChildResourcesDataModel(PageControlView.ChildResourcesList, MANAGED_BEAN_NAME);
}
return this.dataModel;
}
public String getManuallyAddResourceTypeId() {
return this.manuallyAddResourceTypeId;
}
public void setManuallyAddResourceTypeId(String resourceTypeId) {
this.manuallyAddResourceTypeId = resourceTypeId;
}
public String getCreateNewResourceTypeId() {
return createNewResourceTypeId;
}
public void setCreateNewResourceTypeId(String resourceTypeId) {
this.createNewResourceTypeId = resourceTypeId;
}
public void initChildTypeFilter() {
// As a workaround for JSF calling getRowData() prior to calling setChildTypeFilter(), bypass JSF and set the
// field ourselves.
if (this.childTypeFilter == null) {
this.childTypeFilter = FacesContextUtility.getOptionalRequestParameter(CHILD_TYPE_FILTER_INPUT_CLIENT_ID);
}
}
private List<ResourceType> getManuallyAddableResourceTypes(List<ResourceType> resourceTypes) {
// TODO: Do this via a separate SQL query rather than Java code.
List<ResourceType> manuallyAddableResourceTypes = new ArrayList<ResourceType>();
for (ResourceType resourceType : resourceTypes) {
if (resourceType.isSupportsManualAdd()) {
manuallyAddableResourceTypes.add(resourceType);
}
}
return manuallyAddableResourceTypes;
}
private List<ResourceType> getCreatableResourceTypes(List<ResourceType> resourceTypes) {
// TODO: Do this via a separate SQL query rather than Java code.
List<ResourceType> creatableResourceTypes = new ArrayList<ResourceType>();
for (ResourceType resourceType : resourceTypes) {
if (resourceType.isCreatable()) {
creatableResourceTypes.add(resourceType);
}
}
return creatableResourceTypes;
}
private SelectItem createSelectItemForResourceCategory(ResourceCategory resourceCategory, boolean disable) {
SelectItem selectItem = new SelectItem(resourceCategory.name(), resourceCategory.getDisplayName() + "s");
selectItem.setDisabled(disable);
return selectItem;
}
private List<SelectItem> convertToSelectItems(List<ResourceType> resourceTypes, boolean pluralize) {
List<SelectItem> selectItems = new ArrayList<SelectItem>();
Pluralizer customPluralizer = new CustomEnglishPluralizer();
Set<String> dupResourceTypeNames = getDuplicateResourceTypeNames(resourceTypes);
for (ResourceType resourceType : resourceTypes) {
String resourceTypeName = resourceType.getName();
String pluralizedName = resourceTypeName;
try {
if (pluralize)
pluralizedName = customPluralizer.pluralize(resourceTypeName);
}
catch (StringIndexOutOfBoundsException oobe) { // Work around a bug in the pluralizer, BZ 594417
// Just ignore it and take the plain resource type name
}
String label = NBSP + " - "
+ ((pluralize) ? pluralizedName : resourceTypeName);
if (dupResourceTypeNames.contains(resourceTypeName)) {
label += " (" + resourceType.getPlugin() + " plugin)";
}
SelectItem selectItem = new SelectItem(resourceType.getId(), label);
selectItem.setEscape(false); // so that the ampersands in the non-blanking spaces will not be escaped to &
selectItems.add(selectItem);
}
return selectItems;
}
private static Set<String> getDuplicateResourceTypeNames(List<ResourceType> resourceTypes) {
Set<String> resourceTypeNames = new HashSet();
Set<String> dupResourceTypeNames = new HashSet();
for (ResourceType resourceType : resourceTypes) {
String resourceTypeName = resourceType.getName();
if (resourceTypeNames.contains(resourceTypeName)) {
dupResourceTypeNames.add(resourceTypeName);
}
resourceTypeNames.add(resourceTypeName);
}
return dupResourceTypeNames;
}
protected class ListChildResourcesDataModel extends PagedListDataModel<ResourceComposite> {
ListChildResourcesDataModel(PageControlView view, String beanName) {
super(view, beanName);
}
@Override
public PageList<ResourceComposite> fetchPage(PageControl pageControl) {
ResourceCategory resourceCategory = null;
int resourceTypeId = -1;
ListChildResourcesUIBean.this.initChildTypeFilter();
if ((ListChildResourcesUIBean.this.childTypeFilter != null)
&& !ListChildResourcesUIBean.this.childTypeFilter.equals(CHILD_TYPE_FILTER_VALUE_ALL)) {
try {
// first see if the filter is a category name (i.e. "SERVER" or "SERVICE")
resourceCategory = ResourceCategory.valueOf(ListChildResourcesUIBean.this.childTypeFilter);
} catch (IllegalArgumentException e) {
// not a category - see if it's a type id
try {
resourceTypeId = Integer.parseInt(ListChildResourcesUIBean.this.childTypeFilter);
} catch (NumberFormatException e1) {
throw new IllegalStateException("Invalid child type filter: "
+ ListChildResourcesUIBean.this.childTypeFilter);
}
}
}
PageList<ResourceComposite> resourceComposites = resourceManager
.findResourceCompositeForParentAndTypeAndCategory(EnterpriseFacesContextUtility.getSubject(),
resourceCategory, resourceTypeId, EnterpriseFacesContextUtility.getResource(), pageControl);
for (ResourceComposite composite : resourceComposites) {
ResourceType type = composite.getResource().getResourceType();
composite.setResourceFacets(resourceTypeManager.getResourceFacets(type.getId()));
}
return resourceComposites;
}
}
}