/* * 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, version 2, as * published by the Free Software Foundation, and/or the GNU Lesser * General Public License, version 2.1, also as published by the Free * Software Foundation. * * 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 and the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.rhq.core.domain.resource.flyweight; import java.util.HashMap; import java.util.Map; 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; import org.rhq.core.domain.resource.ResourceType; /** * A helper object to hold the cached instances of the flyweights. * The keys in the maps are ids, values are the objects themselves. * <p> * The <code>construct*</code> methods are provided to correctly initialize * instances of the flyweight types in the cache instance from a minimal set * of data. * * @author Lukas Krejci */ public class FlyweightCache { private Map<Integer, ResourceFlyweight> resources = new HashMap<Integer, ResourceFlyweight>(); private Map<Integer, ResourceTypeFlyweight> resourceTypes = new HashMap<Integer, ResourceTypeFlyweight>(); public Map<Integer, ResourceFlyweight> getResources() { return resources; } public Map<Integer, ResourceTypeFlyweight> getResourceTypes() { return resourceTypes; } /** * Deprecated due to a simpler but more powerful subcategory design. * Please see https://bugzilla.redhat.com/show_bug.cgi?id=1069545 */ @Deprecated public Map<Integer, ResourceSubCategoryFlyweight> getSubCategories() { return null; } /** * @see #constructResource(int, String, String, String, Integer, int, AvailabilityType) * * @param original the resource * @return the initialized resource flyweight */ public ResourceFlyweight constructResource(Resource original) { int id = original.getId(); String name = original.getName(); String uuid = original.getUuid(); String resourceKey = original.getResourceKey(); Resource parent = original.getParentResource(); ResourceType type = original.getResourceType(); ResourceAvailability avail = original.getCurrentAvailability(); return constructResource(id, name, uuid, resourceKey, parent != null ? parent.getId() : null, type.getId(), avail != null ? avail.getAvailabilityType() : AvailabilityType.UNKNOWN); } /** * Constructs a fully initialized instance of the resource flyweight. * The resource type, sub-category and parent are looked up * in this cache instance. If not found, new instances are created and added * to this cache. * <p> * Note that if the parentId is not null and not found in this cache, a new flyweight * is created for the parent, initialized only with the id. * <p> * The type is supposed to exist in this cache already. If it doesn't, no type is assigned * to the returned resource flyweight. * <p> * If a corresponding flyweight for the provided resource id is already found in this cache, * it is refreshed with the data provided to this call. * * @param id the resource id * @param name the resource name * @param uuid the resource uuid * @param resourceKey the resource key * @param parentId the id of the parent resource * @param typeId the id of the resource type * @param currentAvailability the availability of the resource * @return the initialized resource flyweight */ public ResourceFlyweight constructResource(int id, String name, String uuid, String resourceKey, Integer parentId, int typeId, AvailabilityType currentAvailability) { ResourceFlyweight ret = getResources().get(id); if (ret == null) { ret = new ResourceFlyweight(); getResources().put(id, ret); } ret.setId(id); ret.setName(name); ret.setUuid(uuid); ret.setResourceKey(resourceKey); ret.setCurrentAvailability(new ResourceAvailabilityFlyweight(ret, currentAvailability)); if (parentId != null) { ResourceFlyweight parent = getResources().get(parentId); if (parent == null) { parent = constructResource(parentId, null, null, null, null, -1, null); } parent.getChildResources().add(ret); ret.setParentResource(parent); } else { ResourceFlyweight previousParent = ret.getParentResource(); if (previousParent != null) { previousParent.getChildResources().remove(ret); } ret.setParentResource(null); } ret.setResourceType(getResourceTypes().get(typeId)); return ret; } /** * Deprecated due to a simpler but more powerful subcategory design. * Please see https://bugzilla.redhat.com/show_bug.cgi?id=1069545 */ @Deprecated public ResourceSubCategoryFlyweight constructSubCategory(ResourceSubCategory original) { return null; } /** * Deprecated due to a simpler but more powerful subcategory design. * Please see https://bugzilla.redhat.com/show_bug.cgi?id=1069545 */ @Deprecated public ResourceSubCategoryFlyweight constructSubCategory(int id, String name, Integer parentSubCategoryId, String parentSubCategoryName) { return null; } /** * @see #constructResourceType(int, String, String, boolean, ResourceCategory, Integer) * * @param original the original resource type * @return a fully initialized resource type flyweight */ public ResourceTypeFlyweight constructResourceType(ResourceType original) { int id = original.getId(); String name = original.getName(); String plugin = original.getPlugin(); boolean singleton = original.isSingleton(); ResourceCategory category = original.getCategory(); String subCategory = original.getSubCategory(); return constructResourceType(id, name, plugin, singleton, category, subCategory); } /** * Constructs a fully initialized resource type flyweight. * If a flyweight instance is found in the cache under the provided id, a new instance * is *NOT* created but rather the properties of that existing instance are updated with * the provided values. * <p> * The subcategory is supposed to exist in the cache. If it doesn't the subcategory of the * returned resource type flyweight is set to null. * * @param id the resource type id * @param name the resource type name * @param plugin the resource type plugin * @param singleton true if the resource type is a singleton * @param category the resource type category * @param subCategory the id of the resource type sub category or null * @return the resource type flyweight */ public ResourceTypeFlyweight constructResourceType(int id, String name, String plugin, boolean singleton, ResourceCategory category, String subCategory) { ResourceTypeFlyweight ret = getResourceTypes().get(id); if (ret == null) { ret = new ResourceTypeFlyweight(); getResourceTypes().put(id, ret); } ret.setId(id); ret.setName(name); ret.setPlugin(plugin); ret.setSingleton(singleton); ret.setCategory(category); ret.setSubCategory(subCategory); return ret; } }