package dspControl;

import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpSession;
import org.apache.beehive.netui.pageflow.PageFlowController;
import org.apache.beehive.netui.pageflow.annotations.Jpf;
import org.apache.beehive.controls.api.bean.Control;
import controls.DSPControlFile;
import org.apache.beehive.netui.pageflow.Forward;

import weblogic.jndi.Environment;

@Jpf.Controller()
public class DspControlController extends PageFlowController {
	private static final long serialVersionUID = 1L;
	
	public static retailer.impl.PROFILE_SERVICEImpl[]profileServiceBeans=null; 
	public static String[]profileServiceStrings=null;
	public static String outputString=null;
	
	String clientType="java";
	String uri="t3://localhost:7001";
	String username= "weblogic";
	String password="weblogic";
	enum ClassloaderType { noclassloader, currentthread, other};
	ClassloaderType classloaderType=ClassloaderType.noclassloader;
	transient 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";
	commonj.sdo.helper.XMLHelper xh = null;
	commonj.sdo.helper.DataFactory factory = null;
	
	@Control
	private DSPControlFile DSPControlFile;

	@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "index.jsp") })
	public Forward begin() {
		
		out("--------------------------------------------------------------");
		if(! "java".equals(clientType) && ! "webservice".equals(clientType)){
			out("clientType must be java or webservice");
			return new Forward("default");
		}
		if(ClassloaderType.noclassloader != classloaderType){
			out("ClassloaderType must be noclassloader");
			return new Forward("default");
		}
		
		try {
	
			commonj.sdo.helper.HelperContext hc = com.bea.dsp.das.HelperContextCache.get("RetailDataspace");
			xh = hc.getXMLHelper();
			factory = hc.getDataFactory();
		}catch(Exception e){
			e.printStackTrace();
		}
		Forward forward = new Forward("success");
		return forward;
	}

	@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "index.jsp") })
	public Forward client(retailer.impl.PROFILE_SERVICEImpl form) {
		retailer.PROFILE_SERVICE[] profiles=DSPControlFile.getCustomerByCustID("CUSTOMER1");
		outputString=dataObjectsToString(profiles);
		Forward forward = new Forward("success");
		return forward;
	}

	@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "index.jsp") })
	public Forward clientComplexArg() {
		
		// dataobject argument - type found in signature 
		
		retailer.PROFILE_SERVICE profileService =(retailer.PROFILE_SERVICE)factory.create(retailer.PROFILE_SERVICE.class );
		
		// now we set the name to be the element name we found in the function signature ...
		
		com.bea.dsp.sdo.SDOUtil.setElementName(profileService,
				"urn:retailer", "PROFILE");
		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");
		
		retailer.CASE_SERVICE[] cases=DSPControlFile.getServiceCase(profileService);
		outputString=dataObjectsToString(cases);
		Forward forward = new Forward("success");
		return forward;
	}

	@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "index.jsp") })
	public Forward clientComplexArgList() {
		
		// dataobject argument - type found in signature 

		retailer.PROFILE_SERVICES profileService =(retailer.PROFILE_SERVICES)factory.create("urn:retailer",
		"PROFILE_SERVICES");
		
		// now we set the name to be the element name we found in the function signature ...

		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");
	
		retailer.CASE_SERVICE[] cases = DSPControlFile.getServiceCases(profileService);
		outputString=dataObjectsToString(cases);
		Forward forward = new Forward("success");
		return forward;
	}

	@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "index.jsp") })
	public Forward clientComplexArgs_andCRUD() {
			
		// array to hold data objects
		
		retailer.PROFILE_SERVICE[] profileServices = new retailer.PROFILE_SERVICE[2];
		
		// dataobject argument - type found in signature 
		
		retailer.PROFILE_SERVICE profileService1 =(retailer.PROFILE_SERVICE)factory.create("urn:retailer",
		"PROFILE_SERVICE");
		
		// now we set the name to be the element name we found in the function signature ...
		
		com.bea.dsp.sdo.SDOUtil.setElementName(profileService1,
				"urn:retailer", "PROFILE");
		
		profileServices[0]=profileService1;

		retailertype.PROFILE_TYPE profile1 = profileService1.createPROFILE();
		profile1.setCustomerID("CUSTOMER44"); 
		profile1.setFirstName("dummyFirstName"); 
		profile1.setLastName("dummyLastName44");
		profile1.setCustomerSince( "2001-01-01");
		profile1.setEmailAddress( "dummyEmailAddress");
		profile1.setTelephoneNumber("8885551212");
		
		retailer.PROFILE_SERVICE profileService2 =(retailer.PROFILE_SERVICE)factory.create("urn:retailer",
		"PROFILE_SERVICE");
		com.bea.dsp.sdo.SDOUtil.setElementName(profileService2,
				"urn:retailer", "PROFILE");
		
		profileServices[1]=profileService2;
		retailertype.PROFILE_TYPE profile2 = profileService2.createPROFILE();
		profile2.setCustomerID("CUSTOMER55"); 
		profile2.setFirstName("dummyFirstName"); 
		profile2.setLastName("dummyLastName55");
		profile2.setCustomerSince( "2001-01-01");
		profile2.setEmailAddress( "dummyEmailAddress");
		profile2.setTelephoneNumber("8885551212");
		
		retailer.PROFILE_SERVICE[] returnedProfileServices=DSPControlFile.getCustomerByCustID("CUSTOMER44");

		outputString="";
		if(returnedProfileServices.length==0) {
			outputString=outputString +"ADDING: \n";
			DSPControlFile.createPROFILE(profileServices);
			outputString=outputString + dataObjectsToString(profileServices);

		} else {
			retailer.PROFILE_SERVICE dObj= returnedProfileServices[0];
			if("dummyLastName44".equals(dObj.get("PROFILE/LastName"))){
				outputString=outputString +"UPDATING: \n";
				outputString=outputString + dataObjectsToString(profileServices);
				com.bea.dsp.sdo.SDOUtil.enableChanges(dObj);
				dObj.set("PROFILE/LastName", "Smith");
				DSPControlFile.updatePROFILE(new retailer.PROFILE_SERVICE[]{dObj});
				

			} else {
				outputString=outputString +"DELETING: \n";
				outputString=outputString + dataObjectsToString(returnedProfileServices);

				DSPControlFile.deletePROFILE(new retailer.PROFILE_SERVICE[]{dObj});
				returnedProfileServices=DSPControlFile.getCustomerByCustID("CUSTOMER55");

				if(returnedProfileServices.length>0){
					dObj= returnedProfileServices[0];
					outputString=outputString + dataObjectsToString(returnedProfileServices);
					DSPControlFile.deletePROFILE(new retailer.PROFILE_SERVICE[]{dObj});
				}
			}
		}

		Forward forward = new Forward("success");
		return forward;
	}

	@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "index.jsp") })
	public Forward clientSimpleReturn() {	
		outputString="";
		java.math.BigInteger count = DSPControlFile.getOrderCount( "CUSTOMER4");
		outputString=outputString + dataObjectsToString(new Object[]{count});
		java.math.BigInteger[] counts = DSPControlFile.getOrderCounts( "CUSTOMER4");
		outputString=outputString + dataObjectsToString(counts);	
		Forward forward = new Forward("success");
		return forward;
	}

	@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "index.jsp") })
	public Forward clientWithAudit() {
		
		String[] attributes = new String[] { "common", "query" };
		
		com.bea.dsp.RequestConfig reqConfig = new com.bea.dsp.RequestConfig();
		reqConfig.enableFeature(com.bea.dsp.RequestConfig.RETURN_DATA_SERVICE_AUDIT);
		reqConfig.setStringArrayAttribute(
				com.bea.dsp.RequestConfig.RETURN_AUDIT_PROPERTIES, attributes);

		retailer.PROFILE_SERVICE profileService[] = DSPControlFile.getCustomerByLoginID("Steve",
				reqConfig);
		outputString=dataObjectsToString(profileService);
		/** Dump out the audit information **/
		com.bea.ld.DataServiceAudit dsAudit = reqConfig.retrieveDataServiceAudit();
		if (dsAudit != null) {
			List l = dsAudit.getAllRecords();
			for (Iterator it = l.iterator(); it.hasNext();) {
				com.bea.ld.DSPAuditRecord auditRec = (com.bea.ld.DSPAuditRecord) it.next();
				Map propMap = auditRec.getAuditProperties();
				for (Iterator pit = propMap.keySet().iterator(); pit
						.hasNext();) {
					String key = (String) pit.next();
					outputString=outputString + "Audit Information: " + key + " = "
							+ propMap.get(key)+"\n";
				}
			}
		}

		
		Forward forward = new Forward("success");
		return forward;
	}

	@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "index.jsp") })
	public Forward useSetClassloader() {
		classloaderType=ClassloaderType.currentthread;
		Forward forward = begin();
		return forward;
	}

	@Jpf.Action(forwards = { @Jpf.Forward(name = "success", path = "index.jsp") })
	public Forward dontUseSetClassloader() {
		classloaderType=ClassloaderType.noclassloader;
		Forward forward = begin();
		return forward;
	}
	
	/**
	 * Callback that is invoked when this controller instance is created.
	 */
	@Override
	protected void onCreate() {
	}

	/**
	 * Callback that is invoked when this controller instance is destroyed.
	 */
	@Override
	protected void onDestroy(HttpSession session) {
	}
	
	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());
	}

	String dataObjectToString(commonj.sdo.helper.XMLHelper xh, Object obj) {
		String theString=null;
		try {
			if(obj instanceof commonj.sdo.DataObject){
				commonj.sdo.DataObject dObj=(commonj.sdo.DataObject)obj;
				com.bea.sdo.PropertyXML element = ((com.bea.sdo.DataObjectXML) dObj)
						.getContainmentPropertyXML();
				String elementName = element.getName();
				String elementURI = element.getType().getURI();
				commonj.sdo.helper.XMLDocument xmlDocument = xh.createDocument(dObj, elementURI,
						elementName);
				StringWriter outputWriter = new StringWriter();
				xh.save(xmlDocument, outputWriter, null);
				theString=outputWriter.toString();
			} else if (obj instanceof Object[]){
				StringBuffer sb=new StringBuffer();
				Object[] objArray=(Object[]) obj;
				for(int i=0; i<objArray.length; i++)
					sb.append("    "+dataObjectToString(xh,objArray[i]));
				theString=sb.toString();
				return theString;
			} else {
				theString=obj.toString();
			}
			StackTraceElement[] stes=Thread.currentThread().getStackTrace();
			
			return stes[4].getMethodName()+"/"+runningIn+"/"+clientType+"/"+classloaderType+" "+theString.replace("&","&amp;").replace("<", "&lt;").replace(">", "&gt;");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	String dataObjectsToString(Object[] dObjs){
		StringBuffer sb=new StringBuffer();
		for(int i=0; i<dObjs.length; i++){
			sb.append(dataObjectToString(xh,dObjs[i])+"\n");
		}
		return sb.toString();
	}
	
	String dataObject2String(commonj.sdo.helper.XMLHelper xh, Object obj) {
		StringBuffer theString=new StringBuffer();
		try {

			if(obj instanceof commonj.sdo.DataObject){
				commonj.sdo.DataObject dObj=(commonj.sdo.DataObject)obj;
				com.bea.sdo.PropertyXML element = ((com.bea.sdo.DataObjectXML) dObj)
						.getContainmentPropertyXML();
				String elementName = element.getName();
				String elementURI = element.getType().getURI();
				commonj.sdo.helper.XMLDocument xmlDocument = xh.createDocument(dObj, elementURI,
						elementName);
				StringWriter outputWriter = new StringWriter();
				xh.save(xmlDocument, outputWriter, null);
				theString.append(outputWriter.toString());
			} else if (obj instanceof Object[]){
				Object[] objArray=(Object[])obj;
				for(int i=0;i<objArray.length; i++)
					theString.append(dataObject2String(xh,objArray[i]));
			} else {
				theString.append(obj.toString());
			}
			
			return theString.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}