/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * This software is the proprietary information of Sun Microsystems, Inc.
 * Use is subject to license terms.
 * 
 * Copyright 2004 Sun Microsystems, Inc.  Tous droits réservés.
 * Ce logiciel est propriété de Sun Microsystems, Inc.
 * Distribué par des licences qui en restreignent l'utilisation.
 *
 * ident        "@(#)CIBProduct.java 1.22     04/07/15 SMI"
 *
 */

package com.sun.mfwk.cib;

import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;

import javax.management.ObjectName;
import javax.management.InvalidAttributeValueException;

import com.sun.mfwk.cib.CIBProductMBean;
import com.sun.mfwk.cib.CIBProductIf;
import com.sun.mfwk.cib.CIBObject;

/**
 * Default implementation of a CIB product MBean
 */
public class CIBProduct
    extends CIBObject
    implements CIBProductMBean, CIBProductIf {

  // properties
  protected String myProductName;
  protected String myProductVersion;
  protected String myPatchId;
  protected long myInstallTime;
  protected String myVendorName;

  // Core information base relations
  protected Set myApplicationsSet = new HashSet();

  /**
   * @label deployedApplications
   * @supplierCardinality 0..*
   * @clientCardinality 1 
   */
  private CIBApplication lnkCIBApplication;
  // Constructors section
  public CIBProduct() {
  }

  public CIBProduct(String theProductName,
                    String theProductVersion,
                    String thePatchId,
                    long theInstallTime,
                    String theVendorName) {

    myProductName = theProductName;
    myProductVersion = theProductVersion;
    myPatchId = thePatchId;
    myInstallTime = theInstallTime;
    if (theVendorName != null) {
      myVendorName = theVendorName;
    }
    else {
      myVendorName = defaultVendor;
    }
  }

  // Interface Mediation
  /**
   * Add an application ObjectName into the CIBProduct object.
   */
  public void addApplication(ObjectName applObjectName) {
    myApplicationsSet.add(applObjectName);
  }

  /**
   * remove an application object name from the CIBProduct
   */
  public void removeApplication(ObjectName applObjectName) throws CIBException {
    if (myApplicationsSet.contains(applObjectName)) {
      myApplicationsSet.remove(applObjectName);
    }
    else {
      String message = "Application named " + applObjectName +
          " is not part of this product ";
      CIBMbeanLogger.warning(CIBMbeanLogMessageHeaderString + message + " : " +
                             this +CIBMbeanNewLine +
                             CIBMbeanLogMessageClosingString);
      throw new CIBException(message);
    }
  }

  /**
   * Allows to set the ProductName of the product
   * @param productName String
   */
  public void setProductName(String productName) {
    myProductName = productName;
  }

  /**
   * Allow to set the version of the product
   * @param productVersion String
   */
  public void setVersion(String productVersion) {
    myProductVersion = productVersion;
  }

  /**
   * Allow to set the patchId
   * @param productPatchId String
   */
  public void setPatchId(String productPatchId) {
    myPatchId = productPatchId;
  }

  /**
   * Allow to set the installtime date
   * @param date long
   */
  public void setInstallTime(long date) {
    myInstallTime = date;
  }

  public void setVendorName(String vendorName) {
    myVendorName = vendorName;
  }

  // Interface MBean
  /**
   * Returns the product name
   * @return String
   */
  public String getProductName() throws InvalidAttributeValueException {
    if (myProductName != null) {
      return myProductName;
    }
    else {
      String message = FORBIDEN_NULL_VALUE + " ProductName" + " in CIBProduct";
      CIBMbeanLogger.warning(CIBMbeanLogMessageHeaderString + message + " : " +
                             this +CIBMbeanNewLine +
                             CIBMbeanLogMessageClosingString);
      throw new InvalidAttributeValueException(message);
    }
  }

  /**
   * Provides the product version
   */
  public String getProductVersion() throws InvalidAttributeValueException {
    if (myProductVersion != null) {
      return myProductVersion;
    }
    else {
      String message = FORBIDEN_NULL_VALUE + " ProductVersion" +
          " in CIBProduct";
      CIBMbeanLogger.warning(CIBMbeanLogMessageHeaderString + message + " : " +
                             this +CIBMbeanNewLine +
                             CIBMbeanLogMessageClosingString);
      throw new InvalidAttributeValueException(message);
    }
  }

  /**
   * Returns the PatchID String which represents the path revision applied
   * to the Componet product
   */
  public String getPatchId() {
    // patchId can be null indeed
    return myPatchId;
  }

  /**
   * Returns as a String the Vendor name.
   */
  public String getVendorName() throws InvalidAttributeValueException {
    if (myVendorName != null) {
      return myVendorName;
    }
    else {
      String message = FORBIDEN_NULL_VALUE + " VendorName" + " in CIBProduct";
      CIBMbeanLogger.warning(CIBMbeanLogMessageHeaderString + message + " : " +
                             this +CIBMbeanNewLine +
                             CIBMbeanLogMessageClosingString);
      throw new InvalidAttributeValueException(message);
    }
  }

  /**
   * Returns the installation time of the component product
   */
  public long getInstallTime() {
    return myInstallTime;
  }

  /**
   * Returns the list of ObjectName(s) of each Application instances running
   * into the Product
   */
  public ObjectName[] getApplications() {
    return setToObjectNameArray(myApplicationsSet);
  }

  /**
   * Returns the ObjectName for a given application
   */
  public ObjectName getApplicationByName(String name) {
    try {
      ObjectName on;
      String foundName;
      for (Iterator i = myApplicationsSet.iterator(); i.hasNext(); ) {
        on = (ObjectName) i.next();
        if ( (foundName = on.getKeyProperty(name)) != null) {
          return on;
        }
      }
    }
    catch (NullPointerException ne) {
      CIBMbeanLogger.info(CIBMbeanLogMessageHeaderString +
                          " Application named " + name +
                          " is not part of product : " +
                          this +CIBMbeanNewLine +
                          CIBMbeanLogMessageClosingString);
      return null;
    }

    return null;
  }

  // Private methods
  private ObjectName[] setToObjectNameArray(Set theSet) {
    ObjectName[] result = null;
    ObjectName elem = null;
    result = new ObjectName[theSet.size()];
    int i = 0;
    for (Iterator j = theSet.iterator(); j.hasNext(); ) {
      elem = (ObjectName) j.next();
      result[i] = elem;
      i++;
    }
    return result;
  }

}
