
package org.apache.axis2.jaxws.sample.nonwrap.sei;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;


/**
 * This class was generated by the JAXWS SI.
 * JAX-WS RI 2.0_01-b15-fcs
 * Generated source version: 2.0
 * 
 */
@WebServiceClient(name = "DocLitNonWrapService", targetNamespace = "http://nonwrap.sample.test.org", wsdlLocation = "doclit_nonwrap.wsdl")
public class DocLitNonWrapService
    extends Service
{

    private final static URL DOCLITNONWRAPSERVICE_WSDL_LOCATION;
    private static String wsdlLocation="/test/org/apache/axis2/jaxws/sample/nonwrap/META-INF/doclit_nonwrap.wsdl";
    static {
        URL url = null;
        try {
        	try{
	        	String baseDir = new File(".").getCanonicalPath();
	        	wsdlLocation = new File(baseDir + wsdlLocation).getAbsolutePath();
        	}catch(Exception e){
        		e.printStackTrace();
        	}
        	File file = new File(wsdlLocation);
        	url = file.toURL();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        DOCLITNONWRAPSERVICE_WSDL_LOCATION = url;
    }

    public DocLitNonWrapService(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    public DocLitNonWrapService() {
        super(DOCLITNONWRAPSERVICE_WSDL_LOCATION, new QName("http://nonwrap.sample.test.org", "DocLitNonWrapService"));
    }

    /**
     * 
     * @return
     *     returns DocLitNonWrapPortType
     */
    @WebEndpoint(name = "DocLitNonWrapPort")
    public DocLitNonWrapPortType getDocLitNonWrapPort() {
        return (DocLitNonWrapPortType)super.getPort(new QName("http://nonwrap.sample.test.org", "DocLitNonWrapPort"), DocLitNonWrapPortType.class);
    }


}
