/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.update.core.model;

import java.io.*;
import java.util.*;
import javax.xml.parsers.*;

import org.eclipse.core.runtime.*;
import org.eclipse.update.core.*;
import org.eclipse.update.internal.core.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

/**
 * Default site parser.
 * Parses the site manifest file as defined by the platform. Defers
 * to a model factory to create the actual concrete model objects. The 
 * update framework supplies two factory implementations:
 * <ul>
 * <li>@see org.eclipse.update.core.model.SiteModelFactory
 * <li>@see org.eclipse.update.core.BaseSiteFactory
 * </ul>
 * 
 * <p>
 * <b>Note:</b> This class/interface is part of an interim API that is still under development and expected to
 * change significantly before reaching stability. It is being made available at this early stage to solicit feedback
 * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
 * (repeatedly) as the API evolves.
 * </p>
 * @since 2.0
 */
public class DefaultSiteParser extends DefaultHandler {
	
	private final static SAXParserFactory parserFactory =
		SAXParserFactory.newInstance();
	
	private SAXParser parser;
	private SiteModelFactory factory;

	private MultiStatus status;

	private boolean DESCRIPTION_SITE_ALREADY_SEEN = false;

	private static final int STATE_IGNORED_ELEMENT = -1;
	private static final int STATE_INITIAL = 0;
	private static final int STATE_SITE = 1;
	private static final int STATE_FEATURE = 2;
	private static final int STATE_ARCHIVE = 3;
	private static final int STATE_CATEGORY = 4;
	private static final int STATE_CATEGORY_DEF = 5;
	private static final int STATE_DESCRIPTION_SITE = 6;
	private static final int STATE_DESCRIPTION_CATEGORY_DEF = 7;
	private static final String PLUGIN_ID = UpdateCore.getPlugin().getBundle().getSymbolicName();

	private static final String SITE = "site"; //$NON-NLS-1$
	private static final String FEATURE = "feature"; //$NON-NLS-1$
	private static final String ARCHIVE = "archive"; //$NON-NLS-1$
	private static final String CATEGORY_DEF = "category-def"; //$NON-NLS-1$
	private static final String CATEGORY = "category"; //$NON-NLS-1$
	private static final String DESCRIPTION = "description"; //$NON-NLS-1$
	private static final String MIRROR = "mirror"; //$NON-NLS-1$

	private static final String DEFAULT_INFO_URL = "index.html"; //$NON-NLS-1$
	private static final String FEATURES = "features/";
    
	// Current State Information
	Stack stateStack = new Stack();

	// Current object stack (used to hold the current object we are
	// populating in this plugin descriptor
	Stack objectStack = new Stack();

	private int currentState;

	/**
	 * Constructs a site parser.
	 */
	public DefaultSiteParser() {
		super();
		try {
			parserFactory.setNamespaceAware(true);
			this.parser = parserFactory.newSAXParser();
		} catch (ParserConfigurationException e) {
			UpdateCore.log(e);
		} catch (SAXException e) {
			UpdateCore.log(e);
		}

		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING)
			debug("Created"); //$NON-NLS-1$
	}

	public void init(SiteModelFactory factory) {
		// PERF: separate instance creation from parsing
		this.factory = factory;
		stateStack = new Stack();
		objectStack = new Stack();
		status = null;
		DESCRIPTION_SITE_ALREADY_SEEN = false;
	}

	/**
	 * Parses the specified input steam and constructs a site model.
	 * The input stream is not closed as part of this operation.
	 * 
	 * @param in input stream
	 * @return site model
	 * @exception SAXException
	 * @exception IOException
	 * @since 2.0
	 */
	public SiteModel parse(InputStream in) throws SAXException, IOException {
		stateStack.push(new Integer(STATE_INITIAL));
		currentState = ((Integer) stateStack.peek()).intValue();
		parser.parse(new InputSource(in), this);
		if (objectStack.isEmpty())
			throw new SAXException(Policy.bind("DefaultSiteParser.NoSiteTag"));	//$NON-NLS-1$
		else {
			if (objectStack.peek() instanceof SiteModel) {
				return (SiteModel) objectStack.pop();
			} else {
				String stack = ""; //$NON-NLS-1$
				Iterator iter = objectStack.iterator();
				while (iter.hasNext()) {
					stack = stack + iter.next().toString() + "\r\n"; //$NON-NLS-1$
				}
				throw new SAXException(Policy.bind("DefaultSiteParser.WrongParsingStack", stack));	//$NON-NLS-1$
			}
		}
	}

	/**
	 * Returns all status objects accumulated by the parser.
	 *
	 * @return multi-status containing accumulated status, or <code>null</code>.
	 * @since 2.0
	 */
	public MultiStatus getStatus() {
		return status;
	}

	/**
	 * Handle start of element tags
	 * @see DefaultHandler#startElement(String, String, String, Attributes)
	 * @since 2.0
	 */
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING) {
			debug("State: " + currentState); //$NON-NLS-1$
			debug("Start Element: uri:" + uri + " local Name:" + localName + " qName:" + qName);//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}

		switch (currentState) {
			case STATE_IGNORED_ELEMENT :
				internalErrorUnknownTag(Policy.bind("DefaultSiteParser.UnknownElement", localName, getState(currentState)));//$NON-NLS-1$
				break;
			case STATE_INITIAL :
				handleInitialState(localName, attributes);
				break;

			case STATE_SITE :
				handleSiteState(localName, attributes);
				break;

			case STATE_FEATURE :
				handleFeatureState(localName, attributes);
				break;

			case STATE_ARCHIVE :
				handleSiteState(localName, attributes);
				break;

			case STATE_CATEGORY :
				handleCategoryState(localName, attributes);
				break;

			case STATE_CATEGORY_DEF :
				handleCategoryDefState(localName, attributes);
				break;

			case STATE_DESCRIPTION_SITE :
				handleSiteState(localName, attributes);
				break;

			case STATE_DESCRIPTION_CATEGORY_DEF :
				handleSiteState(localName, attributes);
				break;

			default :
				internalErrorUnknownTag(Policy.bind("DefaultSiteParser.UnknownStartState", getState(currentState)));//$NON-NLS-1$
				break;
		}
		int newState = ((Integer) stateStack.peek()).intValue();
		if (newState != STATE_IGNORED_ELEMENT)
			currentState = newState;

	}

	/**
	 * Handle end of element tags
	 * @see DefaultHandler#endElement(String, String, String)
	 * @since 2.0
	 */
	public void endElement(String uri, String localName, String qName) {

		String text = null;
		URLEntryModel info = null;

		int state = ((Integer) stateStack.peek()).intValue();
		switch (state) {
			case STATE_IGNORED_ELEMENT :
			case STATE_ARCHIVE :
			case STATE_CATEGORY :
				stateStack.pop();
				break;

			case STATE_INITIAL :
				internalError(Policy.bind("DefaultSiteParser.ParsingStackBackToInitialState"));	//$NON-NLS-1$
				break;

			case STATE_SITE :
				stateStack.pop();
				if (objectStack.peek() instanceof String) {
					text = (String) objectStack.pop();
					SiteModel site = (SiteModel) objectStack.peek();
					site.getDescriptionModel().setAnnotation(text);
				}
				//do not pop the object
				break;

			case STATE_FEATURE :
				stateStack.pop();
				objectStack.pop();
				break;

			case STATE_CATEGORY_DEF :
				stateStack.pop();
				if (objectStack.peek() instanceof String) {
					text = (String) objectStack.pop();
					CategoryModel category = (CategoryModel) objectStack.peek();
					category.getDescriptionModel().setAnnotation(text);
				}
				objectStack.pop();
				break;

			case STATE_DESCRIPTION_SITE :
				stateStack.pop();
				text = ""; //$NON-NLS-1$
				while (objectStack.peek() instanceof String) {
					// add text, preserving at most one space between text fragments
					String newText = (String) objectStack.pop();
					if (trailingSpace(newText) && !leadingSpace(text)) {
						text = " " + text; //$NON-NLS-1$
					}
					text = newText.trim() + text;
					if (leadingSpace(newText) && !leadingSpace(text)) {
						text = " " + text; //$NON-NLS-1$
					}
				}
				text = text.trim();

				info = (URLEntryModel) objectStack.pop();
				if (text != null)
					info.setAnnotation(text);

				SiteModel siteModel = (SiteModel) objectStack.peek();
				// override description.
				// do not raise error as previous description may be default one
				// when parsing site tag
				if (DESCRIPTION_SITE_ALREADY_SEEN)
					debug(Policy.bind("DefaultSiteParser.ElementAlreadySet", getState(state)));	//$NON-NLS-1$
				siteModel.setDescriptionModel(info);
				DESCRIPTION_SITE_ALREADY_SEEN = true;
				break;

			case STATE_DESCRIPTION_CATEGORY_DEF :
				stateStack.pop();
				text = ""; //$NON-NLS-1$
				while (objectStack.peek() instanceof String) {
					// add text, preserving at most one space between text fragments
					String newText = (String) objectStack.pop();
					if (trailingSpace(newText) && !leadingSpace(text)) {
						text = " " + text; //$NON-NLS-1$
					}
					text = newText.trim() + text;
					if (leadingSpace(newText) && !leadingSpace(text)) {
						text = " " + text; //$NON-NLS-1$
					}
				}
				text = text.trim();

				info = (URLEntryModel) objectStack.pop();
				if (text != null)
					info.setAnnotation(text);

				CategoryModel category = (CategoryModel) objectStack.peek();
				if (category.getDescriptionModel() != null)
					internalError(Policy.bind("DefaultSiteParser.ElementAlreadySet2", getState(state), category.getLabel()));//$NON-NLS-1$
				else
					category.setDescriptionModel(info);
				break;

			default :
				internalError(Policy.bind("DefaultSiteParser.UnknownEndState", getState(state)));//$NON-NLS-1$
				break;
		}

		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING)
			debug("End Element:" + uri + ":" + localName + ":" + qName);//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}

	/**
	 * Handle character text
	 * @see DefaultHandler#characters(char[], int, int)
	 * @since 2.0
	 */
	public void characters(char[] ch, int start, int length) {
		String text = new String(ch, start, length);
		//only push if description
		int state = ((Integer) stateStack.peek()).intValue();
		if (state == STATE_DESCRIPTION_SITE || state == STATE_DESCRIPTION_CATEGORY_DEF)
			objectStack.push(text);

	}

	/**
	 * Handle errors
	 * @see DefaultHandler#error(SAXParseException)
	 * @since 2.0
	 */
	public void error(SAXParseException ex) {
		logStatus(ex);
	}

	/**
	 * Handle fatal errors
	 * @see DefaultHandler#fatalError(SAXParseException)
	 * @exception SAXException
	 * @since 2.0
	 */
	public void fatalError(SAXParseException ex) throws SAXException {
		logStatus(ex);
		throw ex;
	}

	private void handleInitialState(String elementName, Attributes attributes) throws SAXException {
		if (elementName.equals(SITE)) {
			stateStack.push(new Integer(STATE_SITE));
			processSite(attributes);
		} else {
			internalErrorUnknownTag(Policy.bind("DefaultSiteParser.UnknownElement", elementName, getState(currentState)));	//$NON-NLS-1$
			// what we received was not a site.xml, no need to continue
			throw new SAXException(Policy.bind("DefaultSiteParser.InvalidXMLStream")); //$NON-NLS-1$
		}

	}

	private void handleSiteState(String elementName, Attributes attributes) {
		if (elementName.equals(DESCRIPTION)) {
			stateStack.push(new Integer(STATE_DESCRIPTION_SITE));
			processInfo(attributes);
		} else if (elementName.equals(FEATURE)) {
			stateStack.push(new Integer(STATE_FEATURE));
			processFeature(attributes);
		} else if (elementName.equals(ARCHIVE)) {
			stateStack.push(new Integer(STATE_ARCHIVE));
			processArchive(attributes);
		} else if (elementName.equals(CATEGORY_DEF)) {
			stateStack.push(new Integer(STATE_CATEGORY_DEF));
			processCategoryDef(attributes);
		} else
			internalErrorUnknownTag(Policy.bind("DefaultSiteParser.UnknownElement", elementName, getState(currentState))); //$NON-NLS-1$ 			
	}

	private void handleFeatureState(String elementName, Attributes attributes) {
		if (elementName.equals(DESCRIPTION)) {
			stateStack.push(new Integer(STATE_DESCRIPTION_SITE));
			processInfo(attributes);
		} else if (elementName.equals(FEATURE)) {
			stateStack.push(new Integer(STATE_FEATURE));
			processFeature(attributes);
		} else if (elementName.equals(ARCHIVE)) {
			stateStack.push(new Integer(STATE_ARCHIVE));
			processArchive(attributes);
		} else if (elementName.equals(CATEGORY_DEF)) {
			stateStack.push(new Integer(STATE_CATEGORY_DEF));
			processCategoryDef(attributes);
		} else if (elementName.equals(CATEGORY)) {
			stateStack.push(new Integer(STATE_CATEGORY));
			processCategory(attributes);
		} else
			internalErrorUnknownTag(Policy.bind("DefaultSiteParser.UnknownElement", elementName, getState(currentState))); //$NON-NLS-1$ 			
	}

	private void handleCategoryDefState(String elementName, Attributes attributes) {
		if (elementName.equals(FEATURE)) {
			stateStack.push(new Integer(STATE_FEATURE));
			processFeature(attributes);
		} else if (elementName.equals(ARCHIVE)) {
			stateStack.push(new Integer(STATE_ARCHIVE));
			processArchive(attributes);
		} else if (elementName.equals(CATEGORY_DEF)) {
			stateStack.push(new Integer(STATE_CATEGORY_DEF));
			processCategoryDef(attributes);
		} else if (elementName.equals(DESCRIPTION)) {
			stateStack.push(new Integer(STATE_DESCRIPTION_CATEGORY_DEF));
			processInfo(attributes);
		} else
			internalErrorUnknownTag(Policy.bind("DefaultSiteParser.UnknownElement", elementName, getState(currentState)));	//$NON-NLS-1$ 			
	}

	private void handleCategoryState(String elementName, Attributes attributes) {
		if (elementName.equals(DESCRIPTION)) {
			stateStack.push(new Integer(STATE_DESCRIPTION_SITE));
			processInfo(attributes);
		} else if (elementName.equals(FEATURE)) {
			stateStack.push(new Integer(STATE_FEATURE));
			processFeature(attributes);
		} else if (elementName.equals(ARCHIVE)) {
			stateStack.push(new Integer(STATE_ARCHIVE));
			processArchive(attributes);
		} else if (elementName.equals(CATEGORY_DEF)) {
			stateStack.push(new Integer(STATE_CATEGORY_DEF));
			processCategoryDef(attributes);
		} else if (elementName.equals(CATEGORY)) {
			stateStack.push(new Integer(STATE_CATEGORY));
			processCategory(attributes);
		} else
			internalErrorUnknownTag(Policy.bind("DefaultSiteParser.UnknownElement", elementName, getState(currentState)));//$NON-NLS-1$ 			
	}

	/* 
	 * process site info
	 */
	private void processSite(Attributes attributes) throws SAXException {
		// create site map
		SiteModel site = factory.createSiteMapModel();

		// if URL is specified, it replaces the URL of the site
		// used to calculate the location of features and archives
		String siteURL = attributes.getValue("url"); //$NON-NLS-1$
		if (siteURL != null && !("".equals(siteURL.trim()))) { //$NON-NLS-1$
			if (!siteURL.endsWith("/") && !siteURL.endsWith(File.separator)) { //$NON-NLS-1$
				siteURL += "/"; //$NON-NLS-1$
			}
			site.setLocationURLString(siteURL);
		}

		// provide default description URL
		// If <description> is specified, for the site,  it takes precedence		
		URLEntryModel description = factory.createURLEntryModel();
		description.setURLString(DEFAULT_INFO_URL);
		site.setDescriptionModel(description);

		// verify we can parse the site ...if the site has
		// a different type throw an exception to force reparsing
		// with the matching parser
		String type = attributes.getValue("type"); //$NON-NLS-1$
		if (!factory.canParseSiteType(type)) {
			throw new SAXException(new InvalidSiteTypeException(type));
		}
		site.setType(type);
		
		// get mirrors, if any
		String mirrorsURL = attributes.getValue("mirrorsURL"); //$NON-NLS-1$
		if (mirrorsURL != null && mirrorsURL.trim().length() > 0) {
			URLEntryModel[] mirrors = getMirrors(mirrorsURL, factory);
			if (mirrors != null)
				site.setMirrorSiteEntryModels(mirrors);
			else 
				site.setMirrorsURLString(mirrorsURL);
		}
		
		objectStack.push(site);

		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING)
			debug("End process Site tag: siteURL:" + siteURL + " type:" + type);//$NON-NLS-1$ //$NON-NLS-2$

	}

	/* 
	 * process feature info
	 */
	private void processFeature(Attributes attributes) {
		SiteFeatureReferenceModel feature = factory.createFeatureReferenceModel();
		
        // feature location on the site
        String urlInfo = attributes.getValue("url"); //$NON-NLS-1$
        // identifier and version
        String id = attributes.getValue("id"); //$NON-NLS-1$
        String ver = attributes.getValue("version"); //$NON-NLS-1$
        
        boolean noURL = (urlInfo == null || urlInfo.trim().equals("")); //$NON-NLS-1$
        boolean noId = (id == null || id.trim().equals("")); //$NON-NLS-1$
        boolean noVersion = (ver == null || ver.trim().equals("")); //$NON-NLS-1$
        
        // We need to have id and version, or the url, or both.
 		if (noURL) {
            if (noId || noVersion)
                internalError(Policy.bind("DefaultSiteParser.Missing", "url", getState(currentState)));	//$NON-NLS-1$  //$NON-NLS-2$
            else // default url
                urlInfo = FEATURES + id + '_' + ver; //$NON-NLS-1$ 
        }
        
		feature.setURLString(urlInfo);

		String type = attributes.getValue("type"); //$NON-NLS-1$
		feature.setType(type);

		// if one is null, and not the other
		if (noId ^ noVersion) {
			String[] values = new String[] { id, ver, getState(currentState)};
			UpdateCore.warn(Policy.bind("DefaultFeatureParser.IdOrVersionInvalid", values));//$NON-NLS-1$
		} else {
			feature.setFeatureIdentifier(id);
			feature.setFeatureVersion(ver);
		}

		// get label if it exists
		String label = attributes.getValue("label"); //$NON-NLS-1$
		if (label != null) {
			if ("".equals(label.trim())) //$NON-NLS-1$
				label = null;
		}
		feature.setLabel(label);

		// OS
		String os = attributes.getValue("os"); //$NON-NLS-1$
		feature.setOS(os);

		// WS
		String ws = attributes.getValue("ws"); //$NON-NLS-1$
		feature.setWS(ws);

		// NL
		String nl = attributes.getValue("nl"); //$NON-NLS-1$
		feature.setNL(nl);

		// arch
		String arch = attributes.getValue("arch"); //$NON-NLS-1$
		feature.setArch(arch);

		//patch
		String patch = attributes.getValue("patch"); //$NON-NLS-1$
		feature.setPatch(patch);

		SiteModel site = (SiteModel) objectStack.peek();
		site.addFeatureReferenceModel(feature);
		feature.setSiteModel(site);

		objectStack.push(feature);

		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING)
			debug("End Processing DefaultFeature Tag: url:" + urlInfo + " type:" + type); //$NON-NLS-1$ //$NON-NLS-2$

	}

	/* 
	 * process archive info
	 */
	private void processArchive(Attributes attributes) {
		ArchiveReferenceModel archive = factory.createArchiveReferenceModel();
		String id = attributes.getValue("path"); //$NON-NLS-1$
		if (id == null || id.trim().equals("")) { //$NON-NLS-1$
			internalError(Policy.bind("DefaultSiteParser.Missing", "path", getState(currentState))); //$NON-NLS-1$  //$NON-NLS-2$
		}

		archive.setPath(id);

		String url = attributes.getValue("url"); //$NON-NLS-1$
		if (url == null || url.trim().equals("")) { //$NON-NLS-1$
			internalError(Policy.bind("DefaultSiteParser.Missing", "archive", getState(currentState)));	//$NON-NLS-1$  //$NON-NLS-2$
		} else {
			archive.setURLString(url);

			SiteModel site = (SiteModel) objectStack.peek();
			site.addArchiveReferenceModel(archive);
		}
		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING)
			debug("End processing Archive: path:" + id + " url:" + url);//$NON-NLS-1$ //$NON-NLS-2$

	}

	/* 
	 * process the Category  info
	 */
	private void processCategory(Attributes attributes) {
		String category = attributes.getValue("name"); //$NON-NLS-1$
		SiteFeatureReferenceModel feature = (SiteFeatureReferenceModel) objectStack.peek();
		feature.addCategoryName(category);

		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING)
			debug("End processing Category: name:" + category); //$NON-NLS-1$
	}

	/* 
	 * process category def info
	 */
	private void processCategoryDef(Attributes attributes) {
		CategoryModel category = factory.createSiteCategoryModel();
		String name = attributes.getValue("name"); //$NON-NLS-1$
		String label = attributes.getValue("label"); //$NON-NLS-1$
		category.setName(name);
		category.setLabel(label);

		SiteModel site = (SiteModel) objectStack.peek();
		site.addCategoryModel(category);
		objectStack.push(category);

		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING)
			debug("End processing CategoryDef: name:" + name + " label:" + label); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/* 
	 * process URL info with element text
	 */
	private void processInfo(Attributes attributes) {
		URLEntryModel inf = factory.createURLEntryModel();
		String infoURL = attributes.getValue("url"); //$NON-NLS-1$
		inf.setURLString(infoURL);

		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING)
			debug("Processed Info: url:" + infoURL); //$NON-NLS-1$

		objectStack.push(inf);
	}

	/*
	 * 
	 */
	private static void debug(String s) {
		UpdateCore.debug("DefaultSiteParser" + s); //$NON-NLS-1$
	}

	/*
	 * 
	 */
	private void logStatus(SAXParseException ex) {
		String name = ex.getSystemId();
		if (name == null)
			name = ""; //$NON-NLS-1$
		else
			name = name.substring(1 + name.lastIndexOf("/")); //$NON-NLS-1$

		String msg;
		if (name.equals("")) //$NON-NLS-1$
			msg = Policy.bind("DefaultSiteParser.ErrorParsing", ex.getMessage());	//$NON-NLS-1$
		else {
			String[] values = new String[] { name, Integer.toString(ex.getLineNumber()), Integer.toString(ex.getColumnNumber()), ex.getMessage()};
			msg = Policy.bind("DefaultSiteParser.ErrorLineColumnMessage", values);//$NON-NLS-1$
		}
		error(new Status(IStatus.ERROR, PLUGIN_ID, Platform.PARSE_PROBLEM, msg, ex));
	}

	/*
	 * Handles an error state specified by the status.  The collection of all logged status
	 * objects can be accessed using <code>getStatus()</code>.
	 *
	 * @param error a status detailing the error condition
	 */
	private void error(IStatus error) {

		if (status == null) {
			status = new MultiStatus(PLUGIN_ID, Platform.PARSE_PROBLEM, Policy.bind("DefaultSiteParser.ErrorParsingSite"), null);//$NON-NLS-1$
		}

		status.add(error);
		if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING)
			UpdateCore.log(error);
	}

	/*
	 * 
	 */
	private void internalErrorUnknownTag(String msg) {
		stateStack.push(new Integer(STATE_IGNORED_ELEMENT));
		internalError(msg);
	}

	/*
	 * 
	 */
	private void internalError(String message) {
		error(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, message, null));
	}

	/*
	 * return the state as String
	 */
	private String getState(int state) {

		switch (state) {
			case STATE_IGNORED_ELEMENT :
				return "Ignored"; //$NON-NLS-1$

			case STATE_INITIAL :
				return "Initial"; //$NON-NLS-1$

			case STATE_SITE :
				return "Site"; //$NON-NLS-1$

			case STATE_FEATURE :
				return "Feature"; //$NON-NLS-1$

			case STATE_ARCHIVE :
				return "Archive"; //$NON-NLS-1$

			case STATE_CATEGORY :
				return "Category"; //$NON-NLS-1$

			case STATE_CATEGORY_DEF :
				return "Category Def"; //$NON-NLS-1$

			case STATE_DESCRIPTION_CATEGORY_DEF :
				return "Description / Category Def"; //$NON-NLS-1$

			case STATE_DESCRIPTION_SITE :
				return "Description / Site"; //$NON-NLS-1$

			default :
				return Policy.bind("DefaultSiteParser.UnknownState"); //$NON-NLS-1$
		}
	}
	private boolean leadingSpace(String str) {
		if (str.length() <= 0) {
			return false;
		}
		return Character.isWhitespace(str.charAt(0));
	}
	private boolean trailingSpace(String str) {
		if (str.length() <= 0) {
			return false;
		}
		return Character.isWhitespace(str.charAt(str.length() - 1));
	}
	
	static URLEntryModel[] getMirrors(String mirrorsURL, SiteModelFactory factory) {
	    
		try {
		    DocumentBuilderFactory domFactory = 
		    DocumentBuilderFactory.newInstance();
		    DocumentBuilder builder = domFactory.newDocumentBuilder();
		    Document document = builder.parse(mirrorsURL);
		    if (document == null)
		    	return null;
		    NodeList mirrorNodes = document.getElementsByTagName(MIRROR); //$NON-NLS-1$
		    URLEntryModel[] mirrors = new URLEntryModel[mirrorNodes.getLength()];
		    for (int i=0; i<mirrorNodes.getLength(); i++) {
		    	Element mirrorNode = (Element)mirrorNodes.item(i);
				mirrors[i] = factory.createURLEntryModel();
				String infoURL = mirrorNode.getAttribute("url"); //$NON-NLS-1$
				String label = mirrorNode.getAttribute("label"); //$NON-NLS-1$
				mirrors[i].setURLString(infoURL);
				mirrors[i].setAnnotation(label);

				if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_PARSING)
					debug("Processed mirror: url:" + infoURL + " label:" + label); //$NON-NLS-1$ //$NON-NLS-2$
		    }
		    return mirrors;
		}
		catch (Exception e) {
		    // log if absolute url
		    if (mirrorsURL != null &&
		    		(mirrorsURL.startsWith("http://")
					|| mirrorsURL.startsWith("https://")
					|| mirrorsURL.startsWith("file://")
					|| mirrorsURL.startsWith("ftp://")
					|| mirrorsURL.startsWith("jar://")))
		    	UpdateCore.log(Policy.bind("DefaultSiteParser.mirrors"), e);
			return null;
		}
	}
}
