blob: 11279e99e5f8f4c7d9a127a135a04bd3b6f37a7f [file] [log] [blame]
/*
* Copyright (c) 2002 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 - Initial API and implementation
* Jens Lukowski/Innoopract - initial renaming/restructuring
*
*/
package org.eclipse.wst.xml.core.internal.contentmodel.internal.annotation;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.wst.xml.core.internal.Logger;
import org.eclipse.wst.xml.core.internal.contentmodel.annotation.Annotation;
import org.eclipse.wst.xml.core.internal.contentmodel.annotation.AnnotationMap;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
*
*/
public class AnnotationFileParser {
public static final String TAG_ID_ANNOTATIONS = "abstractGrammarAnnotations"; //$NON-NLS-1$
public static final String TAG_ID_ANNOTATION = "annotation"; //$NON-NLS-1$
public static final String TAG_ID_PROPERTY = "property"; //$NON-NLS-1$
/**
* This method is called to parse an annotation file and store the
* contents into an annotationMap
*/
private void parse(AnnotationMap annotationMap, InputStream input, AnnotationFileInfo fileInfo) throws Exception {
// move to Xerces-2.... add 'contextClassLoader' stuff
ClassLoader prevClassLoader = Thread.currentThread().getContextClassLoader();
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
SAXParser parser = factory.newSAXParser();
parser.parse(new InputSource(input), new AnnotationMapContentHandler(annotationMap, fileInfo));
}
finally {
Thread.currentThread().setContextClassLoader(prevClassLoader);
}
}
/**
* This method is called to parse an annotation file and store the
* contents into an annotationMap
*/
public void parse(AnnotationMap map, AnnotationFileInfo fileInfo) throws Exception {
InputStream inputStream = null;
try {
URL url = Platform.find(Platform.getBundle(fileInfo.getBundleId()), Path.fromOSString(fileInfo.getAnnotationFileLocation()));
if (url != null) {
inputStream = url.openStream();
parse(map, inputStream, fileInfo);
}
}
catch (Exception e) {
Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
throw (e);
}
finally {
try {
if (inputStream != null) {
inputStream.close();
}
}
catch (IOException e) {
}
}
}
protected class AnnotationMapContentHandler extends DefaultHandler {
private AnnotationMap annotationMap;
private Annotation currentAnnotation;
private String currentPropertyName;
private StringBuffer propertyValueBuffer;
private ResourceBundle resourceBundle;
private AnnotationFileInfo fFileInfo;
public AnnotationMapContentHandler(AnnotationMap annotationMap, AnnotationFileInfo fileInfo) {
this.annotationMap = annotationMap;
this.fFileInfo = fileInfo;
}
private URL generatePropertiesFileURL(AnnotationFileInfo fileInfo, String propertiesLocation) {
URL propertiesURL = null;
// prepend $nl$ variable to location
IPath annotationPath = Path.fromOSString("$nl$/" + fileInfo.getAnnotationFileLocation()); //$NON-NLS-1$
// remove the annotation.xml file
IPath annotationFolder = annotationPath.removeLastSegments(1);
// append location of propertiles file
IPath propertiesFile = annotationFolder.append(propertiesLocation);
// append .properties extension if needed
if (propertiesFile.getFileExtension() == null)
propertiesFile = propertiesFile.addFileExtension("properties"); //$NON-NLS-1$
// create a URL out of the properties file location
propertiesURL = Platform.find(Platform.getBundle(fileInfo.getBundleId()), propertiesFile);
return propertiesURL;
}
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
propertyValueBuffer = new StringBuffer();
if (localName.equals(TAG_ID_ANNOTATIONS)) {
int attributesLength = attributes.getLength();
for (int i = 0; i < attributesLength; i++) {
String attributeName = attributes.getLocalName(i);
String attributeValue = attributes.getValue(i);
if (attributeName.equals("propertiesLocation")) //$NON-NLS-1$
{
URL bundleURL = generatePropertiesFileURL(fFileInfo, attributeValue);
if (bundleURL != null) {
InputStream bundleStream = null;
try {
bundleStream = bundleURL.openStream();
resourceBundle = new PropertyResourceBundle(bundleStream);
}
catch (IOException e) {
Logger.log(Logger.WARNING_DEBUG, e.getMessage(), e);
}
finally {
try {
if (bundleStream != null)
bundleStream.close();
}
catch (IOException x) {
Logger.log(Logger.WARNING_DEBUG, x.getMessage(), x);
}
}
}
}
else if (attributeName.equals("caseSensitive")) //$NON-NLS-1$
{
if (attributeValue.trim().equals("false")) //$NON-NLS-1$
{
annotationMap.setCaseSensitive(false);
}
}
}
}
else if (localName.equals(TAG_ID_ANNOTATION)) {
currentAnnotation = null;
String specValue = attributes.getValue("spec"); //$NON-NLS-1$
if (specValue != null) {
currentAnnotation = new Annotation();
currentAnnotation.setSpec(specValue);
}
annotationMap.addAnnotation(currentAnnotation);
}
else if (localName.equals(TAG_ID_PROPERTY)) {
if (currentAnnotation != null) {
currentPropertyName = attributes.getValue("name"); //$NON-NLS-1$
}
}
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if (currentPropertyName != null && currentAnnotation != null) {
String propertyValue = propertyValueBuffer.toString();
if (propertyValue != null) {
if (propertyValue.startsWith("%") && resourceBundle != null) //$NON-NLS-1$
{
try {
propertyValue = resourceBundle.getString(propertyValue.substring(1));
}
catch (Exception e) {
// ignore any exception that occurs while trying
// to fetch a resource
}
}
currentAnnotation.setProperty(currentPropertyName, propertyValue);
}
}
if (localName.equals(TAG_ID_ANNOTATION)) {
currentAnnotation = null;
}
else if (localName.equals(TAG_ID_PROPERTY)) {
currentPropertyName = null;
}
}
public void characters(char[] ch, int start, int length) {
if (currentPropertyName != null && currentAnnotation != null) {
propertyValueBuffer.append(ch, start, length);
}
}
}
}