//
// CIMQualifierType.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 CIMQualifierType.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: CIMQualifierType.java,v 1.2 2003/09/08 21:04:48 kumpf Exp $
//
// $Log: CIMQualifierType.java,v $
// Revision 1.2  2003/09/08 21:04:48  kumpf
// HP-BAPU: Fixed Bug No. 516 Java CIMQualifierType clone errors
//
// 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:36  karl
// import of SNIA 0_7
//
// Revision 1.6  2000/08/16 05:59:52  shawn
// merge P_TOMCAT31 branch
//
// Revision 1.5.8.1  2000/08/10 00:03:27  shawn
// head merge
//
// Revision 1.5  2000/05/11 10:12:20  davidsi
// - Fixed tabs.
//
// Revision 1.4  2000/05/06 17:04:23  davidsi
// - Modifications to bring classes inline with the SUN WBEM APIs 2.2.
//
// Revision 1.3  2000/04/09 13:19:16  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.util.Vector;
import java.io.Serializable;
import java.net.MalformedURLException;
import org.snia.wbemcmd.xml.XMLCIM;

/**
    Creates and instantiates a CIM qualifier type, which is a template
    for a CIM qualifier.  This class is useful for checking that a 
    characteristic is a valid CIM qualifier characteristic.  Each
    CIMQualifier must have a CIMQualifierType.  A CIM qualifier and its 
    CIM qualifier type must have the same name.
 */

public class CIMQualifierType  extends CIMElement implements Serializable {
    //
    // Please update clone() if you add to these!
    //
    CIMDataType dataType;
    Vector scope=null;		//CIMScope
    Vector flavor=null; 	//CIMFlavor
    CIMValue defaultValue=null;        
 
    // CIMQualifierType 
    //
    public CIMQualifierType() {
    }
    
 
    // CIMQualifierType 
    //
    public CIMQualifierType(String iname) {
	setName(iname);
    }
 
 
    // getScope 
    //
    // Returns the scope for this qualifier type
    public Vector getScope() {
	return(scope);
    }

 
    // getType 
    //
    // Returns data type 
    public CIMDataType getType() {
	return(dataType);
    } 
 
 
    // getSize 
    //
    // Returns the size
    public int getSize() {
	return(dataType.getSize());
    }
    
    // getDefaultValue
    //
    // Returns the default value
    //
    public CIMValue getDefaultValue() {
	return(defaultValue);
    }


    // setType 
    //
    // Sets the data type
    //
    public void setType(CIMDataType type) {
	dataType=type;
    }
     
 
    // setSize 
    //
    // Sets the size of this qualifier type 
    //
    //public void setSize(int aSize) {
    // SUNDIFF: NOT SUPPORTED. why have this? dataType gives us the size
    //}
 
 
    // setDefaultValue 
    // 
    // Sets the default value
    //
    public void setDefaultValue(CIMValue ivalue) {
	defaultValue=ivalue;
    }
    
    
    // toString 
    public String toString() {
	return(toMOF());
    }

    //	toMOF 
    public String toMOF() {
	int i;
	String ret=new String();
	
	ret=ret.concat(" : ");
	ret=ret.concat(dataType.toMOF());

	if (dataType.isArrayType()) {
	    ret=ret.concat("["+dataType.getSize()+"]");
	}
	if (defaultValue!=null) {
	    ret=ret.concat("=");
	    ret=ret.concat(defaultValue.toMOF());
	}
	
	if (scope!=null && scope.size()>0) {
	    ret=ret.concat(",scope(");
	    for(i=0;i<scope.size();i++) {
		if (i>0)
		    ret=ret.concat(",");
		ret=ret.concat( ((CIMScope)scope.elementAt(i)).toMOF());
	    }
	    ret=ret.concat(")");
	}
	if (flavor!=null && flavor.size()>0) {
	    for(i=0;i<flavor.size();i++) {
		if (i>0)
		    ret=ret.concat(",");
		ret=ret.concat( ((CIMFlavor)flavor.elementAt(i)).toMOF());
	    }
	    ret=ret.concat(")");
	}
	ret=ret.concat(";\n");
	return(ret);
    } 
 
    // addScope 
    //
    // Adds another scope 
    //
    public void addScope(CIMScope metaElement) {
	if (scope==null)
	    scope=new Vector();
	scope.addElement(metaElement);
    }

    // hasScope
    //
    // Returns TRUE if the qualifiertype's scope includes the passed 
    // value
    public boolean hasScope(CIMScope metaElement) {
	int i;
	
	if (scope!=null) {
	    int tsize=scope.size();
	    for(i=0;i<tsize;i++)
		if (((CIMScope)scope.elementAt(i)).getScope()==metaElement.getScope())
		    return(true);
	}	 
	return(false);
    }
 
    // hasFlavor 
    // Returns TRUE if the qualifiertype's flavor has
    // the specified flavor 
    public boolean hasFlavor(CIMFlavor iflavor) {
	int i;
	if (flavor!=null) {
	    int tsize=flavor.size();
	    for(i=0;i<tsize;i++)
		if (((CIMFlavor)flavor.elementAt(i)).getFlavor()==iflavor.getFlavor())
		    return(true);
	}
	return(false);
    }
 
 
    // addFlavor 
    //
    // Adds a flavor
    // SUNDIFF: SUN's API verifies there is no conflict but
    // there is no way of returning an error - this version lets
    // the conflict happen - it needs to get checked elsewhere
    //
    public void addFlavor(CIMFlavor newFlavor) {
	int i;
	
	//
	// Don't add it if its already present
	//
	if (flavor!=null) {
	    int tsize=flavor.size();
	    for(i=0;i<tsize;i++)
		if (((CIMFlavor)flavor.elementAt(i)).getFlavor()==newFlavor.getFlavor())
		    return;
	} else
	    flavor=new Vector();
	flavor.addElement(newFlavor);
    }
 
    // getFlavor 
    public Vector getFlavor() {
	return(flavor);
    }
 
    // hasDefaultValue 
    // Returns true if there is a default value
    //
    public boolean hasDefaultValue() {
	return(defaultValue!=null);
    }

 
    // isArrayValue 
    // Returns TRUE if the default value is an array 
    public boolean isArrayValue() {
	if (defaultValue!=null)
	    return(defaultValue.isArrayValue());
	return(false);
    }
    
    //
    // NOTSUN
    //
    public Object clone() {
	CIMQualifierType ct=new CIMQualifierType();
        
	if (scope!=null)
        {
	    Vector tmpScope=new Vector(); // Create empty vector
            ct.scope=tmpScope;
	    for(int i=0;i<scope.size();i++)
            {
		ct.scope.addElement(scope.elementAt(i));
            }
        }
	if (flavor!=null)
        {
	    Vector tmpFlavor=new Vector(); // Create empty vector
            ct.flavor=tmpFlavor;
	    for(int i=0;i<flavor.size();i++)
            {
		ct.flavor.addElement(flavor.elementAt(i));
            }
        }
	if (defaultValue!=null)
	    ct.defaultValue=new CIMValue(defaultValue.getValue(),
				     defaultValue.getType());  
	ct.dataType=dataType;
	
	return(ct);
    }
      // toXmlQualDecl - returns a qualifier declaration
    public String toXml() throws MalformedURLException {
	StringBuffer text;
	CIMFlavor fv;
	String cimName=getName();
	
	if (cimName==null)
	    throw new MalformedURLException("qualifier must have name");

	//
	// If type isn't set then the CIMOM has stored a qualifier
	// thats bad and an exception is generated
	//
	if (dataType==null) {
	    throw new MalformedURLException("QualifierType ("+cimName+") does not have a type set");
	}
	

	
	
	text=new StringBuffer("<QUALIFIER.DECLARATION NAME=\""+cimName+"\" "+
				 "TYPE=\""+dataType.toXml()+"\" ");
	if (dataType.isArrayType()) {
	    text=text.append("ISARRAY=\"true\" ");
	} else {
	    text=text.append("ISARRAY=\"false\" ");
	}
	    
	//
	//
	fv=CIMFlavor.getFlavor(CIMFlavor.ENABLEOVERRIDE);
	if (hasFlavor(fv))
	    ;
	    // NOT NECESSARY, default is TRUE
	    // text=text.concat(fv.toXml()+"=\"true\" ");
	else {
	    fv=CIMFlavor.getFlavor(CIMFlavor.DISABLEOVERRIDE);
	    if (hasFlavor(fv)) 
		text=text.append(fv.toXml()+"=\"false\" ");
	}
	
	fv=CIMFlavor.getFlavor(CIMFlavor.TOSUBCLASS);
	if (hasFlavor(fv)) 
	    ;
	    // NOT NECESSARY, default is TRUE
	    // text=text.concat(fv.toXml()+"=\"true\" ");
	else {
	    fv=CIMFlavor.getFlavor(CIMFlavor.RESTRICTED);
	    if (hasFlavor(fv)) 
		text=text.append(fv.toXml()+"=\"false\" ");
	}
	
	fv=CIMFlavor.getFlavor(CIMFlavor.TRANSLATE);
	if (hasFlavor(fv)) 
	    text=text.append(fv.toXml()+"=\"true\" ");
	//
	// NOT NECESSARY, default is FALSE
	//else
	//  text=text.concat(fv.toXml()+"=\"false\" ");

	text=text.append("><SCOPE ");
	//
	// Write scope information
	//
	String scope;
	boolean scopeWritten=false;
	boolean any=hasScope(CIMScope.getScope(CIMScope.ANY));
	
	if (any || hasScope(CIMScope.getScope(CIMScope.CLASS))) {
	    text=text.append("CLASS=\"true\" ");
	    scopeWritten=true;
	}
	if (any || hasScope(CIMScope.getScope(CIMScope.INSTANCE))) {
	    text=text.append("INSTANCE=\"true\" ");
	    scopeWritten=true;
	}
	if (any || hasScope(CIMScope.getScope(CIMScope.ASSOCIATION))) {
	    text=text.append("ASSOCIATION=\"true\" ");
	    scopeWritten=true;
	}
	if (any ||hasScope(CIMScope.getScope(CIMScope.REFERENCE))) {
	    text=text.append("REFERENCE=\"true\" ");
	    scopeWritten=true;
	}
	if (any ||hasScope(CIMScope.getScope(CIMScope.PROPERTY))) {
	    text=text.append("PROPERTY=\"true\" ");
	    scopeWritten=true;
	}
	if (any ||hasScope(CIMScope.getScope(CIMScope.METHOD))) {
	    text=text.append("METHOD=\"true\" ");
	    scopeWritten=true;
	}
	if (any ||hasScope(CIMScope.getScope(CIMScope.PARAMETER))) {
	    text=text.append("PARAMETER=\"true\" ");
	    scopeWritten=true;
	}
	if (any ||hasScope(CIMScope.getScope(CIMScope.INDICATION))) {
	    text=text.append("INDICATION=\"true\" ");
	    scopeWritten=true;
	}

	if (!scopeWritten) {
	    throw new MalformedURLException("No scope set on qualifier type("+getName()+")");
	}
	
	text=text.append("></SCOPE>");
	
	if (defaultValue!=null) {
	    if (dataType.isArrayType()) {
		Vector v=(Vector)defaultValue.getValue();
		text=text.append("<VALUE.ARRAY>");
		for(int i=0;i<v.size();i++)
			text=text.append("<VALUE>"
					 +XMLCIM.xmlCIMEscape.XMLEscape(v.elementAt(i).toString())
					 +"</VALUE>");
		text=text.append("</VALUE.ARRAY>");
	    } else 
		text=text.append("<VALUE>"+
				 XMLCIM.xmlCIMEscape.XMLEscape(defaultValue.toString())+
				 "</VALUE>");
	}
	    
	
	text=text.append("</QUALIFIER.DECLARATION>");
	
	return(text.toString());
    }
    
}
