/***********************************************************
Copyright (C) 2004 VeriSign, Inc.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library 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
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

http://www.verisign.com/nds/naming/namestore/techdocs.html
***********************************************************/
package com.verisign.epp.codec.host;

import java.util.Date;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.verisign.epp.codec.gen.EPPCodecException;
import com.verisign.epp.codec.gen.EPPDecodeException;
import com.verisign.epp.codec.gen.EPPEncodeException;
import com.verisign.epp.codec.gen.EPPResponse;
import com.verisign.epp.codec.gen.EPPTransId;
import com.verisign.epp.codec.gen.EPPUtil;

/**
 * Represents an EPP Host &lt;host:resData&gt; response to a
 * {@code EPPHostCreateCmd}. When a &lt;create&gt; command has been processed
 * successfully, the EPP &lt;resData&gt; element MUST contain a child
 * &lt;host:creData&gt; element that identifies the host namespace and the
 * location of the host schema. The &lt;host:creData&gt; element SHALL contain
 * the following child elements: <br>
 * 
 * <ul>
 * <li>A &lt;host:name&gt; element that contains the fully qualified name of the
 * host object. Use {@code getName} and {@code setName} to get and set the
 * element.</li>
 * <li>A &lt;host:crDate&gt; element that contains the date and time of host
 * object. Use {@code getCreationDate} and {@code setCreationDate} to get and
 * set the element.</li>
 * </ul>
 * 
 * @see com.verisign.epp.codec.host.EPPHostCreateCmd
 */
public class EPPHostCreateResp extends EPPResponse {
  /**
   * XML local name for {@code EPPHostCreateResp}.
   */
  public static final String ELM_LOCALNAME = "creData";

  /**
   * XML Element Name of {@code EPPHostCreateResp} root element.
   */
  public static final String ELM_NAME = EPPHostMapFactory.NS_PREFIX + ":" + ELM_LOCALNAME;

  /** XML Element Name of {@code EPPHostCreateResp} root element. */
  final static String ELM_HOST_NAME = "name";

  /** XML Element Name of {@code EPPHostCreateResp} root element. */
  final static String ELM_ROID = "roid";

  /** XML Element Name for the {@code crDate} attribute. */
  private final static String ELM_CREATION_DATE = "crDate";

  /** Host Name of host created. */
  private java.lang.String name = null;

  /** Creation Date. */
  private java.util.Date creationDate = null;

  /**
   * {@code EPPHostCreateResp} default constructor. <br>
   * It will set results attribute to an empty {@code Vector}. The name is
   * initialized to null. The creation date must be set before invoking
   * {@code encode}.
   */
  public EPPHostCreateResp() {
    name = null;
  }

  /**
   * {@code EPPHostCreateResp} constructor that will set the result of an
   * individual host. The creation date must be set before invoking
   * {@code encode}.
   *
   * @param aTransId
   *           Transaction Id associated with response.
   * @param aName
   *           Host name
   */
  public EPPHostCreateResp(EPPTransId aTransId, String aName) {
    super(aTransId);

    name = aName;
  }

  /**
   * {@code EPPHostCreateResp} constructor that takes the required attribute
   * values as parameters.
   *
   * @param aTransId
   *           Transaction Id associated with response.
   * @param aName
   *           Host name
   * @param aCreationDate
   *           Creation date of the host
   */
  public EPPHostCreateResp(EPPTransId aTransId, String aName, Date aCreationDate) {
    super(aTransId);

    name = aName;
    creationDate = aCreationDate;
  }

  /**
   * Get the EPP response type associated with {@code EPPHostCreateResp}.
   *
   * @return EPPHostCreateResp.ELM_NAME
   */
  public String getType() {
    return ELM_NAME;
  }

  /**
   * Get the EPP command Namespace associated with {@code EPPHostCreateResp}.
   *
   * @return {@code EPPHostMapFactory.NS}
   */
  public String getNamespace() {
    return EPPHostMapFactory.NS;
  }

  /**
   * Get creation date.
   *
   * @return creation date
   */
  public Date getCreationDate() {
    return creationDate;
  }

  /**
   * Set creation date.
   *
   * @param aCrDate
   *           creation date
   */
  public void setCreationDate(Date aCrDate) {
    creationDate = aCrDate;
  }

  /**
   * Encode a DOM Element tree from the attributes of the
   * {@code EPPHostCreateResp} instance.
   *
   * @param aDocument
   *           DOM Document that is being built. Used as an Element factory.
   *
   * @return Element Root DOM Element representing the
   *         {@code EPPHostCreateResp} instance.
   *
   * @exception EPPEncodeException
   *               Unable to encode {@code EPPHostCreateResp} instance.
   */
  protected Element doEncode(Document aDocument) throws EPPEncodeException {
    try {
      validateState();
    }
    catch (EPPCodecException e) {
      throw new EPPEncodeException("Invalid state on EPPHostCreateResp.encode: " + e);
    }

    Element root = aDocument.createElementNS(EPPHostMapFactory.NS, ELM_NAME);

    // name
    EPPUtil.encodeString(aDocument, root, name, EPPHostMapFactory.NS,
          EPPHostMapFactory.NS_PREFIX + ":" + ELM_HOST_NAME);

    // Creation Date
    EPPUtil.encodeTimeInstant(aDocument, root, creationDate, EPPHostMapFactory.NS,
          EPPHostMapFactory.NS_PREFIX + ":" + ELM_CREATION_DATE);

    return root;
  }

  /**
   * Decode the {@code EPPHostCreateResp} attributes from the aElement DOM
   * Element tree.
   *
   * @param aElement
   *           Root DOM Element to decode {@code EPPHostCreateResp} from.
   *
   * @exception EPPDecodeException
   *               Unable to decode aElement
   */
  protected void doDecode(Element aElement) throws EPPDecodeException {
    // name
    name = EPPUtil.decodeString(aElement, EPPHostMapFactory.NS, ELM_HOST_NAME);

    // Creation Date
    creationDate = EPPUtil.decodeTimeInstant(aElement, EPPHostMapFactory.NS, ELM_CREATION_DATE);
  }

  /**
   * Compare an instance of {@code EPPHostCreateResp} with this instance.
   *
   * @param aObject
   *           Object to compare with.
   *
   * @return {@code true} when equal; {@code false} otherwise.
   */
  public boolean equals(Object aObject) {
    if (!(aObject instanceof EPPHostCreateResp)) {
      return false;
    }

    if (!super.equals(aObject)) {
      return false;
    }

    EPPHostCreateResp theCreateData = (EPPHostCreateResp) aObject;

    // Name
    if (!((name == null) ? (theCreateData.name == null) : name.equals(theCreateData.name))) {
      return false;
    }

    // Creation Date
    if (!((creationDate == null) ? (theCreateData.creationDate == null) :
          creationDate.equals(theCreateData.creationDate))) {
      return false;
    }

    return true;
  }

  /**
   * Clone {@code EPPHostCreateResp}.
   *
   * @return clone of {@code EPPHostCreateResp}
   *
   * @exception CloneNotSupportedException
   *               standard Object.clone exception
   */
  public Object clone() throws CloneNotSupportedException {
    EPPHostCreateResp clone = (EPPHostCreateResp) super.clone();

    return clone;
  }

  /**
   * Implementation of {@code Object.toString}, which will result in an
   * indented XML {@code String} representation of the concrete
   * {@code EPPCodecComponent}.
   *
   * @return Indented XML {@code String} if successful; {@code ERROR}
   *         otherwise.
   */
  public String toString() {
    return EPPUtil.toString(this);
  }

  /**
   * Get host name.
   *
   * @return String Host Name
   */
  public java.lang.String getName() {
    return name;
  }

  /**
   * Set host name.
   *
   * @param newName
   *           String
   */
  public void setName(String newName) {
    name = newName;
  }

  /**
   * Validate the state of the {@code EPPHostCreateResp} instance. A valid
   * state means that all of the required attributes have been set. If
   * validateState returns without an exception, the state is valid. If the
   * state is not valid, the EPPCodecException will contain a description of
   * the error.
   *
   * @throws EPPCodecException
   *            Invalid state
   */
  void validateState() throws EPPCodecException {
    if (name == null) {
      throw new EPPCodecException("required attribute name is not set");
    }

    if (creationDate == null) {
      throw new EPPCodecException("required attribute creationDate is not set");
    }
  }

}
