/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by Ovidiu
 * Predescu <ovidiu@cup.hp.com> on behalf of the Apache Software
 * Foundation and was originally developed at Hewlett Packard Company.
 * For more information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.xml.dtm.ref;

import javax.xml.transform.SourceLocator;

/**
 * <code>NodeLocator</code> maintains information on an XML source
 * node.
 *
 * @author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu</a>
 * @since May 23, 2001
 */
public class NodeLocator implements SourceLocator
{
  protected String m_publicId;
  protected String m_systemId;
  protected int m_lineNumber;
  protected int m_columnNumber;

  /**
   * Creates a new <code>NodeLocator</code> instance.
   *
   * @param publicId a <code>String</code> value
   * @param systemId a <code>String</code> value
   * @param lineNumber an <code>int</code> value
   * @param columnNumber an <code>int</code> value
   */
  public NodeLocator(String publicId, String systemId,
                     int lineNumber, int columnNumber)
  {
    this.m_publicId = publicId;
    this.m_systemId = systemId;
    this.m_lineNumber = lineNumber;
    this.m_columnNumber = columnNumber;
  }

  /**
   * <code>getPublicId</code> returns the public ID of the node.
   *
   * @return a <code>String</code> value
   */
  public String getPublicId()
  {
    return m_publicId;
  }

  /**
   * <code>getSystemId</code> returns the system ID of the node.
   *
   * @return a <code>String</code> value
   */
  public String getSystemId()
  {
    return m_systemId;
  }

  /**
   * <code>getLineNumber</code> returns the line number of the node.
   *
   * @return an <code>int</code> value
   */
  public int getLineNumber()
  {
    return m_lineNumber;
  }

  /**
   * <code>getColumnNumber</code> returns the column number of the
   * node.
   *
   * @return an <code>int</code> value
   */
  public int getColumnNumber()
  {
    return m_columnNumber;
  }

  /**
   * <code>toString</code> returns a string representation of this
   * NodeLocator instance.
   *
   * @return a <code>String</code> value
   */
  public String toString()
  {
    return "file '" + m_systemId
      + "', line #" + m_lineNumber
      + ", column #" + m_columnNumber;
  }
}
