/*
 * JBoss, the OpenSource J2EE webOS
 * 
 * Distributable under LGPL license. See terms of license at gnu.org.
 */

package javax.emb;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * This class models constraints that restrict the selection of protocol
 * servers, like stream servers. Instances can contain multiple kinds of
 * constraints. Constraints come as type/value pairs, with the type defining
 * the type of constraint and the value giving the actual constraint data “
 * similar to a dictionary. Protocol constraints are used when publishing media
 * for a given protocol, see MediaEntityLocalHome.publish(’) for reference. As
 * streaming constraints have to be transferred over machine boundaries, the
 * class implements <code>java.io.Serializable</code>.
 * 
 * <p>This specification covers two types of constraint as binding for all
 * implementations:
 * 
 * <ul><li>"CLIENT_TYPE" constrains the protocol server selection indirectly
 * by defining an array of protocol client types (Strings) that are running on
 * a client machine. Protocol servers are only eligible for selection during
 * publish operations if they at least support one of the given client types.
 * Also, the metadata generated during publish requests must be suitable for
 * one of these clients. Standardized values for this constraint type are:
 * "Quicktime" for Apple Quicktime players, "VideoCharger" for IBM VideoCharger
 * players, "Windows Media" for Microsoft Windows Media players, "RealPlayer"
 * for RealNetworks players. Additional client types may be added to this list
 * in future releases of this specification.</li>
 * 
 * <li>"SERVER_TYPE" constrains the protocol server selection directly by
 * defining an array of protocol server types (Strings) eligible for selection
 * during publish requests. Standardized values for this constraint type are:
 * ”Quicktime" for Apple Quicktime servers, "VideoCharger" for IBM VideoCharger
 * servers, "Windows Media" for Microsoft Windows Media services, "RealSystem"
 * for RealNetworks servers. Additional protocol server types may be added to
 * this list in future releases of this specification.</li></ul>
 * 
 * @version <tt>$Revision: 1.4 $</tt>
 * @author <a href="mailto:ricardoarguello@users.sourceforge.net">Ricardo
 *         Argüello</a>
 */
public final class ProtocolConstraints implements Serializable
{
   public final static String CLIENT_TYPE = "CLIENT_TYPE";
   public final static String SERVER_TYPE = "SERVER_TYPE";

   private final Map constraints = Collections.synchronizedMap(new HashMap());

   /**
    * Returns the value of the constraint defined by the given type, or <code>null</code>
    * if said constraint is not present.
    * 
    * @param type the constraint type.
    * @return the constraint value.
    * @throws javax.emb.NullPointerException if the given type is <code>null</code>.
    */
   public Object getConstraint(String type)
   {
      if (type == null)
      {
         throw new NullPointerException();
      }

      return constraints.get(type);
   }

   /**
    * Alters the value of the constraint defined by the given type to the given
    * value. Passing the constraint value <code>null</code> removes a
    * constraint type from the receiver if present.
    * 
    * @param type the constraint type.
    * @param value the constraint value.
    * @throws java.lang.NullPointerException if the given type is <code>null</code>.
    * @throws java.lang.IllegalArgumentException if the constraint type given
    *         is either "CLIENT_TYPE" or "SERVER_TYPE", and the value given is
    *         not an array of Strings.
    *  
    */
   public void setConstraint(String type, Object value)
   {
      if (type == null)
      {
         throw new NullPointerException();
      }

      if ((type.equals(CLIENT_TYPE) || type.equals(SERVER_TYPE))
         && !(value instanceof String[]))
      {
         throw new IllegalArgumentException();
      }

      constraints.put(type, value);
   }

   /**
    * Returns the receiver's constraint types as an array of Strings.
    * 
    * @return an array of constraint types.
    */
   public String[] getConstraintTypes()
   {
      Collection keySet = constraints.keySet();
      return (String[]) keySet.toArray(new String[keySet.size()]);
   }
}