/******************************************************************************* * Copyright (c) 2005, 2011 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.wst.jsdt.internal.oaametadata; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; import java.util.Stack; import javax.xml.parsers.ParserConfigurationException; 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.wst.jsdt.internal.core.util.Util; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; public class MetadataReader extends DefaultHandler implements IOAAMetaDataConstants { LibraryAPIs apis=new LibraryAPIs(); Stack stack=new Stack(); HashMap states=new HashMap(); boolean collectText=false; boolean collectHTML=false; boolean pendingEndElement=false; boolean doTranslation=true; String collectTextElement; int currentState=STATE_API; Object currentObject; StringBuffer text=new StringBuffer(); HashMap collections; String filePath; HashMap messages=new HashMap(); static class StackElement { HashMap collections; Object currentObject; int state; StackElement(int st, Object obj, HashMap map) { this.collections=map; this.currentObject=obj; this.state=st; } } static final int STATE_ABOUTME=1; static final int STATE_ALIAS=2; static final int STATE_ALAISES=3; static final int STATE_ANCESTOR=4; static final int STATE_ANCESTORS=5; static final int STATE_API=6; static final int STATE_AUTHOR=7; static final int STATE_AUTHORS=8; static final int STATE_AVAILABLE= 9; static final int STATE_CONSTRUCTOR=10; static final int STATE_CONSTRUCTORS=11; static final int STATE_CLASS=12; static final int STATE_CLASSES=13; static final int STATE_DEPRECIATED = 14; static final int STATE_DESCRIPTION =15; static final int STATE_ENUM =16; static final int STATE_ENUMS =17; static final int STATE_EVENT =18; static final int STATE_EVENTS =19; static final int STATE_EXAMPLE =20; static final int STATE_EXAMPLES =21; static final int STATE_EXCEPTION =22; static final int STATE_EXCEPTIONS =23; static final int STATE_FIELD =24; static final int STATE_FIELDS =25; static final int STATE_GLOBALS=26; static final int STATE_INTERFACE =27; static final int STATE_INTERFACES =28; static final int STATE_LICENSE =29; static final int STATE_METHOD=30; static final int STATE_METHODS =31; static final int STATE_MIX =32; static final int STATE_MIXES =33; static final int STATE_MIXIN =34; static final int STATE_MIXINS =35; static final int STATE_NAMESPACE =36; static final int STATE_NAMESPACES =37; static final int STATE_OPTION =38; static final int STATE_OPTIONS =39; static final int STATE_PARAMETER =40; static final int STATE_PARAMETERS =41; static final int STATE_PROPERTY=42; static final int STATE_PROPERTIES=43; static final int STATE_QOUTE =44; static final int STATE_REMARKS =45; static final int STATE_RETURNS =46; static final int STATE_SEEALSO =47; static final int STATE_TITLE=48; static final int STATE_TOPIC =49; static final int STATE_TOPICS =50; static final int STATE_USERAGENT =51; static final int STATE_USERAGENTS =52; static final int STATE_INCLUDE =53; static final ArrayList EMPTY_LIST=new ArrayList(); { states.put(TAG_ABOUTME, new Integer(STATE_ABOUTME)); states.put(TAG_API, new Integer(STATE_API)); states.put(TAG_AUTHOR, new Integer(STATE_AUTHOR)); states.put(TAG_AVAILABLE, new Integer(STATE_AVAILABLE)); states.put(TAG_CLASS, new Integer(STATE_CLASS)); states.put(TAG_CLASSES, new Integer(STATE_CLASSES)); states.put(TAG_ENUM, new Integer(STATE_ENUM)); states.put(TAG_ENUMS, new Integer(STATE_ENUMS)); states.put(TAG_EXAMPLE, new Integer(STATE_EXAMPLE)); states.put(TAG_EXAMPLES, new Integer(STATE_EXAMPLES)); states.put(TAG_GLOBALS, new Integer(STATE_GLOBALS)); states.put(TAG_METHOD, new Integer(STATE_METHOD)); states.put(TAG_PROPERTY, new Integer(STATE_PROPERTY)); states.put(TAG_PROPERTIES, new Integer(STATE_PROPERTIES)); states.put(TAG_ALIAS, new Integer(STATE_ALIAS)); states.put(TAG_ALIASES, new Integer(STATE_ALAISES)); states.put(TAG_ANCESTORS, new Integer(STATE_ANCESTORS)); states.put(TAG_ANCESTOR, new Integer(STATE_ANCESTOR)); states.put(TAG_AUTHORS, new Integer(STATE_AUTHORS)); states.put(TAG_AUTHOR, new Integer(STATE_AUTHOR)); states.put(TAG_CONSTRUCTORS, new Integer(STATE_CONSTRUCTORS)); states.put(TAG_CONSTRUCTOR, new Integer(STATE_CONSTRUCTOR)); states.put(TAG_DEPRECIATED, new Integer(STATE_DEPRECIATED)); states.put(TAG_DESCRIPTION, new Integer(STATE_DESCRIPTION )); states.put(TAG_ENUM, new Integer(STATE_ENUM )); states.put(TAG_EVENT, new Integer(STATE_EVENT )); states.put(TAG_EVENTS, new Integer(STATE_EVENTS)); states.put(TAG_EXAMPLE, new Integer(STATE_EXAMPLE )); states.put(TAG_EXAMPLES, new Integer(STATE_EXAMPLES )); states.put(TAG_EXCEPTION, new Integer(STATE_EXCEPTION )); states.put(TAG_EXCEPTIONS, new Integer(STATE_EXCEPTIONS)); states.put(TAG_FIELD, new Integer(STATE_FIELD )); states.put(TAG_FIELDS, new Integer(STATE_FIELDS )); states.put(TAG_INTERFACE, new Integer(STATE_INTERFACE )); states.put(TAG_INTERFACES, new Integer(STATE_INTERFACES )); states.put(TAG_LICENSE, new Integer(STATE_LICENSE)); states.put(TAG_METHODS, new Integer(STATE_METHODS )); states.put(TAG_MIX, new Integer(STATE_MIX )); states.put(TAG_MIXES, new Integer(STATE_MIXES )); states.put(TAG_MIXIN, new Integer(STATE_MIXIN)); states.put(TAG_MIXINS, new Integer(STATE_MIXINS )); states.put(TAG_NAMESPACE, new Integer(STATE_NAMESPACE )); states.put(TAG_NAMESPACES, new Integer(STATE_NAMESPACES )); states.put(TAG_OPTION, new Integer(STATE_OPTION )); states.put(TAG_OPTIONS, new Integer(STATE_OPTIONS )); states.put(TAG_PARAMETER, new Integer(STATE_PARAMETER )); states.put(TAG_PARAMETERS, new Integer(STATE_PARAMETERS )); states.put(TAG_QOUTE, new Integer(STATE_QOUTE )); states.put(TAG_REMARKS, new Integer(STATE_REMARKS )); states.put(TAG_RETURNS, new Integer(STATE_RETURNS )); states.put(TAG_SEEALSO, new Integer(STATE_SEEALSO )); states.put(TAG_TITLE, new Integer(STATE_TITLE)); states.put(TAG_TOPIC, new Integer(STATE_TOPIC)); states.put(TAG_TOPICS, new Integer(STATE_TOPICS )); states.put(TAG_USERAGENT, new Integer(STATE_USERAGENT )); states.put(TAG_USERAGENTS, new Integer(STATE_USERAGENTS )); states.put(TAG_INCLUDE, new Integer(STATE_INCLUDE )); } public static LibraryAPIs readAPIsFromStream(InputSource inputSource, String path) { MetadataReader handler= new MetadataReader(); handler.filePath=path; handler.loadMessageBundle(); parseMetadata(inputSource, handler); return handler.apis; } private static void parseMetadata(InputSource inputSource, MetadataReader handler) { try { final SAXParserFactory factory= SAXParserFactory.newInstance(); final SAXParser parser= factory.newSAXParser(); // parser.setProperty("http://xml.org/sax/features/namespaces", new Boolean(true)); XMLReader reader=parser.getXMLReader(); reader.setFeature("http://xml.org/sax/features/namespaces", true); parser.parse(inputSource, handler); } catch (SAXException e) { Util.log(e, "error reading oaametadata"); } catch (IOException e) { Util.log(e, "error reading oaametadata"); } catch (ParserConfigurationException e) { Util.log(e, "error reading oaametadata"); } } public static LibraryAPIs readAPIsFromString(String metadata, String path) { return readAPIsFromStream(new InputSource(new StringReader(metadata)),path); } public static LibraryAPIs readAPIsFromFile(String fileName) { try { FileInputStream file = new FileInputStream(fileName); LibraryAPIs apis= readAPIsFromStream(new InputSource(file),fileName); apis.fileName=fileName.toCharArray(); return apis; } catch (FileNotFoundException e) { Util.log(e, "error reading oaametadata"); } return null; } public void characters(char[] ch, int start, int length) throws SAXException { if (collectText) { if (collectHTML && pendingEndElement) { text.append("/>"); pendingEndElement=false; } text.append(ch,start,length); } } public void endElement(String uri, String localName, String name) throws SAXException { if (collectText) { if (NAMESPACE_API.equals(uri)&& localName.equals(collectTextElement)) { switch (this.currentState) { case STATE_DESCRIPTION: { if (this.currentObject instanceof DocumentedElement) { DocumentedElement documentedElement=((DocumentedElement)this.currentObject); documentedElement.description=localizedString(this.text.toString()); documentedElement.isHTMLDescription=this.collectHTML; } break; } case STATE_DEPRECIATED: case STATE_AVAILABLE: { if (this.currentObject instanceof DepreciatedOrAvailable) { ((DepreciatedOrAvailable)this.currentObject).text=localizedString(this.text.toString()); } break; } case STATE_ABOUTME: case STATE_QOUTE: { if (this.currentObject instanceof Author) { String text=localizedString(this.text.toString()); Author author=(Author)this.currentObject; if (this.currentState==STATE_ABOUTME) author.aboutMe=text; else author.quote=text; } break; } } popState(); this.collectText=false; this.collectHTML=false; this.collectTextElement=null; this.text=new StringBuffer(); } else { if (pendingEndElement) text.append("/>"); else text.append("</").append(localName).append(">"); } pendingEndElement=false; } else { switch (this.currentState) { case STATE_API: { ArrayList collection = getCollection(TAG_CLASS); this.apis.classes= (ClassData[])collection.toArray(new ClassData[collection.size()]); collection = getCollection(TAG_METHOD); this.apis.globalMethods= (Method[])collection.toArray(new Method[collection.size()]); collection = getCollection(TAG_PROPERTY); this.apis.globalVars= (Property[])collection.toArray(new Property[collection.size()]); collection = getCollection(TAG_AUTHOR); this.apis.authors= (Author[])collection.toArray(new Author[collection.size()]); collection = getCollection(TAG_ENUM); this.apis.enums= (Enum[])collection.toArray(new Enum[collection.size()]); collection = getCollection(TAG_ALIAS); this.apis.aliases= (Alias[])collection.toArray(new Alias[collection.size()]); collection = getCollection(TAG_MIXIN); this.apis.mixins= (Mixin[])collection.toArray(new Mixin[collection.size()]); collection = getCollection(TAG_NAMESPACE); this.apis.namespaces= (Namespace[])collection.toArray(new Namespace[collection.size()]); break; } case STATE_CLASS: case STATE_INTERFACE: { ClassData clazz=(ClassData)this.currentObject; ArrayList collection = getCollection(TAG_ANCESTOR); clazz.ancestors= (Ancestor[])collection.toArray(new Ancestor[collection.size()]); collection = getCollection(TAG_CONSTRUCTOR); clazz.constructors= (Method[])collection.toArray(new Method[collection.size()]); collection = getCollection(TAG_EVENT); clazz.events= (Event[])collection.toArray(new Event[collection.size()]); collection = getCollection(TAG_PROPERTY); clazz.properties= (Property[])collection.toArray(new Property[collection.size()]); collection = getCollection(TAG_FIELD); clazz.fields= (Property[])collection.toArray(new Property[collection.size()]); collection = getCollection(TAG_METHOD); clazz.methods= (Method[])collection.toArray(new Method[collection.size()]); collection = getCollection(TAG_AUTHOR); clazz.mixins= (Mix[])collection.toArray(new Mix[collection.size()]); collection = getCollection(TAG_ALIAS); clazz.aliases= (Alias[])collection.toArray(new Alias[collection.size()]); break; } case STATE_CONSTRUCTOR: case STATE_METHOD: { Method method=(Method)this.currentObject; ArrayList collection = getCollection(TAG_EXCEPTION); method.exceptions= (Exception[])collection.toArray(new Exception[collection.size()]); collection = getCollection(TAG_PARAMETER); method.parameters= (Parameter[])collection.toArray(new Parameter[collection.size()]); break; } case STATE_ENUM: { Enum enumData=(Enum)this.currentObject; ArrayList collection = getCollection(TAG_OPTION); enumData.options= (Option[])collection.toArray(new Option[collection.size()]); break; } case STATE_EVENT: { Event event=(Event)this.currentObject; ArrayList collection = getCollection(TAG_PARAMETER); event.parameters= (Parameter[])collection.toArray(new Parameter[collection.size()]); break; } case STATE_EXCEPTION: { Exception exception=(Exception)this.currentObject; ArrayList collection = getCollection(TAG_PARAMETER); exception.parameters= (Parameter[])collection.toArray(new Parameter[collection.size()]); break; } } popState(); } } public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { if (collectText) { if (collectHTML) { text.append("<").append(localName); int nAttributes = attributes.getLength(); for (int i = 0; i < nAttributes; i++) { String qname = attributes.getQName(i); String value = attributes.getValue(i); text.append(" ").append(qname).append("=\"").append(value) .append("\""); } } pendingEndElement=true; } else { Integer stateObj=null; pushState(); if (NAMESPACE_API.equals(uri)) { stateObj=(Integer)states.get(localName); if (stateObj!=null) { int state=stateObj.intValue(); switch (state) { case STATE_ABOUTME: { startCollectingText(localName,attributes); break; } case STATE_ALIAS: { Alias alias=new Alias(); this.currentObject=alias; addCollectionElement(TAG_ALIAS, alias); alias.name = attributes.getValue(ATTRIBUTE_ALAIS_NAME); alias.datatype = attributes.getValue(ATTRIBUTE_ALAIS_TYPE); break; } case STATE_ANCESTOR: { Ancestor ancestor=new Ancestor(); this.currentObject=ancestor; addCollectionElement(TAG_ANCESTOR, ancestor); ancestor.dataType = attributes.getValue(ATTRIBUTE_ANCESTOR_DATATYPE); break; } case STATE_API: { this.apis.libraryVersion = attributes.getValue(ATTRIBUTE_API_VERSION); this.apis.language = attributes.getValue(ATTRIBUTE_API_LANGUAGE); this.apis.getterPattern = attributes.getValue(ATTRIBUTE_API_GETTERPATTERN); this.apis.setterPattern = attributes.getValue(ATTRIBUTE_API_SETTERPATTERN); this.apis.setterPattern = attributes.getValue(ATTRIBUTE_API_SETTERPATTERN); this.apis.spec = attributes.getValue(ATTRIBUTE_API_SPEC); this.collections=new HashMap(); break; } case STATE_AUTHOR: { Author author=new Author(); this.currentObject=author; author.email = attributes.getValue(ATTRIBUTE_AUTHOR_EMAIL); author.location = attributes.getValue(ATTRIBUTE_AUTHOR_LOCATION); author.name = attributes.getValue(ATTRIBUTE_AUTHOR_NAME); author.organization = attributes.getValue(ATTRIBUTE_AUTHOR_ORGANIZATION); author.photo = attributes.getValue(ATTRIBUTE_AUTHOR_PHOTO); author.type = attributes.getValue(ATTRIBUTE_AUTHOR_TYPE); author.website = attributes.getValue(ATTRIBUTE_AUTHOR_WEBSITE); addCollectionElement(TAG_AUTHOR, author); break; } case STATE_AVAILABLE: { DepreciatedOrAvailable available=new DepreciatedOrAvailable(); if (this.currentObject instanceof VersionableElement) ((VersionableElement)this.currentObject).available=available; available.version = attributes.getValue(ATTRIBUTE_AVAILABLE_VERSION); startCollectingText(localName,attributes); break; } case STATE_CLASS: case STATE_INTERFACE: { ClassData clazz=new ClassData(); this.currentObject=clazz; if (STATE_INTERFACE==state) { clazz.isInterface=true; addCollectionElement(TAG_INTERFACE, clazz); } else addCollectionElement(TAG_CLASS, clazz); clazz.name = attributes.getValue(ATTRIBUTE_CLASS_NAME); clazz.superclass = attributes.getValue(ATTRIBUTE_CLASS_SUPERCLASS); clazz.visibility = attributes.getValue(ATTRIBUTE_CLASS_VISIBILITY); clazz.getterPattern = attributes.getValue(ATTRIBUTE_CLASS_GETTERPATTERN); clazz.setterPattern = attributes.getValue(ATTRIBUTE_CLASS_SETTERPATTERN); this.collections=new HashMap(); break; } case STATE_CONSTRUCTOR: case STATE_METHOD: { Method method=new Method(); if (STATE_CONSTRUCTOR==state) { method.isContructor=true; addCollectionElement(TAG_CONSTRUCTOR, method); } else addCollectionElement(TAG_METHOD, method); this.currentObject=method; method.scope = attributes.getValue(ATTRIBUTE_CONSTRUCTOR_SCOPE); method.visibility = attributes.getValue(ATTRIBUTE_CONSTRUCTOR_VISIBILITY); method.name = attributes.getValue(ATTRIBUTE_METHOD_NAME); this.collections=new HashMap(); break; } case STATE_DEPRECIATED: { DepreciatedOrAvailable depreciated=new DepreciatedOrAvailable(); if (this.currentObject instanceof VersionableElement) ((VersionableElement)this.currentObject).depreciated=depreciated; depreciated.isDepreciated=true; depreciated.version = attributes.getValue(ATTRIBUTE_DEPRECIATED_VERSION); startCollectingText(localName,attributes); break; } case STATE_DESCRIPTION: { startCollectingText(localName,attributes); break; } case STATE_ENUM: { Enum enumData =new Enum(); this.currentObject=enumData; addCollectionElement(TAG_ENUM, enumData); enumData.name = attributes.getValue(ATTRIBUTE_ENUM_NAME); enumData.datatype = attributes.getValue(ATTRIBUTE_ENUM_DATATYPE); break; } case STATE_EVENT: { Event event=new Event(); this.currentObject=event; addCollectionElement(TAG_EVENT, event); this.collections=new HashMap(); break; } case STATE_EXCEPTION: { Exception exception=new Exception(); this.currentObject=exception; addCollectionElement(TAG_EXCEPTION, exception); this.collections=new HashMap(); break; } case STATE_FIELD: case STATE_PROPERTY: { Property property=new Property(); this.currentObject=property; if (STATE_FIELD==state) { property.isField=true; addCollectionElement(TAG_FIELD, property); } else addCollectionElement(TAG_PROPERTY, property); property.name = attributes.getValue(ATTRIBUTE_FIELD_NAME); property.dataType = attributes.getValue(ATTRIBUTE_FIELD_DATATYPE); property.scope = attributes.getValue(ATTRIBUTE_FIELD_SCOPE); property.visibility = attributes.getValue(ATTRIBUTE_FIELD_VISIBILITY); this.collections=new HashMap(); break; } case STATE_INCLUDE: { String src= attributes.getValue(ATTRIBUTE_INCLUDE_SRC); handleInclude(src); break; } case STATE_MIX: { Mix mix=new Mix(); addCollectionElement(TAG_MIX, mix); this.currentObject=mix; mix.datatype = attributes.getValue(ATTRIBUTE_MIX_DATATYPE); mix.fromScope = attributes.getValue(ATTRIBUTE_MIX_FROMSCOPE); mix.toScope = attributes.getValue(ATTRIBUTE_MIX_TOSCOPE); break; } case STATE_MIXIN: { Mixin mixin=new Mixin(); addCollectionElement(TAG_MIXIN, mixin); this.currentObject=mixin; mixin.name = attributes.getValue(ATTRIBUTE_MIXIN_NAME); mixin.scope = attributes.getValue(ATTRIBUTE_MIXIN_SCOPE); mixin.visibility = attributes.getValue(ATTRIBUTE_MIXIN_VISIBILITY); break; } case STATE_NAMESPACE: { Namespace namespace=new Namespace(); addCollectionElement(TAG_NAMESPACE, namespace); this.currentObject=namespace; namespace.name = attributes.getValue(ATTRIBUTE_NAMESPACE_NAME); namespace.visibility = attributes.getValue(ATTRIBUTE_NAMESPACE_VISIBILITY); break; } case STATE_PARAMETER: { Parameter parameter=new Parameter(); this.currentObject=parameter; addCollectionElement(TAG_PARAMETER, parameter); parameter.name = attributes.getValue(ATTRIBUTE_PARAMETER_NAME); parameter.dataType = attributes.getValue(ATTRIBUTE_PARAMETER_DATATYPE); parameter.usage = attributes.getValue(ATTRIBUTE_PARAMETER_USAGE); this.collections=new HashMap(); break; } case STATE_QOUTE: { startCollectingText(localName,attributes); break; } case STATE_RETURNS: { ReturnsData returnData =new ReturnsData(); if (this.currentObject instanceof Method) ((Method)this.currentObject).returns=returnData; else if (this.currentObject instanceof Event) ((Event)this.currentObject).returns=returnData; else if (this.currentObject instanceof Exception) ((Exception)this.currentObject).returns=returnData; this.currentObject=returnData; returnData.dataType = attributes.getValue(ATTRIBUTE_RETURNS_DATATYPE); break; } } this.currentState=state; } } } } private void startCollectingText(String localName,Attributes attributes) { this.collectText=true; this.collectTextElement=localName; this.collectHTML=MIME_TYPE_HTML.equals(attributes.getValue(ATTRIBUTE_DESCRIPTION_TYPE)); this.text=new StringBuffer(); } private void addCollectionElement(String tagClass,Object element) { if (this.collections==null) this.collections=new HashMap(); ArrayList list = (ArrayList)this.collections.get(tagClass); if (list==null) { this.collections.put(tagClass, list=new ArrayList()); } list.add(element); } private ArrayList getCollection(String tagClass) { ArrayList list = (ArrayList)this.collections.get(tagClass); if (list==null) list=EMPTY_LIST; return list; } private void popState() { StackElement stackElement=(StackElement)stack.pop(); this.currentState=stackElement.state; this.collections=stackElement.collections; this.currentObject=stackElement.currentObject; } private void pushState() { StackElement newElement=new StackElement(this.currentState,this.currentObject, this.collections); stack.push(newElement); } private String localizedString(String string) { if (!this.doTranslation) return string; int subLength=VARIABLE_SUBSTITUTION_STRING.length(); int index=string.indexOf(VARIABLE_SUBSTITUTION_STRING); if (index<0) return string; StringBuffer text=new StringBuffer(); int start=0; while (index>=0) { text.append(string.substring(start, index)); start=index+subLength; index=string.indexOf(VARIABLE_SUBSTITUTION_STRING,start); if (index<0) { text.append(string.substring(start-subLength)); break; } String key=string.substring(start,index); String value=(String)this.messages.get(key); String replace=(value!=null)? value : VARIABLE_SUBSTITUTION_STRING+key+VARIABLE_SUBSTITUTION_STRING; text.append(replace); start=index+subLength; index=string.indexOf(VARIABLE_SUBSTITUTION_STRING,start); } return text.toString(); } private void handleInclude(String src) { IPath basePath = new Path(this.filePath); Path srcPath= new Path (src); basePath=basePath.removeLastSegments(1); basePath=basePath.append(srcPath); String fileName = basePath.toOSString(); String savePath=this.filePath; try { FileInputStream file = new FileInputStream(fileName); this.filePath=fileName; parseMetadata( new InputSource(file),this); } catch (FileNotFoundException e) { Util.log(e, "error reading oaametadata"); } this.filePath=savePath; } private void loadMessageBundle() { class MessageBundleHandler extends DefaultHandler { String currentID; StringBuffer text; public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { if (TAG_MSG.equals(localName)) { currentID = attributes.getValue(ATTRIBUTE_MSG_NAME); if (currentID!=null && currentID.length()>0) text=new StringBuffer(); else currentID=null; } } public void endElement(String uri, String localName, String name) throws SAXException { if (currentID!=null) { messages.put(currentID, text.toString()); } currentID=null; text=null; } public void characters(char[] ch, int start, int length) throws SAXException { if (currentID!=null && text!=null) { text.append(ch,start,length); } } } final String[] variants = buildVariants(); for (int i = 0; i < variants.length; i++) { // loader==null if we're launched off the Java boot classpath File file = new File(variants[i]); if (!file.exists()) continue; try { InputSource inputSource = new InputSource(new FileReader(file)); } catch (FileNotFoundException e) { Util.log(e, "error reading oaametadata"); } } } private static final String EXTENSION = ".xml"; //$NON-NLS-1$ private static final String ALL = "ALL"; //$NON-NLS-1$ private static String[] nlSuffixes; private static String[] buildVariants() { if (nlSuffixes == null) { //build list of suffixes for loading resource bundles String nl = Locale.getDefault().toString(); ArrayList result = new ArrayList(4); int lastSeparator; String defaultStr=""; while (true) { result.add( nl +defaultStr+ EXTENSION); lastSeparator = nl.lastIndexOf('_'); if (lastSeparator == -1) break; defaultStr="_"+ALL; nl = nl.substring(0, lastSeparator); } //add the empty suffix last (most general) result.add(ALL+"_"+ALL+EXTENSION); nlSuffixes = (String[]) result.toArray(new String[result.size()]); } String[] variants = new String[nlSuffixes.length]; for (int i = 0; i < variants.length; i++) variants[i] = nlSuffixes[i]; return variants; } }