/*******************************************************************************
 * Copyright (c) 2006, 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20060317   127456 cbrealey@ca.ibm.com - Chris Brealey
 * 20060517   140832 andyzhai@ca.ibm.com - Andy Zhai
 * 20060620   147862 cbrealey@ca.ibm.com - Chris Brealey
 * 20060620   147864 cbrealey@ca.ibm.com - Chris Brealey
 * 20061214   165716 makandre@ca.ibm.com - Andrew Mak, Web Service finder does not locate Axis Web service deployed on certain servers
 *******************************************************************************/

package org.eclipse.jst.ws.internal.axis.consumption.core.locator;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jst.ws.internal.common.J2EEUtils;
import org.eclipse.jst.ws.internal.wsrt.WebServiceJavaClientInfo;
import org.eclipse.wst.server.core.IServer;
import org.eclipse.wst.server.core.ServerPort;
import org.eclipse.wst.server.core.ServerUtil;
import org.eclipse.wst.ws.internal.wsfinder.AbstractWebServiceLocator;
import org.eclipse.wst.ws.internal.wsrt.WebServiceClientInfo;
import org.eclipse.wst.ws.internal.wsrt.WebServiceInfo;
import org.xml.sax.SAXException;

/**
 * @author cbrealey
 * The Axis Web service locator plugs itself into the
 * Web Services Finder framework and does the job of
 * locating Axis clients and services.
 */
public class AxisWebServiceLocator extends AbstractWebServiceLocator
{
	private String AXIS_STUB = "org.apache.axis.client.Stub";
	
	/**
	 * Searches the workspace for Axis clients as
	 * identified by non-stub classes that implement
	 * SEIs that are implemented by stubs that implement
	 * org.apache.axis.client.Stub.
	 * @param monitor A progress monitor, possibly null.
	 * @return A possibly empty list of WebServiceClientInfo objects.
	 */
	public List getWebServiceClients (IProgressMonitor monitor)
	{
		List list = new LinkedList();
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IJavaModel javaModel = JavaCore.create(root);
		try
		{
			javaModel.open(monitor);
			IJavaProject[] javaProjects = javaModel.getJavaProjects();
			for (int i=0; i<javaProjects.length; i++)
			{
				// We're only interested in Java projects within which
				// the Axis runtime's client "Stub" class is loadable:
				IType axisStub = javaProjects[i].findType(AXIS_STUB);
				if (axisStub != null)
				{
					// Find "Proxy" classes in the project and add to the list.
					addAxisProxies(javaProjects[i],axisStub,list,monitor);
				}
			}
			javaModel.close();
		}
		catch (Exception e)
		{
			// Fall thru and return an empty list.
		}
		return list;
	}
	
	/**
	 * Searches the workspace for Axis clients as
	 * identified by non-stub classes that implement
	 * SEIs that are implemented by stubs that implement
	 * org.apache.axis.client.Stub.
	 * @param projects The projects to confine the search to.
	 * @param monitor A progress monitor, possibly null.
	 * @return A possibly empty list of WebServiceClientInfo objects.
	 */
	public List getWebServiceClients (IProject[] projects, IProgressMonitor monitor)
	{
		if (projects == null)
		{
			return getWebServiceClients(monitor);
		}
		List list = new LinkedList();
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IJavaModel javaModel = JavaCore.create(root);
		try
		{
			javaModel.open(monitor);
			for (int i=0; i<projects.length; i++)
			{
				IJavaProject javaProject = javaModel.getJavaProject(projects[i].getName());
				// We're only interested in Java projects within which
				// the Axis runtime's client "Stub" class is loadable:
				IType axisStub = javaProject.findType(AXIS_STUB);
				if (axisStub != null)
				{
					// Find "Proxy" classes in the project and add to the list.
					addAxisProxies(javaProject,axisStub,list,monitor);
				}
			}
			javaModel.close();
		}
		catch (Exception e)
		{
			// Fall thru and return an empty list.
		}
		return list;
	}
	
	/**
	 * Tries to find Axis "Proxy" classes related the given Stub.
	 * @param axisStub The Axis client "Stub" from which to search.
	 * @param list A list to which we'll add and WebServiceClientInfo
	 * objects for "Proxy" classes we find in the search. 
	 */
	private void addAxisProxies (IJavaProject javaProject, IType axisStub, List list, IProgressMonitor monitor)
	{
		try
		{
			// Compute a hierarchy to help us find all the
			// generated Stub subclasses of the Axis "Stub"
			// class across the entire workspace:
			ITypeHierarchy axisStubHierarchy = axisStub.newTypeHierarchy(javaProject,monitor);
			IType[] stubs = axisStubHierarchy.getSubtypes(axisStub);
			for (int s=0; s<stubs.length; s++)
			{
				// For each stub, find all its super-interfaces of which
				// there should be one, namely the generated SEI:
				IType seis[] = axisStubHierarchy.getSuperInterfaces(stubs[s]);
				for (int i=0; i<seis.length; i++)
				{
					try
					{
						// Compute a hierarchy to help us find all the
						// generated classes that implement the SEI
						// confined to the current project:
						ITypeHierarchy seiHierarchy = seis[i].newTypeHierarchy(javaProject,monitor);
						IType[] proxies = seiHierarchy.getSubtypes(seis[i]);
						for (int p=0; p<proxies.length; p++)
						{
							// Under normal circumstances we should find two subclasses:
							// 1. The generated stub that got us here (two loops above).
							// 2. The generated "Proxy" that we're looking for.
							// Skip #1 and capture #2:
							if (!proxies[p].getFullyQualifiedName().equals(stubs[s].getFullyQualifiedName()))
							{
								WebServiceClientInfo wscInfo = newWebServiceClientInfo(proxies[p]);
								if (wscInfo != null)
								{
									list.add(wscInfo);
								}
							}
						}
					}
					catch (Exception e)
					{
						// We'll land here if the JDT was unable to compute
						// a type hierarchy for the current SEI.
						// This should never happen, but if it does,
						// there's not much we can do except bypass the SEI
						// and loop on to the next one.
					}
				}
			}
		}
		catch (Exception e)
		{
			// We'll land here if JDT was unable to compute
			// a type hierarchy for the Axis client "Stub" class.
			// This should never happen, but if it does,
			// there's not much we can do except bail out, having
			// added nothing to the list.
		}
	}
	
	/**
	 * Creates a new WebServiceClientInfo object for a
	 * JDT IType object representing a generated Proxy.
	 * @param axisProxy The IType of the generated Proxy.
	 * @return A new WebServiceClientInfo object describing the Proxy,
	 * or null if the IType does not appear to describe a normal Proxy. 
	 */
	private WebServiceClientInfo newWebServiceClientInfo (IType axisProxy)
	{
		WebServiceJavaClientInfo wscInfo = null;
		try
		{
			IResource resource = axisProxy.getUnderlyingResource();
			if (resource != null)
			{
				IPath proxyPath = resource.getLocation();
				if (proxyPath != null)
				{
					String proxyURL = proxyPath.toFile().toURL().toString();
					wscInfo = new WebServiceJavaClientInfo();
					wscInfo.setType(axisProxy);
					wscInfo.setImplURL(proxyURL);
				}
			}
		}
		catch (Exception e)
		{
			// We'll land here if we could not convert the IType
			// into an IResource, or if we could not compute a URL
			// from that resource. Either way, it definitely isn't
			// a normal generated Proxy, so get out and return null.
		}
		return wscInfo;		
	}

	/**
	 * Searches the workspace for Axis services as
	 * identified by server-config.wsdd <service> elements
	 * in projects with an Axis servlet registered
	 * in the web.xml descriptor.
	 * @param monitor A progress monitor, possibly null.
	 * @return A possibly empty list of WebServiceInfo objects.
	 */
	public List getWebServices (IProgressMonitor monitor)
	{
		return getWebServices(null,monitor);
	}
	
	/**
	 * Searches the workspace for Axis services as
	 * identified by server-config.wsdd <service> elements
	 * in projects with an Axis servlet registered
	 * in the web.xml descriptor.
	 * @param projects The projects to confine the search to.
	 * @param monitor A progress monitor, possibly null.
	 * @return A possibly empty list of WebServiceInfo objects.
	 */
	public List getWebServices (IProject[] projects, IProgressMonitor monitor)
	{
		Vector webServices = new Vector();
		if (projects == null)
		{
			projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
		}
		for (int i = 0; i < projects.length; i++)
		{
			// we are only intersted in dynamic web project
			if (J2EEUtils.isWebComponent(projects[i]))
			{
				try 
				{
					webServices.addAll(getWebServicesFromProject(projects[i], monitor));
				} 
				catch (Exception e) 
				{
					// Fall thru and return an empty list.
				} 
			}
		}
		return webServices;
	}
	
	/**
	 * Searches for a particular web project for Axis services as
	 * identified by server-config.wsdd <service> elements
	 * with an Axis servlet registered
	 * in the web.xml descriptor.
	 * @param monitor A progress monitor, possibly null.
	 * @return A possibly empty list of WebServiceInfo objects.
	 */
	private List getWebServicesFromProject(IProject project, IProgressMonitor monitor) throws CoreException, ParserConfigurationException, SAXException, IOException
	{	
		// Search the web.xml in fixed location
		IPath webDescriptorPath = J2EEUtils.getWebInfPath(project).append("/web.xml");
		IFile webXmlFile = ResourcesPlugin.getWorkspace().getRoot().getFile(webDescriptorPath);
		
		if (webXmlFile != null && isAxisServletExisted(webXmlFile, monitor))
		{
			// Search for all server-config.wsdd inside this project
			ServerConfigWSDDVisitor visitor = new ServerConfigWSDDVisitor();
			project.accept(visitor);		
			visitor.visit(project);
			Vector wsddFiles = visitor.getWsddFiles();
			Vector servicesNames = new Vector(); 
			for (int i = 0; i < wsddFiles.size(); i++)
			{
				servicesNames.addAll(getWebServicesNamesFromAxisConfig((IFile)wsddFiles.get(i), monitor));
			}
			return getWebServices(project, servicesNames, monitor);
		}
		else
		{
			return new Vector();
		}
	}
	
	/*
	 * Determine whether web.xml contains axis servlet
	 */
	private boolean isAxisServletExisted(IFile file, IProgressMonitor monitor) throws CoreException, ParserConfigurationException, SAXException, IOException
	{
		InputStream inputStream = file.getContents();
		SAXParserFactory factory = SAXParserFactory.newInstance();
		factory.setNamespaceAware(true);
		SAXParser parser = factory.newSAXParser();
		AxisServletSaxHandler handler = new AxisServletSaxHandler();
		parser.parse(inputStream, handler);
		inputStream.close();
		return handler.isThereAxisServlet();
	}
	
	/*
	 * Given a list of services, find the servers this project is associated,
	 * Combine them and form various end point
	 */
	private List getWebServices(IProject project, List servicesNames, IProgressMonitor monitor)
	{
		Vector webServices = new Vector();
		IServer[] servers = ServerUtil.getServersByModule(ServerUtil.getModule(project),monitor);
		for (int i = 0; i < servers.length; i++)
		{
			String host = servers[i].getHost();
			ServerPort httpPort = getHttpPort(servers[i].getServerPorts(monitor));
			if (httpPort != null)
			{
				for (int j = 0; j < servicesNames.size(); j++)
				{
					WebServiceInfo wsInfo = new WebServiceInfo();
					String endPointURL = "http://" + host + ":" + httpPort.getPort() + "/" + J2EEUtils.getFirstWebModuleName(project) + "/services/" + (String)servicesNames.get(j);
					wsInfo.setEndPointURL(endPointURL);
					wsInfo.setWsdlURL(endPointURL+"?wsdl");
		            webServices.add(wsInfo);
				}
			}
		}
		return webServices;
	}
	
	/*
	 * Parse the server-config.wsdd file, return a list of names of web services 
	 */
	private List getWebServicesNamesFromAxisConfig(IFile file, IProgressMonitor monitor) throws CoreException, ParserConfigurationException, SAXException, IOException
	{
		InputStream inputStream = file.getContents();
		SAXParserFactory factory = SAXParserFactory.newInstance();
		factory.setNamespaceAware(true);
		SAXParser parser = factory.newSAXParser();
		AxisServicesSaxHandler handler = new AxisServicesSaxHandler();
		parser.parse(inputStream, handler);
		inputStream.close();
		return handler.getWebServicesNames();	
	}
	
	/*
	 * find the right port (http) from a list or ports
	 */
	private ServerPort getHttpPort(ServerPort[] ports)
	{
		for (int i = 0; i < ports.length; i++)
		{
			String protocol = ports[i].getProtocol(); 
			if ( protocol != null && protocol.trim().toLowerCase().equals("http")) return ports[i];
		}
		return null;
	}
}
