import java.net.MalformedURLException;
import java.rmi.RemoteException;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ServiceException;

import org.apache.axis.EngineConfiguration;
import org.apache.axis.EngineConfigurationFactory;
import org.apache.axis.client.AxisClient;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.configuration.EngineConfigurationFactoryDefault;
import org.apache.axis.configuration.EngineConfigurationFactoryFinder;
import org.apache.axis.encoding.XMLType;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.Priority;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.ErrorCode;
import org.apache.log4j.spi.ErrorHandler;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;


public class MyAppender extends AppenderSkeleton {
	String endpoint;
	Service service;
	Call call;
	String ret;
	Map env;
	private static final String  ENDPOINT_URL = "http://localhost:8080/axis/services/MyService";
	private static final String  OPERATION_NAME = "serviceMethod";
	private static final String  NAMESPACE_URI = "http://example3.userguide.samples";


	public MyAppender() {
//		this.service = new Service();
	}


	public boolean requiresLayout() {
		System.out.println("MyAppender.requiresLayout()");
		return true;
	}

	public String getEndpoint() {
		return endpoint;
	}

	public void setEndpoint(String endpoint) {
		this.endpoint = endpoint;
	}

	@Override
	public void activateOptions() {
		System.out.println("MyAppender.activateOptions()");
		if (endpoint != null) {
			System.out.println("MyAppender.activateOptions() endpoint != null");
			try {
				setEndpoint("http://localhost:8080/axis/services/MyService");

			} catch (Exception e) {
				System.err.println("Exception "+e);
				errorHandler.error("my error", e, ErrorCode.GENERIC_FAILURE);
			}
		} else {
			System.out.println("MyAppender.activateOptions() endpoint is null");
			LogLog.warn("end point not set for appender [" + name + "].");
		}
	}

	protected void append(LoggingEvent event) {
		/*endpoint = getEndpoint();
		if (endpoint == null) {
			System.out.println("No endpoint set");
			return;
		}*/
		System.out.println("========append() begin========");
		executeWebService(event);
		System.out.println("========append() end=======");
		this.finalize();
	}


	@Override
	public void addFilter(Filter arg0) {
		// TODO Auto-generated method stub
		super.addFilter(arg0);
		System.out.println("MyAppender.addFilter()");
	}

	@Override
	public void clearFilters() {
		// TODO Auto-generated method stub
		super.clearFilters();
		System.out.println("MyAppender.clearFilters()");
	}

	@Override
	public synchronized void doAppend(LoggingEvent arg0) {
		// TODO Auto-generated method stub
		super.doAppend(arg0);
		System.out.println("MyAppender.doAppend()");
	}

	@Override
	public void finalize() {
		System.out.println("MyAppender.finalize()");
		if(this.closed) 
			return;
//		this.closed = true; 
		System.out.println("Finalizing appender named ["+name+"].");
		this.close();
	}

	@Override
	public ErrorHandler getErrorHandler() {
		// TODO Auto-generated method stub
		System.out.println("MyAppender.getErrorHandler()");
		return super.getErrorHandler();
	}

	@Override
	public Filter getFilter() {
		// TODO Auto-generated method stub
		System.out.println("MyAppender.getFilter()");
		return super.getFilter();
	}

	@Override
	public Layout getLayout() {
		// TODO Auto-generated method stub
		System.out.println("MyAppender.getLayout()");
		return super.getLayout();
	}

	@Override
	public Priority getThreshold() {
		// TODO Auto-generated method stub
		System.out.println("MyAppender.getThreshold()");
		return super.getThreshold();
	}

	@Override
	public boolean isAsSevereAsThreshold(Priority arg0) {
		// TODO Auto-generated method stub
		System.out.println("MyAppender.isAsSevereAsThreshold() returned "+ super.isAsSevereAsThreshold(arg0));
		return super.isAsSevereAsThreshold(arg0);
	}

	@Override
	public synchronized void setErrorHandler(ErrorHandler arg0) {
		// TODO Auto-generated method stub
		super.setErrorHandler(arg0);
		System.out.println("MyAppender.setErrorHandler()");
	}

	@Override
	public void setLayout(Layout arg0) {
		// TODO Auto-generated method stub
		super.setLayout(arg0);
		System.out.println("MyAppender.setLayout()");
	}

	@Override
	public void setName(String arg0) {
		// TODO Auto-generated method stub
		arg0 = "myAppender";
		super.setName(arg0);
		System.out.println("MyAppender.setName()");
	}

	@Override
	public void setThreshold(Priority arg0) {
		// TODO Auto-generated method stub
		super.setThreshold(arg0);
		System.out.println("MyAppender.setThreshold()");
	}

	public void close() {
		System.out.println("MyAppender.close()");
		this.closed = true;
	}

	private void executeWebService(LoggingEvent event) {
		System.out.println("MyAppender.executeWebService()");
		System.out.println("MyAppender.executeWebService() message ="+ event.getMessage());
		String[] args = new String[]{};

//		String endpointURL = "http://localhost:8080/axis/services/MyService";

//		String endpointURL = getEndpoint();
		String textToSend = "hello";
//		QName qName = new QName("http://example3.userguide.samples","serviceMethod");

		try {
			/*EngineConfigurationFactory factory = EngineConfigurationFactoryFinder.newFactory();
			EngineConfiguration config = factory.getClientEngineConfig();
			AxisClient axisClient = new AxisClient(config);*/
			
			System.out.println("Before Service");
//			ServiceFactory sf = (ServiceFactory) ServiceFactory.newInstance(); 
			service = new Service();  
			System.out.println("After Service");
			
			call = (Call) service.createCall();
			
			call.setTargetEndpointAddress(new java.net.URL(ENDPOINT_URL));
			call.setOperationName(new QName(NAMESPACE_URI,OPERATION_NAME));
			call.addParameter("arg1", XMLType.XSD_STRING, ParameterMode.IN);
			call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);
			
			ret = (String) call.invoke(new Object[] { textToSend });
			
			System.out.println("You typed : " + ret);
		} catch (ServiceException e) {
			System.err.println(e.toString());
		} catch (MalformedURLException e) {
			System.err.println(e.toString());
		} catch (RemoteException e) {
			System.err.println(e.toString());
		} catch (Exception e) {
			System.err.println(e.toString());
		}
	}





}
