/*******************************************************************************
 * Copyright (c) 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.wtp.releng.tools.component.ui.internal;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
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.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.wtp.releng.tools.component.IClazzVisitor;
import org.eclipse.wtp.releng.tools.component.ILibrary;
import org.eclipse.wtp.releng.tools.component.ILocation;
import org.eclipse.wtp.releng.tools.component.IPluginXML;
import org.eclipse.wtp.releng.tools.component.internal.FileLocation;
import org.eclipse.wtp.releng.tools.component.internal.Library;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class WorkspacePluginXML implements IPluginXML
{
  private IFile pluginXML;
  private List libraries;
  private String name;
  private String version;
  private ILocation location;

  public WorkspacePluginXML(IFile pluginXML)
  {
    this.pluginXML = pluginXML;
  }

  private void init()
  {
    InputStream is = null;
    try
    {
      SAXParserFactory factory = SAXParserFactory.newInstance();
      factory.setNamespaceAware(false);
      factory.setValidating(false);
      SAXParser saxParser = factory.newSAXParser();
      is = getLocation().getInputStream();
      saxParser.parse(new InputSource(is), new PluginHandler());
    }
    catch (ParserConfigurationException e)
    {
      e.printStackTrace();
    }
    catch (SAXException e)
    {
      e.printStackTrace();
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    finally
    {
      if (is != null)
      {
        try
        {
          is.close();
        }
        catch (IOException e)
        {
          e.printStackTrace();
        }
      }
    }
  }

  /**
   * Answers the libraries that are declared in this plugin.
   * 
   * @return List libraries in this plugin
   */
  public List getLibraries()
  {
    if (libraries == null)
    {
      libraries = new ArrayList(1);
      IJavaProject javaProject = JavaCore.create(pluginXML.getProject());
      try
      {
        libraries.add(new Library(new FileLocation(getAbsolutePath(javaProject.getOutputLocation()).toFile())));
      }
      catch (JavaModelException e)
      {
        e.printStackTrace();
      }
    }
    return libraries;
  }

  /**
   * Answers the name of this plugin. Plugin names do not contain the version
   * identifier, for example, org.eclipse.core.resources.
   * 
   * @return String the name of the plugin, not <code>null</code>.
   */
  public String getName()
  {
    if (name == null)
      init();
    return name;
  }

  /**
   * Answers the version identifier for the plugin. A version identifier is a
   * '.' delimited set of numbers, for example, 2.0.1.5.
   * 
   * @return String the plugin version, not <code>null</code>.
   */
  public String getVersion()
  {
    if (version == null)
      init();
    return version;
  }

  /**
   * The unique identifier is a concatination of the plugin name, and '_' and
   * the plugin version.
   * 
   * @return String the unique identifier of the plugin.
   */
  public String getUniqueIdentifier()
  {
    return getName() + "_" + getVersion();
  }

  public void accept(IClazzVisitor visitor)
  {
    for (Iterator it = getLibraries().iterator(); it.hasNext();)
    {
      ILibrary lib = (ILibrary)it.next();
      lib.accept(visitor);
      lib.resetTypes();
    }
  }

  public IProject getProject()
  {
    return pluginXML.getProject();
  }

  private ILocation getLocation()
  {
    if (location == null)
      location = new FileLocation(getAbsolutePath(pluginXML.getFullPath()).toFile());
    return location;
  }

  private IPath getAbsolutePath(IPath path)
  {
    return Platform.getLocation().append(path);
  }

  private class PluginHandler extends DefaultHandler
  {
    public void startElement(String uri, String elementName, String qName, Attributes attributes) throws SAXException
    {
      if (elementName.equals("plugin") || qName.equals("plugin"))
      {
        name = attributes.getValue("id");
        version = attributes.getValue("version");
      }
    }
  }
}
