/***********************************************************
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 org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.verisign.epp.codec.gen.EPPDecodeException;
import com.verisign.epp.codec.gen.EPPEncodeException;
import com.verisign.epp.codec.gen.EPPInfoCmd;
import com.verisign.epp.codec.gen.EPPUtil;

/**
 * Represents an EPP Host &lt;info&gt; command that is used to retrieve
 * information associated with a host. The &lt;host:info&gt; element MUST
 * contain the following child elements:<br>
 * 
 * <ul>
 * <li>A &lt;host:name&gt; element that contains the fully qualified host name
 * for which information is requested. Use {@code getName} and {@code setName}
 * to get and set the element.</li>
 * </ul>
 * 
 * {@code EPPHostInfoResp} is the concrete {@code EPPReponse} associated with
 * {@code EPPHostInfoCmd}.
 * 
 * @see com.verisign.epp.codec.host.EPPHostInfoResp
 */
public class EPPHostInfoCmd extends EPPInfoCmd {
  /**
   * XML local name for {@code EPPHostInfoCmd}.
   */
  public static final String ELM_LOCALNAME = "info";

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

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

  /** Host Name to get information on. */
  private String name;

  /**
   * {@code EPPHostInfoCmd} default constructor. The name is initialized to
   * {@code null}. The name must be set before invoking {@code encode}.
   */
  public EPPHostInfoCmd() {
    name = null;
  }

  /**
   * {@code EPPHostInfoCmd} constructor that takes the host name as an
   * argument.
   *
   * @param aTransId
   *           Transaction Id associated with command.
   * @param aName
   *           Host name to get information on.
   */
  public EPPHostInfoCmd(String aTransId, String aName) {
    super(aTransId);

    name = aName;
  }

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

  /**
   * Gets the key for the host object, which is the host name.
   * 
   * @return The host name if set; {@code null} otherwise.
   */
  @Override
  public String getKey() {
    return this.getName();
  }
  
  /**
   * Encode a DOM Element tree from the attributes of the
   * {@code EPPHostInfoCmd} instance.
   *
   * @param aDocument
   *           DOM Document that is being built. Used as an Element factory.
   *
   * @return Root DOM Element representing the {@code EPPHostInfoCmd} instance.
   *
   * @exception EPPEncodeException
   *               Unable to encode {@code EPPHostInfoCmd} instance.
   */
  protected Element doEncode(Document aDocument) throws EPPEncodeException {
    // Validate state
    if (name == null) {
      throw new EPPEncodeException("required attribute name is not set");
    }

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

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

    return root;
  }

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

  /**
   * Gets the host name to get information on.
   *
   * @return Host Name {@code String} instance if defined; {@code null}
   *         otherwise.
   */
  public String getName() {
    return name;
  }

  /**
   * Sets the host name to get information on.
   *
   * @param aName
   *           Host Name
   */
  public void setName(String aName) {
    name = aName;
  }

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

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

    EPPHostInfoCmd theComp = (EPPHostInfoCmd) aObject;

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

    return true;
  }

  /**
   * Clone {@code EPPHostInfoCmd}.
   *
   * @return clone of {@code EPPHostInfoCmd}
   *
   * @exception CloneNotSupportedException
   *               standard Object.clone exception
   */
  public Object clone() throws CloneNotSupportedException {
    EPPHostInfoCmd clone = (EPPHostInfoCmd) 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);
  }

}
