/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package userguide.clients;

import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.axis2.deployment.FileSystemConfigurator;
import org.apache.axis2.engine.AxisConfiguration;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.*;
import org.apache.axis2.rpc.client.*;

import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.File;
import java.io.FileNotFoundException;

/**
 * This is a Client progam that accesses 'MyService' web service in Axis2 samples
 */
public class SOAPClient {
    
    private static final Log log = LogFactory.getLog(SOAPClient.class);

    //    private static String toEpr = "http://localhost:8080/axis2/rest/MyService4";
    private static String toEpr = "http://localhost:8080/axis2/services/MyService4";
    
    private static int i = 0;
    private static Integer intObj = new Integer(i);
        
    public static void main(String[] args) throws AxisFault {
        
        try {
                        
            Options options = new Options();
            options.setManageSession(true);
            options.setTo(new EndpointReference(toEpr));
            options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
            
            //options.setProperty(Constants.Configuration.ENABLE_REST, Constants.VALUE_TRUE);
            
            String home = System.getProperty("user.home");
            // create this folder at your home. This folder could be anything
            //then create the "modules" folder
            //copy the LoggingModule.mar to "modules" folder.
            //copy the axis2.xml to the client-repository
            //then modify the axis2.xml that is generating there according to
            //phases that being included in the "module.xml"
            
            
            File repository = new File(home + File.separator + "client-repository");
            if (!repository.exists()) {
                throw new FileNotFoundException(repository.getAbsolutePath() + " does not Exist");
            };
            
            String str_axis2xml = repository.getAbsolutePath() + File.separator + "axis2.xml";
            File axis2_xml = new File(str_axis2xml);
            if (!axis2_xml.exists()) {
                throw new FileNotFoundException(axis2_xml.getAbsolutePath() + " does not Exist");
            };
            
            FileSystemConfigurator fsc = new FileSystemConfigurator(
            repository.getAbsolutePath(),
            axis2_xml.getAbsolutePath());
            
            AxisConfiguration er = fsc.getAxisConfig();
            
            ConfigurationContext configContext =
            ConfigurationContextFactory.createConfigurationContextFromFileSystem(
            repository.getAbsolutePath(),
            axis2_xml.getAbsolutePath()
            );
            
            
            //ServiceClient sender = new ServiceClient();
            ServiceClient sender = new ServiceClient(configContext,null);
            
            //sender.engageModule(new QName(Constants.MODULE_LOGGING));
            sender.engageModule(new QName("logging"));
            
            //sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
            sender.engageModule(new QName("addressing-1.1"));
            
            //sender.engageModule(new QName(Constants.MODULE_SOAPMONITOR));
            sender.engageModule(new QName("soapmonitor-1.1"));
            
            
            // invoke the start method first using it's StartPaylod
            options.setAction("urn:start");
            sender.setOptions(options);
            
            
            
            OMElement start = sender.sendReceive(getStartPayload());
            // from now on use this sender so that WS-address stuff i.e. ServiceGroupeContextID info is sent
            // where in the dark of the code is that?

            
            String s = intObj.toString(i);
            System.out.print("No"+s);
            
            XMLStreamWriter startWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(System.out);
            start.serialize(startWriter);
            startWriter.flush();                // write every-thing out
            System.out.println("");             // and add a CRLF
            
            
            
            options.setAction("urn:echo");
            sender.setOptions(options);
            
            for(int i=0;i<500;i++){
                
                OMElement result = sender.sendReceive(getPayload());
                
                s = intObj.toString(i);
                System.out.print("No"+s);
                
                XMLStreamWriter writer = XMLOutputFactory.newInstance().createXMLStreamWriter(System.out);
                result.serialize(writer);
                writer.flush();               // write every-thing out
                System.out.println("");       // and add a CRLF
                
                if (i==100){
                    System.gc();    // do an explicit Garbage Collection and get it all back
                }
                if (0 == i % 100){                    
                    System.gc();    // do an explicit Garbage Collection once evry 100 loops-through
                }
            } // end-for - so do a cleanup now to give up sender resource
            sender.cleanup();   // return resources .finalize would do more but is protected
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (XMLStreamException e) {
            e.printStackTrace();
        } catch (FactoryConfigurationError e) {
            e.printStackTrace();
        } catch (java.lang.Exception e) {
            e.printStackTrace();
        }
    }
    
    private static OMElement getStartPayload() {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        OMNamespace omNs = fac.createOMNamespace("http://example14.org/example4", "example4");
        OMElement method = fac.createOMElement("start", omNs);
        OMElement value = fac.createOMElement("Text", omNs);
        value.addChild(fac.createOMText(value, "Axis2 'SOAPSession' start"));
        method.addChild(value);
        
        return method;
    }
    
    private static OMElement getPayload() {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        OMNamespace omNs = fac.createOMNamespace("http://example4.org/example4", "example4");
        OMElement method = fac.createOMElement("echo", omNs);
        OMElement value = fac.createOMElement("Text", omNs);
        value.addChild(fac.createOMText(value, "Axis2 'SOAPClient' Echo-String "));
        method.addChild(value);
        
        return method;
    }
}
