//
// CIMNameSpace.java
//
// The contents of this file are subject to the SNIA Public License Version 1.0
// (the "License"); you may not use this file except in compliance with the
// License. You may obtain a copy of the License at
//
//	http://www.snia.org/resources/openSource.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 
// License for the specific language governing rights and limitations
// under the License.
//
// The Original Code is CIMNameSpace.java
// 
// The Initial Developer of the Original Code is David Simons.
//
// Contributor(s):
//
//
// This source uses the Solaris WBEM APIs version 2.2. 
// Synchronization will be maintained with the Solaris WBEM APIS,
// which are being standardized through the Java Community Process.
//
//
// $Id: CIMNameSpace.java,v 1.1 2003/07/17 18:32:55 kumpf Exp $
//
// $Log: CIMNameSpace.java,v $
// Revision 1.1  2003/07/17 18:32:55  kumpf
// HP-BAPU: PEP-64 CIM Client and CIM Listener Java Interface
//
// Revision 1.1.1.1  2001/10/31 18:14:26  karl
// import of SNIA 0_7
//
// Revision 1.14  2001/07/08 16:12:54  davidsi
// - Moved default port to 5988.
//
// Revision 1.13  2001/07/01 11:27:21  davidsi
// - Made the default namespace a public in CIMClient so now it is only
//   defined in a single place.
//
// Revision 1.12  2000/11/18 13:48:01  davidsi
// - Added back default port of 80, which gets set if no port number
//   can be found.
//
// Revision 1.11  2000/11/11 14:52:58  davidsi
// - From hfcheng, add check for null hostname.
//
// Revision 1.10  2000/11/06 18:05:47  davidsi
// - From Heung-For Cheng. Added more javadoc.
//
// Revision 1.9  2000/09/15 16:52:33  davidsi
// - From Heung-For Cheng. Fixed constructors to handle urls.
//
// Revision 1.8  2000/09/15 16:39:35  davidsi
// - From Heung-For Cheng. Added getHostURL() and parse().
//
// Revision 1.7  2000/08/16 05:59:52  shawn
// merge P_TOMCAT31 branch
//
// Revision 1.6.8.1  2000/08/10 00:03:27  shawn
// head merge
//
// Revision 1.6  2000/05/11 10:12:20  davidsi
// - Fixed tabs.
//
// Revision 1.5  2000/05/09 20:14:54  davidsi
// - Fixed URL support so that it takes a string (not a URL object).
//
// Revision 1.4  2000/05/06 17:04:21  davidsi
// - Modifications to bring classes inline with the SUN WBEM APIs 2.2.
//
// Revision 1.3  2000/04/09 13:19:15  davidsi
// - Switched to StringBuffer (from String) for XML generation.
//
// Revision 1.2  2000/02/13 15:09:07  davidsi
// - Added text to cover re-use of Solaris WBEM APIs.
//
// Revision 1.1.1.1  2000/02/06 16:41:03  davidsi
// Initial version.
//
//
//
package org.snia.wbem.cim;

import java.net.MalformedURLException;
import java.io.Serializable;
import java.net.URL;
import org.snia.wbemcmd.xml.XMLCIM;

/**
    Creates and instantiates a CIM namespace, a component of a CIM
    object name (namespace + model path) that provides a scope within
    which the objects are unique.
 */

public class CIMNameSpace extends Object implements Serializable {
    // http default port is 5988
    static public final int DEFAULT_PORT=5988;

    // Default namespace name 
    static public final String DEFAULT_NAMESPACE="\\root\\cimv2";

    String nameSpace= DEFAULT_NAMESPACE;

    String hostName="127.0.0.1";
    int portNumber=DEFAULT_PORT;
    String protocol=new String("http");
    String fileName=new String("/cimom");

   /***
    * Constructs a default instance (for localhost's CIM namespace
    * "\Root\CIMV2").
    */
    public CIMNameSpace() {
    }


    /**
     * Constructs an instance on the specified host's CIM namespace
     *  "\Root\CIMV2").
     * @param host Host information (host name or URL spec).
     *   <br><ul><li> "myhost"
     *   <li> "http://myhost/cimom" or "http://myhost:8080/cimom"
     *   <li> "//myhost/cimom" or "//myhost:8080/cimom"
     *</ul>
     **/
    public CIMNameSpace(String host){
     	this(host, null);
    }


    /**
     * Constructs an instance on the specified host's specified CIM namespace.<p>
     * Note: This method uses a very simplistic approach to differentiate the
     * two formats of the 1st paramter.
     * If the string does not contain any slash ('/') character, it is assumed
     * to be a simple host name.  Otherwise, it is assumed to be a URL spec.
     * <p>
     *   @param host                 Host information (host name or URL spec).
     * <br><ul><li> "myhost"
     * <li> "http://myhost/cimom" or "http://myhost:8080/cimom"
     * <li> "//myhost/cimom" or "//myhost:8080/cimom"
     *</ul>
     *   @param ns                   Name of the CIM namespace
     **/
    public CIMNameSpace(String host,String ns){
	try {
	    if (host !=null) {
		// if no slash in the parameter, assume it to be the host name
		if (host.indexOf('/') == -1)
		    hostName = host;
		// if at least one slash, consider it to be a URL spec.
		else {
		    // Use default data to provide the context URL
		    URL context = new URL (protocol, host, fileName);
	    	    URL url = new URL(context, host);
		    hostName = url.getHost();
                    //protocol = url.getProtocol();    // always use HTTP

                    // Added by Bapu ( 07/22/02) 
                    protocol = url.getProtocol();    // HTTP or HTTPS

		    portNumber=url.getPort();
		    // if port number is not specified, use http default port
		    if (portNumber == -1)
		        portNumber = DEFAULT_PORT;
		    // Should be "/cimom", but some servers (e.g., Solaris) may have
		    // a special URL for custom purposes.
		    fileName = url.getFile();
		}
	    }
	} catch (MalformedURLException me) {
	    System.out.println("Exception: "+me);
	    // use default Host (localhost) and URL
        }

	// use specified namespace
	if (ns != null)
	    nameSpace = ns;
    }

    

    
   /** 
    * Gets (path)name of namespace
    * 
    * @return        (path)name of CIM namespace.
    **/
    public String getNameSpace(){
	return(nameSpace);
    }


   /**
    * Gets the host url of this CIM namespace
    * 
    * @return  a URL instance representing this CIM namespace.
    **/
    public String getHost(){
	return(hostName);
    }

   /**
    * Gets the host url of this CIM namespace
    *
    * @return	A URL instance representing this CIM namespace.
    */
    public java.net.URL getHostURL() {
	URL hostURL;
	try {
	    hostURL=new URL(protocol, hostName, portNumber, fileName);
	} catch (MalformedURLException me) {
	    hostURL=null;
	}
	return(hostURL);
    }
    
   /**
    * parses the name of a namespace by replacing the forward slash (/) with
    * a backward slash (\). For example, if you pass the name of the default
    *  namespace, /cim/v2, this routine replaces this string with \cim\v2.
    * <p>
    *    [TBD]:  Sun's interface definition (no return value) seems to be in error.
    *            String is immutable, and replacing input String instance with a 
    *            newly modified String instance on stack does not do much for 
    *           the user.  So, we will return the new String for now, and send 
    *           a clarification query to Sun/JSR-000048 folks.
    * <p>
    * @param p  the string to parse
    * @return   a new String with backslashes.
    **/
    public String parse(String p) {
	return p.replace('/', '\\');
    }
     
     
 
   /***
    * Sets namespace
    *
    * @param ns  the string representing the name of this CIM namespace
    */
    public void setNameSpace(String ns) {
	nameSpace=ns;
    }
     
     

    /**
     * Sets host name
     * @param h  the string representing the host name of this CIM namespace
     **/
    public void setHost(String h){
	hostName=h;
    }


    /***
     *
     * Returns a String representation of the CIMNameSpace. <p>
     * This is expected to be implementation specific, and the names of 
     * namespace and host are used for this implementation. <p>
     * @return   A String representation of this instance.
     */
    public String toString(){
	return("CIMNameSpace="+nameSpace+" [host "+hostName+"]");
    }
 
 

    /***
     * Writes namespace using NAMESPACEPATH
     *
     * @return XML Document (a String) representing this
     *          +instance (using NAMESPACEPATH). 
     */
    public String toXml() throws MalformedURLException {
	return(toXml(false));
    }
    
   /***
    * Writes namespace using LOCALNAMESPACEPATH. <p>
    * @param dolocal                    for localhost: <ul>
    *          <li> false = write as LOCALNAMESPACEPATH
    *          <li> true = write as NAMESPACEPATH.
    * </ul><p>
    * @return XML Document (a String) representing this
    *         instance (using LOCALNAMESPACEPATH).
    */
    public String toXml(boolean dolocal) throws MalformedURLException {
	StringBuffer nameSpaceXML=new StringBuffer();
	String name=nameSpace;
	
	if (name==null)
	    throw new MalformedURLException("Namespace not set");
	for(;;) {
	    int index=name.indexOf('/');
	    if (index== -1)
		index=name.indexOf('\\');
		if (index== -1)
		    break;
	    nameSpaceXML=nameSpaceXML.append("<NAMESPACE NAME=\""+
				    XMLCIM.xmlCIMEscape.XMLEscape(name.substring(0,index))+
				    "\"></NAMESPACE>");
	    name=name.substring(index+1);
	}	
	nameSpaceXML=nameSpaceXML.append("<NAMESPACE NAME=\""+
					 XMLCIM.xmlCIMEscape.XMLEscape(name)+
					 "\"></NAMESPACE>");

	if (dolocal)
	    return("<LOCALNAMESPACEPATH>"+nameSpaceXML+"</LOCALNAMESPACEPATH>");
	else
	    return("<NAMESPACEPATH><HOST>"+XMLCIM.xmlCIMEscape.XMLEscape(hostName)+
		   "</HOST><LOCALNAMESPACEPATH>"+
		   nameSpaceXML+
		   "</LOCALNAMESPACEPATH></NAMESPACEPATH>");
    }
    
    //
    // NOT SUN
    //
   /**
    * gets the Port Number.
    * @return The port number used to access the namespace
    *         represented by this instance.
    */
    public int getPortNumber() {
	return(portNumber);
    }


   /**
    * get the protocol.
    * 
    * @return  The protocol used to access the namespace 
    *          represented by this instance.
    */
    public String getProtocol() {
	return(protocol);
    }

	
   /**
    * get the file name. 
    * 
    * @return The filename of the URL representing this
    *         namespace instance.
    */
    public String getFileName() {
	return(fileName);
    }
}
