/***********************************************************
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.domain;

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

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

/**
 * Represents an EPP Domain &lt;delete&gt; command that allows a client to
 * delete a domain object. The EPP &lt;delete&gt; command provides a transform
 * operation that allows a client to delete a domain object. In addition to the
 * standard EPP command elements, the &lt;delete&gt; command MUST contain a
 * "domain:delete" element that identifies the domain namespace and the location
 * of the domain schema. A domain object SHOULD NOT be deleted if subordinate
 * host objects are associated with the domain object. For example, if domain
 * "example.com" exists, and host object "ns1.example.com" also exists, then
 * domain "example.com" SHOULD NOT be deleted until host "ns1.example.com" has
 * been either deleted or renamed to exist in a different superordinate domain.
 * <br>
 * <br>
 *
 * <ul>
 * <li>A &lt;domain:name&gt; element that contains the fully qualified domain
 * name of the object to be deleted. Use {@code getName} and {@code setName} to
 * get and set the element.</li>
 * </ul>
 *
 * <br>
 * {@code EPPReponse} is the response associated with
 * {@code EPPDomainDeleteCmd}.
 *
 * @see com.verisign.epp.codec.gen.EPPResponse
 */
public class EPPDomainDeleteCmd extends EPPDeleteCmd {
  /**
   * XML local name for {@code EPPDomainDeleteCmd}.
   */
  public static final String ELM_LOCALNAME = "delete";

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

  /**
   * XML Element Name of a domain name in a {@code EPPDomainDeleteCmd}.
   */
  private final static String ELM_DOMAIN_NAME = "name";

  /**
   * Domain Name of domain to delete.
   */
  private String name;

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

  /**
   * {@code EPPDomainDeleteCmd} constructor that takes the domain name as an
   * argument.
   *
   * @param aTransId
   *           Transaction Id associated with command.
   * @param aName
   *           Domain name to delete.
   */
  public EPPDomainDeleteCmd(String aTransId, String aName) {
    super(aTransId);

    this.name = aName;
  }

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

	/**
	 * Gets the key for the domain name object, which is the domain name.
	 * 
	 * @return The domain name if set; {@code null} otherwise.
	 */
	@Override
	public String getKey() {
		return this.getName();
	}
  
  /**
   * Gets the domain name to delete.
   *
   * @return Domain Name {@code String} instance if defined; {@code null}
   *         otherwise.
   */
  public String getName() {
    return this.name;
  }

  /**
   * Sets the domain name to delete.
   *
   * @param aName
   *           Domain Name
   */
  public void setName(String aName) {
    this.name = aName;
  }

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

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

    EPPDomainDeleteCmd theComp = (EPPDomainDeleteCmd) aObject;

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

    return true;
  }

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

    return clone;
  }

  /**
   * Encode a DOM Element tree from the attributes of the
   * {@code EPPDomainDeleteCmd} instance.
   *
   * @param aDocument
   *           DOM Document that is being built. Used as an Element factory.
   *
   * @return Root DOM Element representing the {@code EPPDomainDeleteCmd}
   *         instance.
   *
   * @exception EPPEncodeException
   *               Unable to encode {@code EPPDomainDeleteCmd} instance.
   */
  @Override
  protected Element doEncode(Document aDocument) throws EPPEncodeException {
    // Validate state
    if (this.name == null) {
      throw new EPPEncodeException("name required attribute is not set");
    }

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

    // Name
    EPPUtil.encodeString(aDocument, root, this.name, EPPDomainMapFactory.NS,
          EPPDomainMapFactory.NS_PREFIX + ":" + ELM_DOMAIN_NAME);

    return root;
  }

  /**
   * Decode the {@code EPPDomainDeleteCmd} attributes from the aElement DOM
   * Element tree.
   *
   * @param aElement
   *           Root DOM Element to decode {@code EPPDomainDeleteCmd} from.
   *
   * @exception EPPDecodeException
   *               Unable to decode aElement
   */
  @Override
  protected void doDecode(Element aElement) throws EPPDecodeException {
    // Domain Name
    this.name = EPPUtil.decodeString(aElement, EPPDomainMapFactory.NS, ELM_DOMAIN_NAME);
  }

}
