/*******************************************************************************
 * Copyright (c) 2001, 2005 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
 *******************************************************************************/
package org.eclipse.jem.internal.beaninfo.core;
/*
 *  $RCSfile: BeaninfoEntry.java,v $
 *  $Revision: 1.6 $  $Date: 2005/08/24 20:31:28 $ 
 */

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
import org.w3c.dom.*;

import org.eclipse.jem.internal.beaninfo.adapters.*;

/**
 * Beaninfo entry. Location of the beaninfos. Much like a standard classpath entry.
 * The BeanInfos are either in a jar or another project. They can be supplied as
 * a local file in the project, or as an external jar, or as external jar through a
 * variable, or an external jar through a plugin.
 * <p>
 * An external jar through containers is not valid because container are attached to
 * projects. they aren't standalone.
 * 
 * @version 	1.0
 * @author
 */
public class BeaninfoEntry implements IBeaninfosDocEntry {

	final static String sBeaninfo = "beaninfo"; // Beaninfo entry, shared with BeaninfosDoc. //$NON-NLS-1$
	
	public static final int BIE_PLUGIN = 100;	// Beaninfo jar can be found in a plugin.

	static int kindFromString(String kindStr) {
		if (kindStr == null || kindStr.length() == 0)
			return BIE_PLUGIN;	// Default to plugin. If coming from beaninfoconfig, there should always be kind. But if coming from plugin.xml there shouldn't be one.
		if (kindStr.equalsIgnoreCase("con")) //$NON-NLS-1$
			return IClasspathEntry.CPE_CONTAINER;
		if (kindStr.equalsIgnoreCase("var")) //$NON-NLS-1$
			return IClasspathEntry.CPE_VARIABLE;
		if (kindStr.equalsIgnoreCase("src")) //$NON-NLS-1$
			return IClasspathEntry.CPE_SOURCE;
		if (kindStr.equalsIgnoreCase("lib")) //$NON-NLS-1$
			return IClasspathEntry.CPE_LIBRARY;
		if (kindStr.equalsIgnoreCase("plugin")) //$NON-NLS-1$
			return BIE_PLUGIN;
		return -1;
	}

	static String kindToString(int kind) {

		switch (kind) {
			case IClasspathEntry.CPE_PROJECT :
				return "src"; // backward compatibility //$NON-NLS-1$
			case IClasspathEntry.CPE_SOURCE :
				return "src"; //$NON-NLS-1$
			case IClasspathEntry.CPE_LIBRARY :
				return "lib"; //$NON-NLS-1$
			case IClasspathEntry.CPE_VARIABLE :
				return "var"; //$NON-NLS-1$
			case IClasspathEntry.CPE_CONTAINER:
				return "con"; //$NON-NLS-1$
			case BIE_PLUGIN:
				return "plugin";	//$NON-NLS-1$
			default :
				return "unknown"; //$NON-NLS-1$
		}
	}

	/**
	 * Return the appropriate kind of entry when we know it is a classpath entry.
	 */
	public static IClasspathEntry createEntry(int kind, IPath path, IProject project, boolean isExported) {
		switch (kind) {

			case IClasspathEntry.CPE_LIBRARY :
				if (path.isAbsolute())
					return JavaCore.newLibraryEntry(path, null, null, isExported);
				break;

			case IClasspathEntry.CPE_SOURCE :
				if (path.isAbsolute()) {
					// must be an entry in this project or specify another project
					String projSegment = path.segment(0);
					if (project != null && projSegment != null && projSegment.equals(project.getName())) {
						// this project
						return JavaCore.newSourceEntry(path);
					} else {
						// another project
						return JavaCore.newProjectEntry(path, isExported);
					}
				}
				break;

			case IClasspathEntry.CPE_VARIABLE :
				return JavaCore.newVariableEntry(path, null, null, isExported);
			
			case IClasspathEntry.CPE_CONTAINER:
				return JavaCore.newContainerEntry(path, isExported);

		}

		return null;
	}
	/**
	 * Read the entry in from the element.
	 */
	public static BeaninfoEntry readEntry(IReader reader, Object element, IProject project) {
		String elementKind = reader.getAttribute(element, BeaninfosDoc.sKind);
		String pathStr = reader.getAttribute(element, BeaninfosDoc.sPath);
		// ensure path is absolute
		IPath path = new Path(pathStr);
		int kind = kindFromString(elementKind);
		if (kind != IClasspathEntry.CPE_VARIABLE && kind != IClasspathEntry.CPE_CONTAINER && kind != BIE_PLUGIN && !path.isAbsolute()) {
			path = project != null ? project.getFullPath().append(path) : path.makeAbsolute(); // Some folder/jar within this project
		}

		// exported flag
		String exportedString = reader.getAttribute(element, BeaninfosDoc.sExported);
		boolean isExported = "true".equalsIgnoreCase(exportedString); //$NON-NLS-1$
		//$NON-NLS-1$

		// recreate the entry
		IClasspathEntry cpEntry = null;
		IPath pluginPath = null;
		if (kind != BIE_PLUGIN) {
			cpEntry = createEntry(kind, path, project, isExported);
		} else {
			if (path.isAbsolute())
				pluginPath = path;
			else {
				// Kludge This should only be a plugin type if from configuration element. So we will cast to that
				// and get the plugin id to create an absolute plugin path.
				if (element instanceof IConfigurationElement) {
					pluginPath = new Path('/'+((IConfigurationElement) element).getDeclaringExtension().getNamespace()).append(path);
				} else
					return null;	// Not valid because can't have plugin from .beaninfoconfig file.
			}
		}

		ArrayList searchpaths = new ArrayList();
		Object children = reader.getChildren(element);
		int childrenLength = reader.getLength(children);
		for (int i = 0; i < childrenLength; i++) {
			Object child = reader.getItem(children, i);
			if (reader.isNodeTypeElement(child)) {
				Object entry = null;
				if (reader.getNodeName(child).equalsIgnoreCase(SearchpathEntry.sSearchpath)) {
					entry = SearchpathEntry.readEntry(reader, child, project, true);
				}
				if (entry != null)
					searchpaths.add(entry);
			}
		}

		if (cpEntry != null)
			return new BeaninfoEntry(
				cpEntry,
				(SearchpathEntry[]) searchpaths.toArray(new SearchpathEntry[searchpaths.size()]),
				isExported);
		else return new BeaninfoEntry(
				pluginPath,
				(SearchpathEntry[]) searchpaths.toArray(new SearchpathEntry[searchpaths.size()]),
				isExported);
	}

	protected IClasspathEntry entry; // Store it as a classpath entry for convienence. It is the RAW classpath entry. This is only used when pointing to something other than a plugin.
	protected IPath pluginPath;	// When stored in a plugin, this will be set instead.
	protected boolean isExported;
	protected SearchpathEntry[] searchpaths;
	
	/**
	 * Used when the beaninfo jar is within a plugin. In that case, the first segment
	 * of the path is the plugin descriptor, and the rest is the path from the plugin
	 * directory to the jar.
	 */
	public BeaninfoEntry(IPath pluginPath, SearchpathEntry[] searchpaths, boolean isExported) {
		this(searchpaths, isExported);
		this.pluginPath = pluginPath;
	}

	/**
	 * Used when the beaninfo jar/folder is either an external jar/folder or is somewhere else
	 * in the workspace. In that case the entry is the RAW classpath entry to that code.
	 */
	public BeaninfoEntry(IClasspathEntry entry, SearchpathEntry[] searchpaths, boolean isExported) {
		this(searchpaths, isExported);
		this.entry = entry;
	}
	
	protected BeaninfoEntry(SearchpathEntry[] searchpaths, boolean isExported) {
		this.isExported = isExported;
		this.searchpaths = searchpaths != null ? searchpaths : new SearchpathEntry[0];
	}
	
	public SearchpathEntry[] getSearchPaths() {
		return searchpaths;
	}
	
	public void setSearchPaths(SearchpathEntry[] searchpaths) {
		this.searchpaths = searchpaths;
	}
	
	public boolean isExported() {
		return isExported;
	}
	
	public void setIsExported(boolean isExported) {
		this.isExported = isExported;
	}

	public Node writeEntry(Document doc, IProject project) {

		Element element = doc.createElement(sBeaninfo);
		IPath path = null;
		if (entry != null) {
			element.setAttribute(BeaninfosDoc.sKind, kindToString(entry.getEntryKind()));
			path = entry.getPath();
			if (entry.getEntryKind() != IClasspathEntry.CPE_VARIABLE && entry.getEntryKind() != IClasspathEntry.CPE_CONTAINER) {
				// translate to project relative from absolute (unless a device path)
				if (path.isAbsolute()) {
					if (path.segment(0).equals(project.getFullPath().segment(0))) {
						path = path.removeFirstSegments(1);
						path = path.makeRelative();
					} else {
						path = path.makeAbsolute();
					}
				}
			}
		} else {
			element.setAttribute(BeaninfosDoc.sKind, kindToString(BIE_PLUGIN));
			path = pluginPath;
		}

		element.setAttribute(BeaninfosDoc.sPath, path.toString()); //$NON-NLS-1$
		if (isExported()) {
			element.setAttribute(BeaninfosDoc.sExported, "true"); //$NON-NLS-1$
		}

		for (int i = 0; i < searchpaths.length; i++) {
			SearchpathEntry spe = searchpaths[i];
			element.appendChild(spe.writeEntry(doc, project));
		}

		return element;
	}
	
	/**
	 * If this is not a plugin info, then return the classpath entry.
	 */
	public IClasspathEntry getClasspathEntry() {
		return entry;
	}

	/**
	 * Return the resolved classpaths. Each entry in the array will be either:
	 * 1) IProject - If it is a project type entry. Want the whole project
	 * 2) String - an absolute external path to a jar
	 * 3) IPath - a path to a plugin jar. The first segment is the plugin id, the rest is the path relative to that plugin.
	 *            
	 * 
	 * @param javaProject
	 * @return The array of paths, or <code>null</code> if no paths.
	 * 
	 * @since 1.0.0
	 */
	public Object[] getClasspath(IJavaProject javaProject) {
		if (entry != null) {
			// It is a standard CPE Entry.
			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
			List paths = new ArrayList(1);
			IClasspathEntry resolvedEntry = JavaCore.getResolvedClasspathEntry(entry);
			resolveEntry(root, paths, resolvedEntry, javaProject);
			return paths.toArray();
		} else if (pluginPath != null) 
			return new Object[] {pluginPath};
		
		return null;

	}
	
	private void resolveEntry(IWorkspaceRoot root, List paths, IClasspathEntry entry, IJavaProject javaProject) {
		switch (entry.getEntryKind()) {
			case IClasspathEntry.CPE_PROJECT :
				IProject reqProject = (IProject) root.findMember(entry.getPath().lastSegment());
				// Project entries only have one segment.
				if (reqProject != null && reqProject.isOpen())
					paths.add(reqProject);
				break;

			case IClasspathEntry.CPE_SOURCE :
				reqProject = (IProject) root.findMember(entry.getPath().segment(0));
				// Find project from the first segment.
				IJavaProject jProject = JavaCore.create(reqProject);
				if (jProject != null) {
					try {
						IPath outputLocation = jProject.getOutputLocation();
						IResource resource = root.findMember(outputLocation);
						if (resource != null) {
							paths.add(resource.getLocation().toString());
						}
					} catch(JavaModelException e) {
					}
				}
				break;

			case IClasspathEntry.CPE_LIBRARY :
				IResource library = root.findMember(entry.getPath());
				// can be external or in workspace
				paths.add((library != null) ? library.getLocation().toString() : entry.getPath().toString());
				break;
				
			case IClasspathEntry.CPE_CONTAINER:
				try {
					IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
					if (container != null) {
						IClasspathEntry[] entries = container.getClasspathEntries();
						for (int i = 0; i < entries.length; i++) {
							resolveEntry(root, paths, entries[i], javaProject);
						}
					}
				} catch (JavaModelException e) {
					BeaninfoPlugin.getPlugin().getLogger().log(e, Level.WARNING);
				}			
		}
	}

	public int getKind() {
		return entry != null ? entry.getEntryKind() : BIE_PLUGIN;
	}
	
	public IPath getPath() {
		return entry != null ? entry.getPath() : pluginPath;
	}
	
	public boolean equals(Object other) {
		if (this == other)
			return true;
			
		if (!(other instanceof BeaninfoEntry))
			return false;

		// Return equal if the classpath entry is the same classpath entry or plugin path entry.
		// The search path doesn't have any affect on the semantic equality.
		BeaninfoEntry otherEntry = (BeaninfoEntry) other;
		if (isExported != otherEntry.isExported)
			return false;	
		if (entry != null)
			return entry.equals(otherEntry.entry);
		
		return pluginPath.equals(otherEntry.pluginPath);
	}
	
	public int hashCode() {
		if (entry != null)
			return entry.hashCode() ^ (isExported ? Boolean.TRUE : Boolean.FALSE).hashCode();
		else
			return pluginPath.hashCode() ^ (isExported ? Boolean.TRUE : Boolean.FALSE).hashCode();
	}

}
