blob: afccb0787a2d50cf14f8bd14db2256c4a9a78ff5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 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.update.core.model;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Locale;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.eclipse.update.core.IURLEntry;
import org.eclipse.update.core.SiteFeatureReferenceModel;
import org.eclipse.update.core.URLEntry;
import org.eclipse.update.internal.core.ExtendedSite;
import org.eclipse.update.internal.core.Messages;
import org.eclipse.update.internal.core.UpdateCore;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* 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
* @deprecated The org.eclipse.update component has been replaced by Equinox p2. This
* provisional API was never promoted to stable API, and may be removed from a future release of the platform.
*/
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 ASSOCIATE_SITES = "associateSites"; //$NON-NLS-1$
private static final String ASSOCIATE_SITE = "associateSite"; //$NON-NLS-1$
private static final String DEFAULT_INFO_URL = "index.html"; //$NON-NLS-1$
private static final String FEATURES = "features/"; //$NON-NLS-1$
// 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(Messages.DefaultSiteParser_NoSiteTag);
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(NLS.bind(Messages.DefaultSiteParser_WrongParsingStack, (new String[] { stack })));
}
}
}
/**
* 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(NLS.bind(Messages.DefaultSiteParser_UnknownElement, (new String[] { localName, getState(currentState) })));
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(NLS.bind(Messages.DefaultSiteParser_UnknownStartState, (new String[] { getState(currentState) })));
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(Messages.DefaultSiteParser_ParsingStackBackToInitialState);
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(NLS.bind(Messages.DefaultSiteParser_ElementAlreadySet, (new String[] { getState(state) })));
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(NLS.bind(Messages.DefaultSiteParser_ElementAlreadySet, (new String[] { getState(state), category.getLabel() })));
else
category.setDescriptionModel(info);
break;
default :
internalError(NLS.bind(Messages.DefaultSiteParser_UnknownEndState, (new String[] { getState(state) })));
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(NLS.bind(Messages.DefaultSiteParser_UnknownElement, (new String[] { elementName, getState(currentState) })));
// what we received was not a site.xml, no need to continue
throw new SAXException(Messages.DefaultSiteParser_InvalidXMLStream);
}
}
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(NLS.bind(Messages.DefaultSiteParser_UnknownElement, (new String[] { elementName, getState(currentState) })));
}
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(NLS.bind(Messages.DefaultSiteParser_UnknownElement, (new String[] { elementName, getState(currentState) })));
}
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(NLS.bind(Messages.DefaultSiteParser_UnknownElement, (new String[] { elementName, getState(currentState) })));
}
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(NLS.bind(Messages.DefaultSiteParser_UnknownElement, (new String[] { elementName, getState(currentState) })));
}
/*
* 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);
}
String pack200 = attributes.getValue("pack200"); //$NON-NLS-1$
if(site instanceof ExtendedSite && pack200 != null && new Boolean(pack200).booleanValue()){
((ExtendedSite) site).setSupportsPack200(true);
}
if ( (site instanceof ExtendedSite) && (attributes.getValue("digestURL") != null)) { //$NON-NLS-1$
ExtendedSite extendedSite = (ExtendedSite) site;
extendedSite.setDigestExist(true);
extendedSite.setDigestURL(attributes.getValue("digestURL")); //$NON-NLS-1$
if ( (attributes.getValue("availableLocales") != null) && (!attributes.getValue("availableLocales").trim().equals(""))) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
StringTokenizer locals = new StringTokenizer(attributes.getValue("availableLocales"), ","); //$NON-NLS-1$//$NON-NLS-2$
String[] availableLocals = new String[locals.countTokens()];
int i = 0;
while(locals.hasMoreTokens()) {
availableLocals[i++] = locals.nextToken();
}
extendedSite.setAvailableLocals(availableLocals);
}
}
if ( (site instanceof ExtendedSite) && (attributes.getValue("associateSitesURL") != null)) { //$NON-NLS-1$
IURLEntry[] associateSites = getAssociateSites(attributes.getValue("associateSitesURL"), factory); //$NON-NLS-1$
if (associateSites != null)
((ExtendedSite)site).setAssociateSites(associateSites);
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(NLS.bind(Messages.DefaultSiteParser_Missing, (new String[] { "url", getState(currentState) }))); //$NON-NLS-1$
else // default url
urlInfo = FEATURES + id + '_' + ver; //
}
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(NLS.bind(Messages.DefaultFeatureParser_IdOrVersionInvalid, values));
} 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(NLS.bind(Messages.DefaultSiteParser_Missing, (new String[] { "path", getState(currentState) }))); //$NON-NLS-1$
}
archive.setPath(id);
String url = attributes.getValue("url"); //$NON-NLS-1$
if (url == null || url.trim().equals("")) { //$NON-NLS-1$
internalError(NLS.bind(Messages.DefaultSiteParser_Missing, (new String[] { "archive", getState(currentState) }))); //$NON-NLS-1$
} 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 = NLS.bind(Messages.DefaultSiteParser_ErrorParsing, (new String[] { ex.getMessage() }));
else {
String[] values = new String[] { name, Integer.toString(ex.getLineNumber()), Integer.toString(ex.getColumnNumber()), ex.getMessage()};
msg = NLS.bind(Messages.DefaultSiteParser_ErrorlineColumnMessage, values);
}
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, Messages.DefaultSiteParser_ErrorParsingSite, null);
}
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 Messages.DefaultSiteParser_UnknownState;
}
}
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 {
String countryCode = Locale.getDefault().getCountry().toLowerCase();
int timeZone = (new GregorianCalendar()).get(Calendar.ZONE_OFFSET)/(60*60*1000);
if (mirrorsURL.indexOf("?") != -1) { //$NON-NLS-1$
mirrorsURL = mirrorsURL + "&"; //$NON-NLS-1$
} else {
mirrorsURL = mirrorsURL + "?"; //$NON-NLS-1$
}
mirrorsURL = mirrorsURL + "countryCode=" + countryCode + "&timeZone=" + timeZone + "&responseType=xml"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
DocumentBuilderFactory domFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document document = builder.parse(mirrorsURL);
if (document == null)
return null;
NodeList mirrorNodes = document.getElementsByTagName(MIRROR);
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://") //$NON-NLS-1$
|| mirrorsURL.startsWith("https://") //$NON-NLS-1$
|| mirrorsURL.startsWith("file://") //$NON-NLS-1$
|| mirrorsURL.startsWith("ftp://") //$NON-NLS-1$
|| mirrorsURL.startsWith("jar://"))) //$NON-NLS-1$
UpdateCore.log(Messages.DefaultSiteParser_mirrors, e);
return null;
}
}
private static IURLEntry[] getAssociateSites(String associateSitesURL, SiteModelFactory factory) {
try {
DocumentBuilderFactory domFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document document = builder.parse(associateSitesURL);
if (document == null)
return null;
NodeList mirrorNodes = document.getElementsByTagName(ASSOCIATE_SITE);
URLEntry[] mirrors = new URLEntry[mirrorNodes.getLength()];
for (int i=0; i<mirrorNodes.getLength(); i++) {
Element mirrorNode = (Element)mirrorNodes.item(i);
mirrors[i] = new URLEntry();
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 (associateSitesURL != null &&
(associateSitesURL.startsWith("http://") //$NON-NLS-1$
|| associateSitesURL.startsWith("https://") //$NON-NLS-1$
|| associateSitesURL.startsWith("file://") //$NON-NLS-1$
|| associateSitesURL.startsWith("ftp://") //$NON-NLS-1$
|| associateSitesURL.startsWith("jar://"))) //$NON-NLS-1$
UpdateCore.log(Messages.DefaultSiteParser_mirrors, e);
return null;
}
}
}