package client.java_and_ws.static0;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import weblogic.jndi.Environment;
import java.io.StringWriter;
/*
 * DSP Client - run in a webapp or stand-alone, uses either java or web service mediator
 * 
 * Everything you need to know is in the run() method.
 * 
 * You will need in your classpath
 * aldsp_3.2/ld-client.jar, 
 * wlserver_10.0/weblogic.jar, 
 * wlserver_10.0/wlclient.jar, 
 * wlserver_10.0/wls-api.jar,
 * modules/com.bea.core.sdo*.jar
 * 
 * If you are running as a Java Application from your 
 * Dynamic Web Project, make sure that "WebLogic System Libraries"
 * are *NOT* in the classpath.
 * 
 */
public class ClientComplexArgList{
/* add this to the bottom of ld:RetailApplication/CustomerManagement/ProfileService.ds and redeploy the dataspace

 (::pragma  function <f:function kind="library" visibility="public" isPrimary="false" xmlns:f="urn:annotations.ld.bea.com"/>::)
declare function tns:getServiceCases($profiles as element(ns5:PROFILES)) as element(ns7:CASE)*{
for $profile in $profiles/ns2:PROFILE
for $b in ns8:getServiceCaseByCustID($profile/CustomerID) 
return $b
};


* add this before </xs:schema> at the bottom of ld:RetailApplication/CustomerManagement/schemas/ProfileService.xsd and redeply the dataspace

    <xsd:complexType name="PROFILE_SERVICES">
      <xsd:sequence>
        <xsd:element ref="retailerType:PROFILE" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
    </xsd:complexType>
    <xsd:element name="PROFILES" type="retailer:PROFILE_SERVICES"/>

 */
	String locator="http://localhost:7001/RetailDataspace/RetailApplication/CustomerManagement/ProfileService.ws?WSDL";
	String dsLocator=null;
	String uri=null;
	String username= "weblogic";
	String password="weblogic";
	java.io.Writer out=new java.io.PrintWriter(System.out);
	String className=this.getClass().getName().substring(this.getClass().getName().lastIndexOf('.')+1);
	String runningIn=this.getClass().getClassLoader().equals(com.bea.dsp.das.DASResult.class.getClassLoader()) ? "standalone" : "webapp";
	String contextCacheKey=null;
	enum ClientType {java, webservice, control};
	ClientType clientType=ClientType.java;
	enum ClassloaderType { noclassloader, currentthread, other};
	ClassloaderType classloaderType=ClassloaderType.noclassloader;

	public ClientComplexArgList(){
		this((String)null,(String)null,(String)null, (String)null, null, null);
	}
	public ClientComplexArgList(java.io.Writer out){
		this((String)null,(String)null,(String)null, (String)null, out, null);
	}
	public ClientComplexArgList(String locator){
		this(locator,(String)null,(String)null, (String)null, null, null);
	}
	public ClientComplexArgList(String locator, java.io.Writer out, String classloadertypeStr){
		this(locator,(String)null,(String)null, (String)null, out, classloadertypeStr);
	}
	public ClientComplexArgList(String cType, String locator, String username, String password, java.io.Writer out, String classloadertypeStr){
		if(cType != null) this.clientType=ClientType.valueOf(cType);
		if(locator!=null) this.locator=locator;
		if(username!=null) this.username=username;
		if(password!=null)this.password=password;
		if(out!=null) this.out=out;
		if(classloadertypeStr != null) this.classloaderType=ClassloaderType.valueOf(classloadertypeStr);
	}	
	
	public static void main(String[] args) {
		String locator=args.length > 0 ? args[0] : null;
		String uri=args.length > 1 ? args[1] : null;
		String username=args.length > 2 ? args[2] : null;
		String password=args.length > 3 ? args[3] : null;
		String classloadertypeStr=args.length > 4 ? args[4] : null;
		ClientComplexArg c=new ClientComplexArg(locator, uri, username, password, null, classloadertypeStr);
		c.run();
	}
	
	public void run(){

		if(! locator.startsWith("http://") ){
			out("locator must be http://... (wsdl URL)");
			return;
		}
		das.ws.retailapplication.customermanagement.ProfileServiceDAS wsDas = null;
		das.ejb.retailapplication.customermanagement.ProfileServiceDAS ejbDas = null;
		com.bea.dsp.das.DASResult<retailer.CASE_SERVICE> dasResult = null;
		
		try {
			
			System.err.println("--------------------------------------------------------------");
			out("-----------------------------------------------------------------------------");

			// The DSP webservice client identifies DataAccessService by the url of the wsdl
			// The DSP java client identifies DataAccessServices by the dataspace name
			// These examples parse the wsdl url to get the necessary strings for the java client
			// http://localhost:7001/RetailDataspace/RetailApplication/CustomerManagement/ProfileService.ws?WSDL
				
			if(isWebServiceClient()){
				contextCacheKey=locator;
	   			wsDas=das.ws.retailapplication.customermanagement.ProfileServiceDAS.getInstance(new java.util.Hashtable(), contextCacheKey);
			} else {
				/* set uri, contextCacheKey, dsLocator - normally you would just use strings instead of obtaining from the wsdl url*/
				splitLocator(locator);
				Context ctx = getInitialContext(uri, username,password);
				ejbDas=
                    das.ejb.retailapplication.customermanagement.ProfileServiceDAS.getInstance(ctx, contextCacheKey);
			}

			commonj.sdo.helper.HelperContext hc=com.bea.dsp.das.HelperContextCache.get(contextCacheKey);
			commonj.sdo.helper.XMLHelper xh = hc.getXMLHelper();
			commonj.sdo.helper.DataFactory factory = hc.getDataFactory();

			// To create the argument: Must give the namespace uri and the name of the type of the argument
			// Open RetailDataspace/RetailApplication/CustomerManagement/ProfileService.ds
			// In the Design View, right-click->Edit Signature on the getServiceCase function
			// Select the PROFILE argument and click on Edit
			// The Schema file field will show the schema file where the element is defined,
			// copy the schema file (ctrl-a, ctrl-c), and then open it in File->Open (paste
			// the filename in with ctrl-v (then change the forward slashes to backward
			// slashes) to open the file
			// Click on 'Design' view of the open schema file.
 			// On the left-hand side will be an Elements box containg a list of Elements : Types
			// Find the PROFILE element, you will see its type is named PROFILE_SERVICE. The
			// namespace uri for the type is shown at the top of the Schemas box 
			// (urn:retailer)

			retailer.PROFILE_SERVICES profileService =(retailer.PROFILE_SERVICES)factory.create("urn:retailer",
			"PROFILE_SERVICES");
			com.bea.dsp.sdo.SDOUtil.setElementName(profileService,
					"urn:retailer", "PROFILES");
			retailertype.PROFILE_TYPE profile = profileService.createPROFILE();
			profile.setCustomerID("CUSTOMER4"); 
			profile.setFirstName("dummyFirstName"); 
			profile.setLastName("dummyLastName");
			profile.setCustomerSince( "2001-01-01");
			profile.setEmailAddress( "dummyEmailAddress");
			profile.setTelephoneNumber("8885551212");
			
			profile = profileService.createPROFILE();
			profile.setCustomerID("CUSTOMER6"); 
			profile.setFirstName("dummyFirstName"); 
			profile.setLastName("dummyLastName");
			profile.setCustomerSince( "2001-01-01");
			profile.setEmailAddress( "dummyEmailAddress");
			profile.setTelephoneNumber("8885551212");
		
			if(isWebServiceClient()){
				dasResult = wsDas.getServiceCases(profileService);
			} else {
				dasResult = ejbDas.getServiceCases(profileService);
			}

			while( dasResult.hasNext()){
				out("DataObject : " + dataObjectToString(xh,(retailer.CASE_SERVICE)dasResult.next()));
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(dasResult!=null) dasResult.dispose();
			} catch(Exception e){e.printStackTrace();}
			
		}
	}

	public void out(String s){
		try{
			if(out instanceof javax.servlet.jsp.JspWriter)
				s=s.replace("&","&amp;").replace("<", "&lt;").replace(">", "&gt;");
			out.write(className+"/"+runningIn+"/"+clientType+"/"+classloaderType+" "+s+"\n");
			out.flush();
		}catch (Exception e){
			e.printStackTrace();
		}
	}

	public static InitialContext getInitialContext(String url, String username,
			String password) throws NamingException {
		Environment env = new Environment();
		env.setProviderUrl(url);
		env.setInitialContextFactory("weblogic.jndi.WLInitialContextFactory");
		env.setSecurityPrincipal(username);
		env.setSecurityCredentials(password);
		return new InitialContext(env.getInitialContext().getEnvironment());
	}

	static String dataObjectToString(commonj.sdo.helper.XMLHelper xh, commonj.sdo.DataObject dObj) {
		try {
			com.bea.sdo.PropertyXML element = ((com.bea.sdo.DataObjectXML) dObj)
					.getContainmentPropertyXML();
			String elementName = element.getXMLName();
			String elementURI = element.getXMLNamespaceURI();
			commonj.sdo.helper.XMLDocument xmlDocument = xh.createDocument(dObj, elementURI,
					elementName);
			StringWriter outputWriter = new StringWriter();
			xh.save(xmlDocument, outputWriter, null);
			return outputWriter.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	boolean isWebServiceClient(){
		return clientType==ClientType.webservice;
	}
	
	void splitLocator(String locator) throws Exception {
		uri=null;
		contextCacheKey=null;
		dsLocator=null;
		for(int i=0, j=0, last=0;i<locator.length(); i++){
			if(locator.charAt(i) == '/'){
				j++;
				if(j==2)
					last=i;
				if(j==3){
					uri="t3://"+locator.substring(last+1,i);
					last=i;
				}
				if(j==4){
					contextCacheKey=locator.substring(last+1,i);
					dsLocator="ld:"+locator.substring(i+1).replace(".ws?WSDL", "");
					break;
				}
			}
		}
		if(uri==null || contextCacheKey== null || dsLocator==null)
			throw new Exception("locator not valid : "+locator);
		return;
	}


}
