Save This Page
Home » openjdk-7 » javax » management » relation » [javadoc | source]
    1   /*
    2    * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.management.relation;
   27   
   28   import static com.sun.jmx.defaults.JmxProperties.RELATION_LOGGER;
   29   import static com.sun.jmx.mbeanserver.Util.cast;
   30   import com.sun.jmx.mbeanserver.GetPropertyAction;
   31   
   32   import java.io.IOException;
   33   import java.io.ObjectInputStream;
   34   import java.io.ObjectOutputStream;
   35   import java.io.ObjectStreamField;
   36   
   37   import java.security.AccessController;
   38   
   39   import java.util.ArrayList;
   40   import java.util.HashMap;
   41   import java.util.HashSet;
   42   import java.util.List;
   43   import java.util.Map;
   44   import java.util.Set;
   45   import java.util.logging.Level;
   46   
   47   /**
   48    * A RelationTypeSupport object implements the RelationType interface.
   49    * <P>It represents a relation type, providing role information for each role
   50    * expected to be supported in every relation of that type.
   51    *
   52    * <P>A relation type includes a relation type name and a list of
   53    * role infos (represented by RoleInfo objects).
   54    *
   55    * <P>A relation type has to be declared in the Relation Service:
   56    * <P>- either using the createRelationType() method, where a RelationTypeSupport
   57    * object will be created and kept in the Relation Service
   58    * <P>- either using the addRelationType() method where the user has to create
   59    * an object implementing the RelationType interface, and this object will be
   60    * used as representing a relation type in the Relation Service.
   61    *
   62    * <p>The <b>serialVersionUID</b> of this class is <code>4611072955724144607L</code>.
   63    *
   64    * @since 1.5
   65    */
   66   @SuppressWarnings("serial")  // serialVersionUID not constant
   67   public class RelationTypeSupport implements RelationType {
   68   
   69       // Serialization compatibility stuff:
   70       // Two serial forms are supported in this class. The selected form depends
   71       // on system property "jmx.serial.form":
   72       //  - "1.0" for JMX 1.0
   73       //  - any other value for JMX 1.1 and higher
   74       //
   75       // Serial version for old serial form
   76       private static final long oldSerialVersionUID = -8179019472410837190L;
   77       //
   78       // Serial version for new serial form
   79       private static final long newSerialVersionUID = 4611072955724144607L;
   80       //
   81       // Serializable fields in old serial form
   82       private static final ObjectStreamField[] oldSerialPersistentFields =
   83       {
   84         new ObjectStreamField("myTypeName", String.class),
   85         new ObjectStreamField("myRoleName2InfoMap", HashMap.class),
   86         new ObjectStreamField("myIsInRelServFlg", boolean.class)
   87       };
   88       //
   89       // Serializable fields in new serial form
   90       private static final ObjectStreamField[] newSerialPersistentFields =
   91       {
   92         new ObjectStreamField("typeName", String.class),
   93         new ObjectStreamField("roleName2InfoMap", Map.class),
   94         new ObjectStreamField("isInRelationService", boolean.class)
   95       };
   96       //
   97       // Actual serial version and serial form
   98       private static final long serialVersionUID;
   99       /**
  100        * @serialField typeName String Relation type name
  101        * @serialField roleName2InfoMap Map {@link Map} holding the mapping:
  102        *              &lt;role name ({@link String})&gt; -&gt; &lt;role info ({@link RoleInfo} object)&gt;
  103        * @serialField isInRelationService boolean Flag specifying whether the relation type has been declared in the
  104        *              Relation Service (so can no longer be updated)
  105        */
  106       private static final ObjectStreamField[] serialPersistentFields;
  107       private static boolean compat = false;
  108       static {
  109           try {
  110               GetPropertyAction act = new GetPropertyAction("jmx.serial.form");
  111               String form = AccessController.doPrivileged(act);
  112               compat = (form != null && form.equals("1.0"));
  113           } catch (Exception e) {
  114               // OK : Too bad, no compat with 1.0
  115           }
  116           if (compat) {
  117               serialPersistentFields = oldSerialPersistentFields;
  118               serialVersionUID = oldSerialVersionUID;
  119           } else {
  120               serialPersistentFields = newSerialPersistentFields;
  121               serialVersionUID = newSerialVersionUID;
  122           }
  123       }
  124       //
  125       // END Serialization compatibility stuff
  126   
  127       //
  128       // Private members
  129       //
  130   
  131       /**
  132        * @serial Relation type name
  133        */
  134       private String typeName = null;
  135   
  136       /**
  137        * @serial {@link Map} holding the mapping:
  138        *           &lt;role name ({@link String})&gt; -&gt; &lt;role info ({@link RoleInfo} object)&gt;
  139        */
  140       private Map<String,RoleInfo> roleName2InfoMap =
  141           new HashMap<String,RoleInfo>();
  142   
  143       /**
  144        * @serial Flag specifying whether the relation type has been declared in the
  145        *         Relation Service (so can no longer be updated)
  146        */
  147       private boolean isInRelationService = false;
  148   
  149       //
  150       // Constructors
  151       //
  152   
  153       /**
  154        * Constructor where all role definitions are dynamically created and
  155        * passed as parameter.
  156        *
  157        * @param relationTypeName  Name of relation type
  158        * @param roleInfoArray  List of role definitions (RoleInfo objects)
  159        *
  160        * @exception IllegalArgumentException  if null parameter
  161        * @exception InvalidRelationTypeException  if:
  162        * <P>- the same name has been used for two different roles
  163        * <P>- no role info provided
  164        * <P>- one null role info provided
  165        */
  166       public RelationTypeSupport(String relationTypeName,
  167                               RoleInfo[] roleInfoArray)
  168           throws IllegalArgumentException,
  169                  InvalidRelationTypeException {
  170   
  171           if (relationTypeName == null || roleInfoArray == null) {
  172               String excMsg = "Invalid parameter.";
  173               throw new IllegalArgumentException(excMsg);
  174           }
  175   
  176           RELATION_LOGGER.entering(RelationTypeSupport.class.getName(),
  177                   "RelationTypeSupport", relationTypeName);
  178   
  179           // Can throw InvalidRelationTypeException, ClassNotFoundException
  180           // and NotCompliantMBeanException
  181           initMembers(relationTypeName, roleInfoArray);
  182   
  183           RELATION_LOGGER.exiting(RelationTypeSupport.class.getName(),
  184                   "RelationTypeSupport");
  185           return;
  186       }
  187   
  188       /**
  189        * Constructor to be used for subclasses.
  190        *
  191        * @param relationTypeName  Name of relation type.
  192        *
  193        * @exception IllegalArgumentException  if null parameter.
  194        */
  195       protected RelationTypeSupport(String relationTypeName)
  196       {
  197           if (relationTypeName == null) {
  198               String excMsg = "Invalid parameter.";
  199               throw new IllegalArgumentException(excMsg);
  200           }
  201   
  202           RELATION_LOGGER.entering(RelationTypeSupport.class.getName(),
  203                   "RelationTypeSupport", relationTypeName);
  204   
  205           typeName = relationTypeName;
  206   
  207           RELATION_LOGGER.exiting(RelationTypeSupport.class.getName(),
  208                   "RelationTypeSupport");
  209           return;
  210       }
  211   
  212       //
  213       // Accessors
  214       //
  215   
  216       /**
  217        * Returns the relation type name.
  218        *
  219        * @return the relation type name.
  220        */
  221       public String getRelationTypeName() {
  222           return typeName;
  223       }
  224   
  225       /**
  226        * Returns the list of role definitions (ArrayList of RoleInfo objects).
  227        */
  228       public List<RoleInfo> getRoleInfos() {
  229           return new ArrayList<RoleInfo>(roleName2InfoMap.values());
  230       }
  231   
  232       /**
  233        * Returns the role info (RoleInfo object) for the given role info name
  234        * (null if not found).
  235        *
  236        * @param roleInfoName  role info name
  237        *
  238        * @return RoleInfo object providing role definition
  239        * does not exist
  240        *
  241        * @exception IllegalArgumentException  if null parameter
  242        * @exception RoleInfoNotFoundException  if no role info with that name in
  243        * relation type.
  244        */
  245       public RoleInfo getRoleInfo(String roleInfoName)
  246           throws IllegalArgumentException,
  247                  RoleInfoNotFoundException {
  248   
  249           if (roleInfoName == null) {
  250               String excMsg = "Invalid parameter.";
  251               throw new IllegalArgumentException(excMsg);
  252           }
  253   
  254           RELATION_LOGGER.entering(RelationTypeSupport.class.getName(),
  255                   "getRoleInfo", roleInfoName);
  256   
  257           // No null RoleInfo allowed, so use get()
  258           RoleInfo result = roleName2InfoMap.get(roleInfoName);
  259   
  260           if (result == null) {
  261               StringBuilder excMsgStrB = new StringBuilder();
  262               String excMsg = "No role info for role ";
  263               excMsgStrB.append(excMsg);
  264               excMsgStrB.append(roleInfoName);
  265               throw new RoleInfoNotFoundException(excMsgStrB.toString());
  266           }
  267   
  268           RELATION_LOGGER.exiting(RelationTypeSupport.class.getName(),
  269                   "getRoleInfo");
  270           return result;
  271       }
  272   
  273       //
  274       // Misc
  275       //
  276   
  277       /**
  278        * Add a role info.
  279        * This method of course should not be used after the creation of the
  280        * relation type, because updating it would invalidate that the relations
  281        * created associated to that type still conform to it.
  282        * Can throw a RuntimeException if trying to update a relation type
  283        * declared in the Relation Service.
  284        *
  285        * @param roleInfo  role info to be added.
  286        *
  287        * @exception IllegalArgumentException  if null parameter.
  288        * @exception InvalidRelationTypeException  if there is already a role
  289        *  info in current relation type with the same name.
  290        */
  291       protected void addRoleInfo(RoleInfo roleInfo)
  292           throws IllegalArgumentException,
  293                  InvalidRelationTypeException {
  294   
  295           if (roleInfo == null) {
  296               String excMsg = "Invalid parameter.";
  297               throw new IllegalArgumentException(excMsg);
  298           }
  299   
  300           RELATION_LOGGER.entering(RelationTypeSupport.class.getName(),
  301                   "addRoleInfo", roleInfo);
  302   
  303           if (isInRelationService) {
  304               // Trying to update a declared relation type
  305               String excMsg = "Relation type cannot be updated as it is declared in the Relation Service.";
  306               throw new RuntimeException(excMsg);
  307           }
  308   
  309           String roleName = roleInfo.getName();
  310   
  311           // Checks if the role info has already been described
  312           if (roleName2InfoMap.containsKey(roleName)) {
  313               StringBuilder excMsgStrB = new StringBuilder();
  314               String excMsg = "Two role infos provided for role ";
  315               excMsgStrB.append(excMsg);
  316               excMsgStrB.append(roleName);
  317               throw new InvalidRelationTypeException(excMsgStrB.toString());
  318           }
  319   
  320           roleName2InfoMap.put(roleName, new RoleInfo(roleInfo));
  321   
  322           RELATION_LOGGER.exiting(RelationTypeSupport.class.getName(),
  323                   "addRoleInfo");
  324           return;
  325       }
  326   
  327       // Sets the internal flag to specify that the relation type has been
  328       // declared in the Relation Service
  329       void setRelationServiceFlag(boolean flag) {
  330           isInRelationService = flag;
  331           return;
  332       }
  333   
  334       // Initializes the members, i.e. type name and role info list.
  335       //
  336       // -param relationTypeName  Name of relation type
  337       // -param roleInfoArray  List of role definitions (RoleInfo objects)
  338       //
  339       // -exception IllegalArgumentException  if null parameter
  340       // -exception InvalidRelationTypeException  If:
  341       //  - the same name has been used for two different roles
  342       //  - no role info provided
  343       //  - one null role info provided
  344       private void initMembers(String relationTypeName,
  345                                RoleInfo[] roleInfoArray)
  346           throws IllegalArgumentException,
  347                  InvalidRelationTypeException {
  348   
  349           if (relationTypeName == null || roleInfoArray == null) {
  350               String excMsg = "Invalid parameter.";
  351               throw new IllegalArgumentException(excMsg);
  352           }
  353   
  354           RELATION_LOGGER.entering(RelationTypeSupport.class.getName(),
  355                   "initMembers", relationTypeName);
  356   
  357           typeName = relationTypeName;
  358   
  359           // Verifies role infos before setting them
  360           // Can throw InvalidRelationTypeException
  361           checkRoleInfos(roleInfoArray);
  362   
  363           for (int i = 0; i < roleInfoArray.length; i++) {
  364               RoleInfo currRoleInfo = roleInfoArray[i];
  365               roleName2InfoMap.put(currRoleInfo.getName(),
  366                                    new RoleInfo(currRoleInfo));
  367           }
  368   
  369           RELATION_LOGGER.exiting(RelationTypeSupport.class.getName(),
  370                   "initMembers");
  371           return;
  372       }
  373   
  374       // Checks the given RoleInfo array to verify that:
  375       // - the array is not empty
  376       // - it does not contain a null element
  377       // - a given role name is used only for one RoleInfo
  378       //
  379       // -param roleInfoArray  array to be checked
  380       //
  381       // -exception IllegalArgumentException
  382       // -exception InvalidRelationTypeException  If:
  383       //  - the same name has been used for two different roles
  384       //  - no role info provided
  385       //  - one null role info provided
  386       static void checkRoleInfos(RoleInfo[] roleInfoArray)
  387           throws IllegalArgumentException,
  388                  InvalidRelationTypeException {
  389   
  390           if (roleInfoArray == null) {
  391               String excMsg = "Invalid parameter.";
  392               throw new IllegalArgumentException(excMsg);
  393           }
  394   
  395           if (roleInfoArray.length == 0) {
  396               // No role info provided
  397               String excMsg = "No role info provided.";
  398               throw new InvalidRelationTypeException(excMsg);
  399           }
  400   
  401   
  402           Set<String> roleNames = new HashSet<String>();
  403   
  404           for (int i = 0; i < roleInfoArray.length; i++) {
  405               RoleInfo currRoleInfo = roleInfoArray[i];
  406   
  407               if (currRoleInfo == null) {
  408                   String excMsg = "Null role info provided.";
  409                   throw new InvalidRelationTypeException(excMsg);
  410               }
  411   
  412               String roleName = currRoleInfo.getName();
  413   
  414               // Checks if the role info has already been described
  415               if (roleNames.contains(roleName)) {
  416                   StringBuilder excMsgStrB = new StringBuilder();
  417                   String excMsg = "Two role infos provided for role ";
  418                   excMsgStrB.append(excMsg);
  419                   excMsgStrB.append(roleName);
  420                   throw new InvalidRelationTypeException(excMsgStrB.toString());
  421               }
  422               roleNames.add(roleName);
  423           }
  424   
  425           return;
  426       }
  427   
  428   
  429       /**
  430        * Deserializes a {@link RelationTypeSupport} from an {@link ObjectInputStream}.
  431        */
  432       private void readObject(ObjectInputStream in)
  433               throws IOException, ClassNotFoundException {
  434         if (compat)
  435         {
  436           // Read an object serialized in the old serial form
  437           //
  438           ObjectInputStream.GetField fields = in.readFields();
  439           typeName = (String) fields.get("myTypeName", null);
  440           if (fields.defaulted("myTypeName"))
  441           {
  442             throw new NullPointerException("myTypeName");
  443           }
  444           roleName2InfoMap = cast(fields.get("myRoleName2InfoMap", null));
  445           if (fields.defaulted("myRoleName2InfoMap"))
  446           {
  447             throw new NullPointerException("myRoleName2InfoMap");
  448           }
  449           isInRelationService = fields.get("myIsInRelServFlg", false);
  450           if (fields.defaulted("myIsInRelServFlg"))
  451           {
  452             throw new NullPointerException("myIsInRelServFlg");
  453           }
  454         }
  455         else
  456         {
  457           // Read an object serialized in the new serial form
  458           //
  459           in.defaultReadObject();
  460         }
  461       }
  462   
  463   
  464       /**
  465        * Serializes a {@link RelationTypeSupport} to an {@link ObjectOutputStream}.
  466        */
  467       private void writeObject(ObjectOutputStream out)
  468               throws IOException {
  469         if (compat)
  470         {
  471           // Serializes this instance in the old serial form
  472           //
  473           ObjectOutputStream.PutField fields = out.putFields();
  474           fields.put("myTypeName", typeName);
  475           fields.put("myRoleName2InfoMap", roleName2InfoMap);
  476           fields.put("myIsInRelServFlg", isInRelationService);
  477           out.writeFields();
  478         }
  479         else
  480         {
  481           // Serializes this instance in the new serial form
  482           //
  483           out.defaultWriteObject();
  484         }
  485       }
  486   }

Save This Page
Home » openjdk-7 » javax » management » relation » [javadoc | source]