/* * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2004-2008], Hyperic, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ package org.hyperic.hq.appdef.shared; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import org.hyperic.hq.authz.server.session.AuthzSubject; import org.hyperic.hq.grouping.shared.GroupEntry; import org.hyperic.hq.grouping.shared.GroupValue; import org.hyperic.util.pager.PageList; /** * Appdef GroupValue implements the grouping subsystem's GroupValue * interface and provides the implementation for its methods. * The class extends the domain of groupable elements to include * appdef entities. The group entries are converted to and from * appdef entities as required to meet the needs of consumers. * * Note, despite the "Value" name and implied value object pattern, this * class is not necessarily light weight. It is likely that an instance * of this class will hold references to one or more visitor * class instances. This makes it an extremely bad candidate for, * say, sticking in the session. * * (MOST of this junk belongs in an abstract base class in the grouping * subsystem. However, the requirement is that this class MUST * extend AppdefResourceValue and since Java doesn't allow * multiple inheritance, well, we're stuck with this.) */ public class AppdefGroupValue extends AppdefResourceValue implements GroupValue, Cloneable, Serializable { private Integer id; // id of group. private int groupType; // adhoc|compat|clusterable private int groupEntType; // platform|server|group|app|service private int groupEntResType; // jboss|oracle,etc. private int clusterId; // clusterId private String name; // group name private String description; // group description private AuthzSubject subject; // group owner private String owner; // String value of owner private PageList<GroupEntry> groupEntries; // list of group entries private Long cTime; private Long mTime; private String modifiedBy; private String location; // The appdef resource type value of this group. private AppdefResourceTypeValue appdefResourceTypeValue = null; public AppdefGroupValue() { init(); } public AppdefGroupValue (Integer id) { this.id = id; init(); } private void init () { groupEntries = new PageList<GroupEntry>(); appdefResourceTypeValue = new GroupTypeValue(); clusterId = -1; } /** The group identifier */ public Integer getId() { return this.id; } public void setId( Integer id ) { this.id = id; } public AppdefEntityID getEntityId() { return AppdefEntityID.newGroupID(getId()); } /** The group type (adhoc, compatible) */ public int getGroupType() { return this.groupType; } public void setGroupType( int groupType ) { this.groupType = groupType; } /** The group type label */ public String getGroupTypeLabel(){ return getAppdefResourceTypeValue().getName(); } /** Test whether the group type is one of the adhoc types. */ public boolean isGroupAdhoc () { return AppdefEntityConstants.isGroupAdhoc(this.groupType); } /** Test whether the group is dynamic */ public boolean isDynamicGroup () { return AppdefEntityConstants.isDynamicGroup(this.groupType); } /** Test whether the group type is one of the compatible types. */ public boolean isGroupCompat() { return AppdefEntityConstants.isGroupCompat(this.groupType); } /** The group entity type */ public int getGroupEntType() { return groupEntType; } public void setGroupEntType( int groupEntType ) { this.groupEntType=groupEntType; } /** The group entity resource type */ public int getGroupEntResType() { return groupEntResType; } public void setGroupEntResType( int groupEntResType ) { this.groupEntResType = groupEntResType; } public int getClusterId () { return this.clusterId; } public void setClusterId (int clusterId) { this.clusterId=clusterId; } /** The name of the group */ public String getName() { return this.name; } public void setName( String name ) { this.name = name; } /** Group description */ public String getDescription() { return this.description; } public void setDescription (String desc) { this.description=desc; } /** The group owner */ public void setSubject(AuthzSubject s){ this.subject = s; } public AuthzSubject getSubject(){ return subject; } /** The group size PageList.size() */ public int getSize() { return this.groupEntries.size(); } /** The group total size (PageList.getTotalSize()) */ public int getTotalSize() { return this.groupEntries.getTotalSize(); } /** The group total size (PageList.setTotalSize()) */ public void setTotalSize( int groupTotalSize ) { this.groupEntries.setTotalSize( groupTotalSize ); } /** The PageList of group entries */ public PageList<GroupEntry> getGroupEntries() {return this.groupEntries; } /** Fetch the group members as a paged list of AppdefEntityIDs. The group * will always contain a page list of values because ResourceGroupManager * sees to it that all requests for group members receives a paged list. * To specify a page control, pass it into the AppdefGroupManager's findGroup * method (or to GroupUtil's) methods. * @return paged list of members. */ public PageList<AppdefEntityID> getAppdefGroupEntries () { return getAppdefGroupEntries(null); } /** Fetch the group members as a paged list of AppdefEntityIDs. The group * will always contain a page list of values because ResourceGroupManager * sees to it that all requests for group members receives a paged list. * To specify a page control, pass it into the AppdefGroupManager's findGroup * method (or to GroupUtil's) methods. * @return paged list of members. * @param optional comparator */ public PageList<AppdefEntityID> getAppdefGroupEntries (Comparator<AppdefEntityID> comparator) { List<AppdefEntityID> entities = new ArrayList<AppdefEntityID>(); for (GroupEntry entry: getGroupEntries()) { entities.add( entryToEntity( entry ) ); } if (comparator !=null) Collections.sort(entities,comparator); return new PageList<AppdefEntityID>(entities,getGroupEntries().getTotalSize()); } public Long getCTime() { return cTime; } public Long getMTime() { return mTime; } public void setCTime(Long ctime) { this.cTime = ctime; } public void setMTime(Long mtime) { this.mTime = mtime; } /** Adds an entity identified by AppdefEntityID to our group. Conversion * to the underlying group entry type (GroupEntry) will be automatic. * @param appdef entity id * */ public void addAppdefEntity ( AppdefEntityID entity ) { addEntry( entityToEntry(entity) ); } /** Asserts that an element exists in the group. * @return true if in group, false if not in group */ public boolean existsAppdefEntity ( AppdefEntityID entity ) { return existsEntry( entityToEntry(entity) ); } /** Asserts that an element exists in the group. * @return true if in group, false if not in group */ public boolean existsEntry (GroupEntry entry) { for (Iterator i=this.getGroupEntries().iterator();i.hasNext();) { GroupEntry ge = (GroupEntry)i.next(); if (ge.equals(entry)) { return true; } } return false; } /** * Removes an entity identified by AppdefEntityID from our group. */ public void removeAppdefEntity (AppdefEntityID entity) { removeEntry( entityToEntry(entity) ); } /** Gets the appdef resource type value of this group. * @return value object dowcasted to its base abstract class */ public AppdefResourceTypeValue getAppdefResourceTypeValue( ) { return appdefResourceTypeValue; } /** Sets the appdef resource type value of this group. * @param artv - The entity type value object. */ public void setAppdefResourceTypeValue ( AppdefResourceTypeValue artv) { this.appdefResourceTypeValue = artv; } /** Adds an entry to the group. * @param group entry value object. * */ public void addEntry (GroupEntry entry) { groupEntries.add(entry); } /** * Removes an entry from the group. */ public void removeEntry (GroupEntry goner) { for (Iterator i=groupEntries.iterator();i.hasNext();) { GroupEntry ge = (GroupEntry)i.next(); if (ge.equals(goner)) { i.remove(); } } } // utility method for converting back and forth from appdef to authz private GroupEntry entityToEntry (AppdefEntityID entity) { return new GroupEntry ( entity.getId(), AppdefUtil.appdefTypeIdToAuthzTypeStr( entity.getType())); } // utility method for converting back and forth from appdef to authz private AppdefEntityID entryToEntity (GroupEntry entry) { return new AppdefEntityID ( AppdefUtil.resNameToAppdefTypeId( entry.getType()), entry.getId()); } public String toString() { StringBuffer sb = new StringBuffer(AppdefGroupValue.class.getName()); sb.append("[groupId=").append(getId().intValue()); sb.append(",groupeType=").append(getGroupType()); sb.append(",name=").append(getName()); sb.append(",description=").append(getDescription()); sb.append(",elements=(").append(getGroupEntries().toString()); sb.append(")] super: "); sb.append(super.toString()); return sb.toString(); } public boolean equals(Object other) { if (other instanceof AppdefGroupValue) { AppdefGroupValue that = (AppdefGroupValue) other; // Cannot perform equals if groupid is not defined. if (that.getId() == null || this.getId()==null ) return false; return this.id.equals( that.id ); } else { return false; } } public int hashCode(){ int result = 17; result = 37*result + (int) groupType; result = 37*result + ((this.description != null) ? this.description.hashCode() : 0); result = 37*result + ((this.name != null) ? this.name.hashCode() : 0); result = 37*result + ((this.id != null) ? this.id.hashCode() : 0); // XXX incorporate hashcode from individual entries. return result; } /** Owner - not applicable, here only to satisfy interface. */ public String getOwner() { return owner; } public void setOwner (String s) { this.owner = s; } /** ModifiedBy - now applicable */ public String getModifiedBy() { return this.modifiedBy; } public void setModifiedBy (String s) { this.modifiedBy = s; } /** Location - now applicable */ public String getLocation() { return this.location; } public void setLocation (String s) { this.location=s; } /** A deep copy clone implementation specifically addresses the need * for the GroupManager to have a way to create new instances of the * concrete groups for which it has no class definition. * @throws CloneNotSupportedException * */ public Object clone () throws CloneNotSupportedException { AppdefGroupValue newGroupVo = (AppdefGroupValue) super.clone(); newGroupVo.init(); // reset any state. return newGroupVo; } }