1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-15 04:55:22 +02:00

[246406] Thread-safe support for Lazy Loading

This commit is contained in:
Martin Oberhuber 2008-09-29 18:41:11 +00:00
parent bca7723a18
commit bae435497e
9 changed files with 367 additions and 199 deletions

View file

@ -405,7 +405,7 @@
</category-def> </category-def>
<!-- END_3_0_1 --> <!-- END_3_0_1 -->
<!-- BEGIN_3_1 --> <!-- BEGIN_3_1 -->
<feature url="features/org.eclipse.rse.core_3.0.100.qualifier.jar" id="org.eclipse.rse.core" version="3.0.100.qualifier"> <feature url="features/org.eclipse.rse.core_3.1.0.qualifier.jar" id="org.eclipse.rse.core" version="3.1.0.qualifier">
<category name="TM and RSE 3.1"/> <category name="TM and RSE 3.1"/>
</feature> </feature>
<feature url="features/org.eclipse.rse.dstore_3.0.100.qualifier.jar" id="org.eclipse.rse.dstore" version="3.0.100.qualifier"> <feature url="features/org.eclipse.rse.dstore_3.0.100.qualifier.jar" id="org.eclipse.rse.dstore" version="3.0.100.qualifier">
@ -417,10 +417,10 @@
<feature url="features/org.eclipse.rse.local_2.1.1.qualifier.jar" id="org.eclipse.rse.local" version="2.1.1.qualifier"> <feature url="features/org.eclipse.rse.local_2.1.1.qualifier.jar" id="org.eclipse.rse.local" version="2.1.1.qualifier">
<category name="TM and RSE 3.1"/> <category name="TM and RSE 3.1"/>
</feature> </feature>
<feature url="features/org.eclipse.rse_3.0.100.qualifier.jar" id="org.eclipse.rse" version="3.0.100.qualifier"> <feature url="features/org.eclipse.rse_3.1.0.qualifier.jar" id="org.eclipse.rse" version="3.1.0.qualifier">
<category name="TM and RSE 3.1"/> <category name="TM and RSE 3.1"/>
</feature> </feature>
<feature url="features/org.eclipse.rse.sdk_3.0.100.qualifier.jar" id="org.eclipse.rse.sdk" version="3.0.100.qualifier"> <feature url="features/org.eclipse.rse.sdk_3.1.0.qualifier.jar" id="org.eclipse.rse.sdk" version="3.1.0.qualifier">
<category name="TM and RSE 3.1"/> <category name="TM and RSE 3.1"/>
</feature> </feature>
<feature url="features/org.eclipse.rse.ssh_2.1.100.qualifier.jar" id="org.eclipse.rse.ssh" version="2.1.100.qualifier"> <feature url="features/org.eclipse.rse.ssh_2.1.100.qualifier.jar" id="org.eclipse.rse.ssh" version="2.1.100.qualifier">

View file

@ -2,7 +2,7 @@
<feature <feature
id="org.eclipse.rse" id="org.eclipse.rse"
label="%featureName" label="%featureName"
version="3.0.100.qualifier" version="3.1.0.qualifier"
provider-name="%providerName" provider-name="%providerName"
plugin="org.eclipse.rse" plugin="org.eclipse.rse"
image="eclipse_update_120.jpg"> image="eclipse_update_120.jpg">

View file

@ -2,7 +2,7 @@
<feature <feature
id="org.eclipse.rse.core" id="org.eclipse.rse.core"
label="%featureName" label="%featureName"
version="3.0.100.qualifier" version="3.1.0.qualifier"
provider-name="%providerName" provider-name="%providerName"
plugin="org.eclipse.rse.core"> plugin="org.eclipse.rse.core">

View file

@ -2,7 +2,7 @@
<feature <feature
id="org.eclipse.rse.sdk" id="org.eclipse.rse.sdk"
label="%featureName" label="%featureName"
version="3.0.100.qualifier" version="3.1.0.qualifier"
provider-name="%providerName" provider-name="%providerName"
image="eclipse_update_120.jpg"> image="eclipse_update_120.jpg">

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2 Bundle-ManifestVersion: 2
Bundle-Name: %pluginName Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.rse.services;singleton:=true Bundle-SymbolicName: org.eclipse.rse.services;singleton:=true
Bundle-Version: 3.0.100.qualifier Bundle-Version: 3.1.0.qualifier
Bundle-Activator: org.eclipse.rse.internal.services.Activator Bundle-Activator: org.eclipse.rse.internal.services.Activator
Bundle-Vendor: %providerName Bundle-Vendor: %providerName
Bundle-Localization: plugin Bundle-Localization: plugin

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2002, 2007 IBM Corporation and others. * Copyright (c) 2002, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,12 +7,13 @@
* *
* Initial Contributors: * Initial Contributors:
* The following IBM employees contributed to the Remote System Explorer * The following IBM employees contributed to the Remote System Explorer
* component that contains this file: David McKnight, Kushal Munir, * component that contains this file: David McKnight, Kushal Munir,
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson, * Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley. * Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
* *
* Contributors: * Contributors:
* {Name} (company) - description of contribution. * David McKnight (IBM) [246406] [performance] Timeout waiting when loading SystemPreferencesManager$ModelChangeListener during startup
* Martin Oberhuber (Wind River) - [246406] Thread-safe support for Lazy Loading
*******************************************************************************/ *******************************************************************************/
package org.eclipse.rse.services.clientserver.messages; package org.eclipse.rse.services.clientserver.messages;
@ -24,8 +25,11 @@ import java.io.InputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collections;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List;
import java.util.Vector; import java.util.Vector;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
@ -44,17 +48,20 @@ import org.xml.sax.SAXParseException;
/** /**
* Use this class to open, and parse, a RSE-style message file. * Use this class to open, and parse, a RSE-style message file.
*/ */
public class SystemMessageFile implements ErrorHandler public class SystemMessageFile implements ErrorHandler
{ {
/**
private static final LinkedList msgfList=new LinkedList(); * List<MessageFileInfo> of loaded message files to avoid double loading.
* Must be synchronized since queried from multiple Threads.
*/
private static final List msgfList = Collections.synchronizedList(new LinkedList());
private MessageFileInfo msgFile; private MessageFileInfo msgFile;
private String defaultMsgFileLocation; private String defaultMsgFileLocation;
private InputStream dtdInputStream; private InputStream dtdInputStream;
// the following is an attempt to improve response time, and reduce memory requirements, by // the following is an attempt to improve response time, and reduce memory requirements, by
// caching SystemMessage objects for previously issued messages. Phil // caching SystemMessage objects for previously issued messages. Phil
private Hashtable messages = new Hashtable(); private Hashtable messages = new Hashtable();
// XML TAG AND ELEMENT NAMES... // XML TAG AND ELEMENT NAMES...
@ -68,19 +75,24 @@ public class SystemMessageFile implements ErrorHandler
private static final String XML_ATTR_ID = "ID"; //$NON-NLS-1$ private static final String XML_ATTR_ID = "ID"; //$NON-NLS-1$
private static final String XML_ATTR_INDICATOR = "Indicator"; //$NON-NLS-1$ private static final String XML_ATTR_INDICATOR = "Indicator"; //$NON-NLS-1$
private static final String XML_ATTR_NAME = "Name"; //$NON-NLS-1$ private static final String XML_ATTR_NAME = "Name"; //$NON-NLS-1$
// when using lazy loading, this is the thread that loads the message file
private final Thread fLoadThread;
// indicates whether the lazy load thread is done
private boolean fLoadThreadFinished = false;
/** /**
* Inner class * File info node in msgfList to avoid duplicate loading.
* Thread-safe since immutable.
*/ */
private class MessageFileInfo private static class MessageFileInfo
{ {
private String filename=null; private final String filename;
private String shortName=null; private final String shortName;
private Document xmlDocument=null; private final Document xmlDocument;
public MessageFileInfo(String ucFileName, String lcFileName, Document doc) public MessageFileInfo(String ucFileName, String lcFileName, Document doc)
{ {
filename=ucFileName; filename=ucFileName;
int idx=lcFileName.lastIndexOf('\\'); int idx=lcFileName.lastIndexOf('\\');
@ -88,61 +100,159 @@ public class SystemMessageFile implements ErrorHandler
idx = lcFileName.lastIndexOf('/'); idx = lcFileName.lastIndexOf('/');
if (idx >= 0) if (idx >= 0)
shortName = lcFileName.substring(idx+1); shortName = lcFileName.substring(idx+1);
else else
shortName = lcFileName; shortName = lcFileName;
xmlDocument=doc; xmlDocument=doc;
} }
public String getMessageFullFileName() public String getMessageFullFileName()
{ {
return filename; return filename;
} }
public String getMessageShortFileName() public String getMessageShortFileName()
{ {
return shortName; return shortName;
} }
public Document getXMLDocument() public Document getXMLDocument()
{ {
return xmlDocument; return xmlDocument;
} }
} }
/** /**
* Constructor * Thread for loading a message file asynchronously.
* @param messageFileName - a key used to determine if a message file has already been loaded. *
* Usually the name of the xml file containing the message file. * Opens Streams, creates an internal message file info object holding the
* @param messageFile the stream containing the message file. * DTD, and closes Streams. In case of error, the message file info object
* @param dtdStream the stream containing the dtd for this message file. * is not set (remains <code>null</code>).
*
* As a result,
* <ul>
* <li>The {@link #msgFile} variable is set to the loaded message file info
* node if successful.</li>
* <li>The {@link #fLoadThreadFinished} is guaranteed to be set
* <code>true</code>.</li>
* <li>All waiting Threads are notified.</li>
* </ul>
*/ */
public SystemMessageFile (String messageFileName, InputStream messageFile, InputStream dtdStream) private class LoadThread extends Thread {
private URL _messageFileURL;
private URL _dtdURL;
private String _messageFileName;
public LoadThread(String messageFileName, URL messageFileURL, URL dtdURL) {
_messageFileName = messageFileName;
_messageFileURL = messageFileURL;
_dtdURL = dtdURL;
}
public void run() {
InputStream messageFile = null;
InputStream dtdFile = null;
try {
messageFile = _messageFileURL.openStream();
dtdFile = _dtdURL.openStream();
SystemMessageFile realFile = new SystemMessageFile(_messageFileName, messageFile, dtdFile);
msgFile = realFile.msgFile;
} catch (IOException e) {
// problem loading message file -- msgFile is not set.
} finally {
// Notify that work is finished before closing Streams -
// Avoid not getting this set due to a RuntimeError
synchronized (this) {
fLoadThreadFinished = true;
notifyAll();
}
if (messageFile != null) {
try {
safeClose(messageFile);
} finally {
if (dtdFile != null)
safeClose(dtdFile);
}
}
}
}
private void safeClose(InputStream s) {
try {
s.close();
} catch (IOException e) {
/* ignore */
}
}
}
/**
* Constructor to use for lazy loading of a system message file.
*
* The difference between the {@link #SystemMessageFile(String,InputStream,InputStream)}
* constructor and this one is that the former loads the message file synchronously while
* this one loads the message file in a thread. The message file and DTD URLs are passed
* in here so that the opening of their input streams can be deferred until the time when
* the worker thread is started and able to load the message file.
*
* @param messageFileName the name of the system message file
* @param msgFileURL the URL to the message file
* @param dtdURL the URL to the DTD for the message file
*
* @since 3.1
*/
public SystemMessageFile(final String messageFileName, final URL msgFileURL, final URL dtdURL)
{ {
// have we already loaded this message file? // have we already loaded this message file?
msgFile = getFromCache(messageFileName); msgFile = getFromCache(messageFileName);
if (msgFile == null){
// now, we haven't. Load it now. // will set msgFile variable and fLoadThreadFinished when done
fLoadThread = new LoadThread(messageFileName, msgFileURL, dtdURL);
fLoadThread.start();
}
else { // there's already a cached message file for this
// no need to load it, just use the msgFile
fLoadThread = null;
}
}
/**
* Constructor
* @param messageFileName - a key used to determine if a message file has already been loaded.
* Usually the name of the xml file containing the message file.
* @param messageFile the stream containing the message file.
* @param dtdStream the stream containing the dtd for this message file.
*/
public SystemMessageFile (String messageFileName, InputStream messageFile, InputStream dtdStream)
{
// have we already loaded this message file?
msgFile = getFromCache(messageFileName);
// now, we haven't. Load it now.
this.dtdInputStream = dtdStream; this.dtdInputStream = dtdStream;
if (msgFile == null) if (msgFile == null)
{ {
Document doc = loadAndParseXMLFile(messageFile); Document doc = loadAndParseXMLFile(messageFile);
msgFile=new MessageFileInfo(messageFileName.toUpperCase(), messageFileName, doc); msgFile=new MessageFileInfo(messageFileName.toUpperCase(), messageFileName, doc);
msgfList.add(msgFile); msgfList.add(msgFile);
//scanForDuplicates(); // don't keep this for production. Too expensive //scanForDuplicates(); // don't keep this for production. Too expensive
} }
fLoadThread = null;
} }
/** /**
* If the named message file has already been loaded return its * If the named message file has already been loaded return its
* MessageFileInfo * MessageFileInfo
* @param messageFileName * @param messageFileName name of the message file
* @return the MessageFileInfo for this message file * @return the MessageFileInfo for this message file
*/ */
protected MessageFileInfo getFromCache(String messageFileName) protected MessageFileInfo getFromCache(String messageFileName)
{ {
for (int i=0; i<msgfList.size(); i++) for (int i=0; i<msgfList.size(); i++)
{ {
MessageFileInfo msgf=(MessageFileInfo)msgfList.get(i); MessageFileInfo msgf=(MessageFileInfo)msgfList.get(i);
if (msgf.getMessageFullFileName().equals(messageFileName.toUpperCase())) if (msgf.getMessageFullFileName().equals(messageFileName.toUpperCase()))
{ {
return msgf; return msgf;
} }
@ -150,33 +260,57 @@ public class SystemMessageFile implements ErrorHandler
return null; return null;
} }
/**
* Waits until the message file is loaded or canceled due to error
*/
private void waitUntilLoaded() {
// fastpath: returns immediately if constructed synchronously
if (fLoadThread != null) {
// asynchronous load pending: wait until loaded or load canceled
synchronized (fLoadThread) {
while (!fLoadThreadFinished) {
try {
fLoadThread.wait();
} catch (InterruptedException e) {
// ignore since the Thread is guaranteed to finish
}
}
}
}
}
/** /**
* Use this method to retrieve a message from the message file. * Use this method to retrieve a message from the message file. If this
* @param msgId - the ID of the message to retrieve. This is the concatenation of the * SystemMessageFile loaded from a thread, then the method will wait until
* message's component abbreviation, subcomponent abbreviation, and message ID as declared * the loading is complete before returning the message.
* in the message xml file. *
* @return SystemMessage object * @param msgId - the ID of the message to retrieve. This is the
* concatenation of the message's component abbreviation,
* subcomponent abbreviation, and message ID as declared in the
* message XML file.
* @return SystemMessage the SysteMessage object that corresponds to the
* message ID
*/ */
public SystemMessage getMessage(String msgId) public SystemMessage getMessage(String msgId)
{ {
waitUntilLoaded();
boolean echoErrorsToStandardOut = true; boolean echoErrorsToStandardOut = true;
// DY Defect 42605 // DY Defect 42605
if (msgFile.getXMLDocument() == null) if (msgFile == null || msgFile.getXMLDocument() == null)
{ {
issueErrorMessage("No XML document for message file", echoErrorsToStandardOut); //$NON-NLS-1$ issueErrorMessage("No XML document for message file", echoErrorsToStandardOut);
return null; return null;
} }
// caching added by Phil to increase performance, and not to leave a trail of SystemMessage objects for // caching added by Phil to increase performance, and not to leave a trail of SystemMessage objects for
// the garbage collector. Hopefully, the extra memory for the cache does not defeat these benefits. // the garbage collector. Hopefully, the extra memory for the cache does not defeat these benefits.
SystemMessage msg = (SystemMessage)messages.get(msgFile.getMessageShortFileName()+":"+msgId); //$NON-NLS-1$ SystemMessage msg = (SystemMessage) messages.get(msgId);
if (msg != null) if (msg != null)
{ {
//System.out.println("Reusing msg " + msgId); //System.out.println("Reusing msg " + msgId);
return msg; return msg;
} }
// I guess the following line of code implies we only support a single component per message file... phil. // I guess the following line of code implies we only support a single component per message file... phil.
// Code tweaked by Phil. // Code tweaked by Phil.
//String componentAbbr=msgFile.getXMLDocument().getElementsByTagName("Component").item(0).getAttributes().getNamedItem("Abbr").getFirstChild().getNodeValue(); //String componentAbbr=msgFile.getXMLDocument().getElementsByTagName("Component").item(0).getAttributes().getNamedItem("Abbr").getFirstChild().getNodeValue();
@ -186,27 +320,27 @@ public class SystemMessageFile implements ErrorHandler
NodeList componentElementList = msgFile.getXMLDocument().getElementsByTagName(XML_TAG_COMPONENT); NodeList componentElementList = msgFile.getXMLDocument().getElementsByTagName(XML_TAG_COMPONENT);
if ((componentElementList == null) || (componentElementList.getLength() == 0)) if ((componentElementList == null) || (componentElementList.getLength() == 0))
{ {
issueErrorMessage("Unable to find any Component elements",echoErrorsToStandardOut); //$NON-NLS-1$ issueErrorMessage("Unable to find any Component elements",echoErrorsToStandardOut);
return null; return null;
} }
Element componentElement = (Element)componentElementList.item(0); Element componentElement = (Element)componentElementList.item(0);
String componentAbbr = componentElement.getAttribute(XML_ATTR_ABBR); String componentAbbr = componentElement.getAttribute(XML_ATTR_ABBR);
// get list of all Subcomponent elements... // get list of all Subcomponent elements...
NodeList subComponentList=msgFile.getXMLDocument().getElementsByTagName(XML_TAG_SUBCOMPONENT); NodeList subComponentList=msgFile.getXMLDocument().getElementsByTagName(XML_TAG_SUBCOMPONENT);
if ((subComponentList == null) || (subComponentList.getLength() == 0)) if ((subComponentList == null) || (subComponentList.getLength() == 0))
{ {
issueErrorMessage("Unable to find any Subcomponent elements",echoErrorsToStandardOut); //$NON-NLS-1$ issueErrorMessage("Unable to find any Subcomponent elements",echoErrorsToStandardOut);
return null; return null;
} }
// fold given msg ID to uppercase // fold given msg ID to uppercase
msgId = msgId.toUpperCase(); msgId = msgId.toUpperCase();
// search for the right component/subcomponent match // search for the right component/subcomponent match
for (int subComponentIdx=0; subComponentIdx<subComponentList.getLength(); subComponentIdx++) for (int subComponentIdx=0; subComponentIdx<subComponentList.getLength(); subComponentIdx++)
{ {
//String subComponentAbbr=subComponentList.item(subComponentIdx).getAttributes().getNamedItem("Abbr").getFirstChild().getNodeValue(); //String subComponentAbbr=subComponentList.item(subComponentIdx).getAttributes().getNamedItem("Abbr").getFirstChild().getNodeValue();
Element subComponentElement = (Element)subComponentList.item(subComponentIdx); Element subComponentElement = (Element)subComponentList.item(subComponentIdx);
@ -216,23 +350,23 @@ public class SystemMessageFile implements ErrorHandler
char msgIndicator=' '; char msgIndicator=' ';
String msgL1=""; //$NON-NLS-1$ String msgL1=""; //$NON-NLS-1$
String msgL2=""; //$NON-NLS-1$ String msgL2=""; //$NON-NLS-1$
// if the message prefix matches, then try to find the message // if the message prefix matches, then try to find the message
//if (msgPrefix.toUpperCase().equals(msgId.toUpperCase().substring(0,msgPrefix.length())) && //if (msgPrefix.toUpperCase().equals(msgId.toUpperCase().substring(0,msgPrefix.length())) &&
//if (msgPrefix.equals(msgId.substring(0,msgPrefix.length())) && //if (msgPrefix.equals(msgId.substring(0,msgPrefix.length())) &&
if (msgId.startsWith(msgPrefix) && if (msgId.startsWith(msgPrefix) &&
Character.isDigit(msgId.charAt(msgPrefix.length()))) Character.isDigit(msgId.charAt(msgPrefix.length())))
{ {
//String msgNumber=msgId.toUpperCase().substring(msgPrefix.length()); //String msgNumber=msgId.toUpperCase().substring(msgPrefix.length());
String msgNumber=msgId.substring(msgPrefix.length()); String msgNumber=msgId.substring(msgPrefix.length());
Element messageListNode=null; Element messageListNode=null;
// search for the message list node // search for the message list node
/* /*
for (Node node=subComponentList.item(subComponentIdx).getFirstChild(); for (Node node=subComponentList.item(subComponentIdx).getFirstChild();
node!=null; node=node.getNextSibling()) node!=null; node=node.getNextSibling())
{ {
if (node.getNodeName().equals("MessageList")) if (node.getNodeName().equals("MessageList"))
{ {
messageListNode=node; messageListNode=node;
break; break;
@ -243,17 +377,17 @@ public class SystemMessageFile implements ErrorHandler
messageListNode = (Element)msgListNodes.item(0); messageListNode = (Element)msgListNodes.item(0);
else else
{ {
issueWarningMessage("unable to find MessageList nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut); //$NON-NLS-1$ issueWarningMessage("unable to find MessageList nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut);
continue; continue;
} }
// search for the message node which has the right number // search for the message node which has the right number
//for (Node node=messageListNode.getFirstChild(); //for (Node node=messageListNode.getFirstChild();
// node!=null; node=node.getNextSibling()) // node!=null; node=node.getNextSibling())
NodeList msgNodes = messageListNode.getElementsByTagName(XML_TAG_MESSAGE); NodeList msgNodes = messageListNode.getElementsByTagName(XML_TAG_MESSAGE);
if ((msgNodes==null) || (msgNodes.getLength()==0)) if ((msgNodes==null) || (msgNodes.getLength()==0))
{ {
issueWarningMessage("unable to find Message nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut); //$NON-NLS-1$ issueWarningMessage("unable to find Message nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut);
continue; continue;
} }
boolean match = false; // I added this so we stop looping when we find what we are looking for!!! Phil. boolean match = false; // I added this so we stop looping when we find what we are looking for!!! Phil.
@ -261,8 +395,8 @@ public class SystemMessageFile implements ErrorHandler
{ {
Element node = (Element)msgNodes.item(msgIdx); Element node = (Element)msgNodes.item(msgIdx);
// if the message number matches... // if the message number matches...
//if (node.getNodeName().equals("Message") && node.getAttributes().getNamedItem("ID").getFirstChild().getNodeValue().toUpperCase().equals(msgNumber)) //if (node.getNodeName().equals("Message") && node.getAttributes().getNamedItem("ID").getFirstChild().getNodeValue().toUpperCase().equals(msgNumber))
if (node.getAttribute(XML_ATTR_ID).equals(msgNumber)) if (node.getAttribute(XML_ATTR_ID).equals(msgNumber))
{ {
match = true; match = true;
// save the indicator value // save the indicator value
@ -270,18 +404,18 @@ public class SystemMessageFile implements ErrorHandler
msgIndicator=node.getAttribute(XML_ATTR_INDICATOR).toUpperCase().charAt(0); msgIndicator=node.getAttribute(XML_ATTR_INDICATOR).toUpperCase().charAt(0);
// search for the l1 & l2 text // search for the l1 & l2 text
for (Node msgNode=node.getFirstChild(); for (Node msgNode=node.getFirstChild();
msgNode!=null; msgNode=msgNode.getNextSibling()) msgNode!=null; msgNode=msgNode.getNextSibling())
{ {
// get Level One text // get Level One text
if (msgNode.getNodeName().equals(XML_TAG_LEVELONE)) if (msgNode.getNodeName().equals(XML_TAG_LEVELONE))
msgL1 = getNodeText(msgNode); msgL1 = getNodeText(msgNode);
// get Level Two text // get Level Two text
else if (msgNode.getNodeName().equals(XML_TAG_LEVELTWO)) else if (msgNode.getNodeName().equals(XML_TAG_LEVELTWO))
msgL2 = getNodeText(msgNode); msgL2 = getNodeText(msgNode);
} }
break; break;
} }
} }
if (!match) if (!match)
{ {
/** TODO - DKM move this somewhere else since system message now needs to be eclipse independent /** TODO - DKM move this somewhere else since system message now needs to be eclipse independent
@ -289,24 +423,15 @@ public class SystemMessageFile implements ErrorHandler
*/ */
return null; return null;
} }
try
{ msg = loadSystemMessage(componentAbbr, subComponentAbbr, msgNumber, msgIndicator, msgL1, msgL2);
msg = loadSystemMessage(componentAbbr, subComponentAbbr, msgNumber, msgIndicator, msgL1, msgL2); messages.put(msgId, msg); // add to cache so we find it immediately next time!!
messages.put(msgFile.getMessageShortFileName()+":"+msgId, msg); // add to cache so we find it immediately next time!! //$NON-NLS-1$ return msg;
return msg;
}
catch (IndicatorException e)
{
/** TODO - DKM move this somewhere else since system message now needs to be eclipse independent
SystemBasePlugin.logError("MessageFile:getMessage: "+e.toString(), e);
*/
}
break;
} }
} }
return null; return null;
} }
/** /**
* Override this to provide different extended SystemMessage implementation * Override this to provide different extended SystemMessage implementation
* @param componentAbbr a three letter component name * @param componentAbbr a three letter component name
@ -316,15 +441,14 @@ public class SystemMessageFile implements ErrorHandler
* @param msgL1 the first level text that describes the error * @param msgL1 the first level text that describes the error
* @param msgL2 the second level text that provides details about the error and possible recovery * @param msgL2 the second level text that provides details about the error and possible recovery
* @return the SystemMessage * @return the SystemMessage
* @throws IndicatorException if the message type indicator is invalid.
* @see SystemMessage for message type indicator constants * @see SystemMessage for message type indicator constants
*/ */
protected SystemMessage loadSystemMessage(String componentAbbr, String subComponentAbbr, String msgNumber, char msgIndicator, protected SystemMessage loadSystemMessage(String componentAbbr, String subComponentAbbr, String msgNumber, char msgIndicator,
String msgL1, String msgL2) throws IndicatorException String msgL1, String msgL2)
{ {
return new SystemMessage(componentAbbr, subComponentAbbr, msgNumber, msgIndicator, msgL1, msgL2); return new SystemMessage(componentAbbr, subComponentAbbr, msgNumber, msgIndicator, msgL1, msgL2);
} }
/** /**
* Get the level one text * Get the level one text
*/ */
@ -332,11 +456,11 @@ public class SystemMessageFile implements ErrorHandler
{ {
String nodeText = ""; //$NON-NLS-1$ String nodeText = ""; //$NON-NLS-1$
for (Node textNode=msgNode.getFirstChild(); for (Node textNode=msgNode.getFirstChild();
textNode!=null; textNode=textNode.getNextSibling()) textNode!=null; textNode=textNode.getNextSibling())
{ {
if ((textNode.getNodeType()==Node.TEXT_NODE) && (textNode.getNodeValue().trim().length()>0)) if ((textNode.getNodeType()==Node.TEXT_NODE) && (textNode.getNodeValue().trim().length()>0))
nodeText += textNode.getNodeValue(); nodeText += textNode.getNodeValue();
} }
return nodeText.trim(); return nodeText.trim();
} }
@ -346,50 +470,51 @@ public class SystemMessageFile implements ErrorHandler
* log file. * log file.
* @return true if duplicates found. * @return true if duplicates found.
*/ */
public boolean scanForDuplicates() public boolean scanForDuplicates()
{ {
boolean echoErrorsToStandardOut = true; boolean echoErrorsToStandardOut = true;
if (msgFile.getXMLDocument() == null) waitUntilLoaded();
return issueErrorMessage("No XML document for message file", echoErrorsToStandardOut); //$NON-NLS-1$ if (msgFile == null || msgFile.getXMLDocument() == null)
return issueErrorMessage("No XML document for message file", echoErrorsToStandardOut);
// parse out the Abbr attr of the first Component element // parse out the Abbr attr of the first Component element
NodeList componentElementList = msgFile.getXMLDocument().getElementsByTagName(XML_TAG_COMPONENT); NodeList componentElementList = msgFile.getXMLDocument().getElementsByTagName(XML_TAG_COMPONENT);
if ((componentElementList == null) || (componentElementList.getLength() == 0)) if ((componentElementList == null) || (componentElementList.getLength() == 0))
return issueErrorMessage("Unable to find any Component elements",echoErrorsToStandardOut); //$NON-NLS-1$ return issueErrorMessage("Unable to find any Component elements",echoErrorsToStandardOut);
Element componentElement = (Element)componentElementList.item(0); Element componentElement = (Element)componentElementList.item(0);
String componentAbbr = componentElement.getAttribute(XML_ATTR_ABBR); String componentAbbr = componentElement.getAttribute(XML_ATTR_ABBR);
// get list of all Subcomponent elements... // get list of all Subcomponent elements...
NodeList subComponentList=msgFile.getXMLDocument().getElementsByTagName(XML_TAG_SUBCOMPONENT); NodeList subComponentList=msgFile.getXMLDocument().getElementsByTagName(XML_TAG_SUBCOMPONENT);
if ((subComponentList == null) || (subComponentList.getLength() == 0)) if ((subComponentList == null) || (subComponentList.getLength() == 0))
return issueErrorMessage("Unable to find any Subcomponent elements",echoErrorsToStandardOut); //$NON-NLS-1$ return issueErrorMessage("Unable to find any Subcomponent elements",echoErrorsToStandardOut);
// scan all subcomponents... // scan all subcomponents...
boolean anyDupes = false; boolean anyDupes = false;
for (int subComponentIdx=0; subComponentIdx<subComponentList.getLength(); subComponentIdx++) for (int subComponentIdx=0; subComponentIdx<subComponentList.getLength(); subComponentIdx++)
{ {
Element subComponentElement = (Element)subComponentList.item(subComponentIdx); Element subComponentElement = (Element)subComponentList.item(subComponentIdx);
String subComponentAbbr = subComponentElement.getAttribute(XML_ATTR_ABBR); String subComponentAbbr = subComponentElement.getAttribute(XML_ATTR_ABBR);
String msgPrefix = (componentAbbr + subComponentAbbr).toUpperCase(); String msgPrefix = (componentAbbr + subComponentAbbr).toUpperCase();
Vector msgsById = new Vector(); Vector msgsById = new Vector();
// search for the message list node // search for the message list node
Element messageListNode=null; Element messageListNode=null;
NodeList msgListNodes = subComponentElement.getElementsByTagName(XML_TAG_MESSAGeList); NodeList msgListNodes = subComponentElement.getElementsByTagName(XML_TAG_MESSAGeList);
if ((msgListNodes!=null) && (msgListNodes.getLength()>0)) if ((msgListNodes!=null) && (msgListNodes.getLength()>0))
messageListNode = (Element)msgListNodes.item(0); messageListNode = (Element)msgListNodes.item(0);
else else
{ {
issueWarningMessage("unable to find MessageList nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut); //$NON-NLS-1$ issueWarningMessage("unable to find MessageList nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut);
continue; continue;
} }
NodeList msgNodes = messageListNode.getElementsByTagName(XML_TAG_MESSAGE); NodeList msgNodes = messageListNode.getElementsByTagName(XML_TAG_MESSAGE);
if ((msgNodes==null) || (msgNodes.getLength()==0)) if ((msgNodes==null) || (msgNodes.getLength()==0))
{ {
issueWarningMessage("unable to find Message nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut); //$NON-NLS-1$ issueWarningMessage("unable to find Message nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut);
continue; continue;
} }
for (int msgIdx = 0; (msgIdx < msgNodes.getLength()); msgIdx++) for (int msgIdx = 0; (msgIdx < msgNodes.getLength()); msgIdx++)
@ -399,7 +524,7 @@ public class SystemMessageFile implements ErrorHandler
if (msgsById.contains(msgId)) if (msgsById.contains(msgId))
{ {
anyDupes = true; anyDupes = true;
issueWarningMessage("Warning: duplicate message " + msgId + " found", echoErrorsToStandardOut); //$NON-NLS-1$ //$NON-NLS-2$ issueWarningMessage("Warning: duplicate message " + msgId + " found", echoErrorsToStandardOut);
} }
else else
msgsById.addElement(msgId); msgsById.addElement(msgId);
@ -414,25 +539,26 @@ public class SystemMessageFile implements ErrorHandler
* @param fullFileName - the fully qualified name of the file to write to. Overwrites current contents. * @param fullFileName - the fully qualified name of the file to write to. Overwrites current contents.
* @return true if it went well, false if it failed for some reason, such as given a bad file name. Errors written to standard out. * @return true if it went well, false if it failed for some reason, such as given a bad file name. Errors written to standard out.
*/ */
public boolean printHTML(String fullFileName) public boolean printHTML(String fullFileName)
{ {
boolean echoErrorsToStandardOut = true; boolean echoErrorsToStandardOut = true;
if (msgFile.getXMLDocument() == null) waitUntilLoaded();
return issueErrorMessage("No XML document for message file", echoErrorsToStandardOut); //$NON-NLS-1$ if (msgFile == null || msgFile.getXMLDocument() == null)
return issueErrorMessage("No XML document for message file", echoErrorsToStandardOut);
// parse out the Abbr attr of the first Component element // parse out the Abbr attr of the first Component element
NodeList componentElementList = msgFile.getXMLDocument().getElementsByTagName(XML_TAG_COMPONENT); NodeList componentElementList = msgFile.getXMLDocument().getElementsByTagName(XML_TAG_COMPONENT);
if ((componentElementList == null) || (componentElementList.getLength() == 0)) if ((componentElementList == null) || (componentElementList.getLength() == 0))
return issueErrorMessage("Unable to find any Component elements",echoErrorsToStandardOut); //$NON-NLS-1$ return issueErrorMessage("Unable to find any Component elements",echoErrorsToStandardOut);
Element componentElement = (Element)componentElementList.item(0); Element componentElement = (Element)componentElementList.item(0);
String componentAbbr = componentElement.getAttribute(XML_ATTR_ABBR); String componentAbbr = componentElement.getAttribute(XML_ATTR_ABBR);
// get list of all Subcomponent elements... // get list of all Subcomponent elements...
NodeList subComponentList=msgFile.getXMLDocument().getElementsByTagName(XML_TAG_SUBCOMPONENT); NodeList subComponentList=msgFile.getXMLDocument().getElementsByTagName(XML_TAG_SUBCOMPONENT);
if ((subComponentList == null) || (subComponentList.getLength() == 0)) if ((subComponentList == null) || (subComponentList.getLength() == 0))
return issueErrorMessage("Unable to find any Subcomponent elements",echoErrorsToStandardOut); //$NON-NLS-1$ return issueErrorMessage("Unable to find any Subcomponent elements",echoErrorsToStandardOut);
File outFile = new File(fullFileName); File outFile = new File(fullFileName);
PrintWriter outFileStream = null; PrintWriter outFileStream = null;
@ -454,11 +580,11 @@ public class SystemMessageFile implements ErrorHandler
} }
catch (IOException exc) catch (IOException exc)
{ {
return issueErrorMessage("Unable to open given html file in printHTML: " + exc.getMessage(), echoErrorsToStandardOut); //$NON-NLS-1$ return issueErrorMessage("Unable to open given html file in printHTML: " + exc.getMessage(), echoErrorsToStandardOut);
} }
// pre-scan all subcomponents... // pre-scan all subcomponents...
for (int subComponentIdx=0; subComponentIdx<subComponentList.getLength(); subComponentIdx++) for (int subComponentIdx=0; subComponentIdx<subComponentList.getLength(); subComponentIdx++)
{ {
Element subComponentElement = (Element)subComponentList.item(subComponentIdx); Element subComponentElement = (Element)subComponentList.item(subComponentIdx);
String subComponentAbbr = subComponentElement.getAttribute(XML_ATTR_ABBR); String subComponentAbbr = subComponentElement.getAttribute(XML_ATTR_ABBR);
@ -473,27 +599,27 @@ public class SystemMessageFile implements ErrorHandler
outFileStream.println("</TABLE>"); //$NON-NLS-1$ outFileStream.println("</TABLE>"); //$NON-NLS-1$
// scan all subcomponents... // scan all subcomponents...
for (int subComponentIdx=0; subComponentIdx<subComponentList.getLength(); subComponentIdx++) for (int subComponentIdx=0; subComponentIdx<subComponentList.getLength(); subComponentIdx++)
{ {
Element subComponentElement = (Element)subComponentList.item(subComponentIdx); Element subComponentElement = (Element)subComponentList.item(subComponentIdx);
String subComponentAbbr = subComponentElement.getAttribute(XML_ATTR_ABBR); String subComponentAbbr = subComponentElement.getAttribute(XML_ATTR_ABBR);
String msgPrefix = (componentAbbr + subComponentAbbr).toUpperCase(); String msgPrefix = (componentAbbr + subComponentAbbr).toUpperCase();
// search for the message list node // search for the message list node
Element messageListNode=null; Element messageListNode=null;
NodeList msgListNodes = subComponentElement.getElementsByTagName(XML_TAG_MESSAGeList); NodeList msgListNodes = subComponentElement.getElementsByTagName(XML_TAG_MESSAGeList);
if ((msgListNodes!=null) && (msgListNodes.getLength()>0)) if ((msgListNodes!=null) && (msgListNodes.getLength()>0))
messageListNode = (Element)msgListNodes.item(0); messageListNode = (Element)msgListNodes.item(0);
else else
{ {
issueWarningMessage("unable to find MessageList nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut); //$NON-NLS-1$ issueWarningMessage("unable to find MessageList nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut);
continue; continue;
} }
NodeList msgNodes = messageListNode.getElementsByTagName(XML_TAG_MESSAGE); NodeList msgNodes = messageListNode.getElementsByTagName(XML_TAG_MESSAGE);
if ((msgNodes==null) || (msgNodes.getLength()==0)) if ((msgNodes==null) || (msgNodes.getLength()==0))
{ {
issueWarningMessage("unable to find Message nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut); //$NON-NLS-1$ issueWarningMessage("unable to find Message nodes for subComponent " + subComponentElement.getAttribute(XML_ATTR_NAME),echoErrorsToStandardOut);
continue; continue;
} }
if (subComponentIdx > 0) if (subComponentIdx > 0)
@ -504,32 +630,32 @@ public class SystemMessageFile implements ErrorHandler
{ {
Element node = (Element)msgNodes.item(msgIdx); Element node = (Element)msgNodes.item(msgIdx);
String msgId = msgPrefix + node.getAttribute(XML_ATTR_ID); String msgId = msgPrefix + node.getAttribute(XML_ATTR_ID);
char msgIndicator=node.getAttribute(XML_ATTR_INDICATOR).toUpperCase().charAt(0); char msgIndicator=node.getAttribute(XML_ATTR_INDICATOR).toUpperCase().charAt(0);
String msgSeverity = "Unknown"; //$NON-NLS-1$ String msgSeverity = "Unknown"; //$NON-NLS-1$
if (msgIndicator == SystemMessage.ERROR) if (msgIndicator == SystemMessage.ERROR)
msgSeverity = "Error"; //$NON-NLS-1$ msgSeverity = "Error";
else if (msgIndicator == SystemMessage.WARNING) else if (msgIndicator == SystemMessage.WARNING)
msgSeverity = "Warning"; //$NON-NLS-1$ msgSeverity = "Warning";
else if (msgIndicator == SystemMessage.INQUIRY) else if (msgIndicator == SystemMessage.INQUIRY)
msgSeverity = "Question"; //$NON-NLS-1$ msgSeverity = "Question";
else if (msgIndicator == SystemMessage.INFORMATION) else if (msgIndicator == SystemMessage.INFORMATION)
msgSeverity = "Information"; //$NON-NLS-1$ msgSeverity = "Information";
else if (msgIndicator == SystemMessage.COMPLETION) else if (msgIndicator == SystemMessage.COMPLETION)
msgSeverity = "Completion"; //$NON-NLS-1$ msgSeverity = "Completion";
else if (msgIndicator == SystemMessage.UNEXPECTED) else if (msgIndicator == SystemMessage.UNEXPECTED)
msgSeverity = "Unexpected"; //$NON-NLS-1$ msgSeverity = "Unexpected";
String msgL1 = ""; //$NON-NLS-1$ String msgL1 = ""; //$NON-NLS-1$
String msgL2 = ""; //$NON-NLS-1$ String msgL2 = ""; //$NON-NLS-1$
// search for the l1 & l2 text // search for the l1 & l2 text
for (Node msgNode=node.getFirstChild(); for (Node msgNode=node.getFirstChild();
msgNode!=null; msgNode=msgNode.getNextSibling()) msgNode!=null; msgNode=msgNode.getNextSibling())
{ {
// get Level One text // get Level One text
if (msgNode.getNodeName().equals(XML_TAG_LEVELONE)) if (msgNode.getNodeName().equals(XML_TAG_LEVELONE))
msgL1 = getNodeText(msgNode); msgL1 = getNodeText(msgNode);
// get Level Two text // get Level Two text
else if (msgNode.getNodeName().equals(XML_TAG_LEVELTWO)) else if (msgNode.getNodeName().equals(XML_TAG_LEVELTWO))
msgL2 = getNodeText(msgNode); msgL2 = getNodeText(msgNode);
} }
outFileStream.println("<H3>"+msgId+"</H3>"); //$NON-NLS-1$ //$NON-NLS-2$ outFileStream.println("<H3>"+msgId+"</H3>"); //$NON-NLS-1$ //$NON-NLS-2$
@ -543,19 +669,19 @@ public class SystemMessageFile implements ErrorHandler
outFileStream.close(); outFileStream.close();
return true; return true;
} }
/** /**
* Issue an error message * Issue an error message
*/ */
private boolean issueErrorMessage(String errormsg, boolean echoStandardOut) private boolean issueErrorMessage(String errormsg, boolean echoStandardOut)
{ {
/** TODO - DKM move this somewhere else since system message now needs to be eclipse independent /** TODO - DKM move this somewhere else since system message now needs to be eclipse independent
* *
SystemBasePlugin.logError("MessageFile error for msg file " + msgFile.getMessageShortFileName() + ": " + errormsg); SystemBasePlugin.logError("MessageFile error for msg file " + msgFile.getMessageShortFileName() + ": " + errormsg);
**/ **/
if (echoStandardOut) if (echoStandardOut)
System.out.println("MessageFile error for msg file " + msgFile.getMessageShortFileName() + ": " + errormsg); //$NON-NLS-1$ //$NON-NLS-2$ System.out.println("MessageFile error for msg file " + msgFile.getMessageShortFileName() + ": " + errormsg);
return false; return false;
} }
/** /**
@ -564,13 +690,13 @@ public class SystemMessageFile implements ErrorHandler
private boolean issueWarningMessage(String errormsg, boolean echoStandardOut) private boolean issueWarningMessage(String errormsg, boolean echoStandardOut)
{ {
/** TODO - DKM move this somewhere else since system message now needs to be eclipse independent /** TODO - DKM move this somewhere else since system message now needs to be eclipse independent
SystemBasePlugin.logError("MessageFile warning for msg file " + msgFile.getMessageShortFileName() + ": " + errormsg); SystemBasePlugin.logError("MessageFile warning for msg file " + msgFile.getMessageShortFileName() + ": " + errormsg);
*/ */
if (echoStandardOut) if (echoStandardOut)
System.out.println("MessageFile warning for msg file " + msgFile.getMessageShortFileName() + ": " + errormsg); //$NON-NLS-1$ //$NON-NLS-2$ System.out.println("MessageFile warning for msg file " + msgFile.getMessageShortFileName() + ": " + errormsg);
return false; return false;
} }
/** /**
* Create the XML parser * Create the XML parser
* Set its entity resolver and error handler. * Set its entity resolver and error handler.
@ -591,11 +717,11 @@ public class SystemMessageFile implements ErrorHandler
return null; return null;
} }
// DOMParser parser=new DOMParser(); // DOMParser parser=new DOMParser();
// try // try
// { // {
// parser.setFeature( "http://xml.org/sax/features/validation", true); // parser.setFeature( "http://xml.org/sax/features/validation", true);
// } // }
// catch (SAXNotRecognizedException e) // catch (SAXNotRecognizedException e)
// { // {
// // the feature was not recognized // // the feature was not recognized
// /** TODO - DKM move this somewhere else since system message now needs to be eclipse independent // /** TODO - DKM move this somewhere else since system message now needs to be eclipse independent
@ -603,7 +729,7 @@ public class SystemMessageFile implements ErrorHandler
// */ // */
// return null; // return null;
// } // }
// catch (SAXNotSupportedException e) // catch (SAXNotSupportedException e)
// { // {
// // the feature requested was not supported // // the feature requested was not supported
// /** TODO - DKM move this somewhere else since system message now needs to be eclipse independent // /** TODO - DKM move this somewhere else since system message now needs to be eclipse independent
@ -612,15 +738,15 @@ public class SystemMessageFile implements ErrorHandler
// return null; // return null;
// } // }
parser.setEntityResolver(new EntityResolver() { parser.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, java.io.IOException public InputSource resolveEntity(String publicId, String systemId) throws SAXException, java.io.IOException
{ {
/* /*
// This code does not work with fragments // This code does not work with fragments
Path path = new Path(systemId); Path path = new Path(systemId);
if (systemId.toUpperCase().endsWith("MESSAGEFILE.DTD")) if (systemId.toUpperCase().endsWith("MESSAGEFILE.DTD"))
{ {
if (SystemPlugin.getBaseDefault().getDescriptor().find(path)==null) if (SystemPlugin.getBaseDefault().getDescriptor().find(path)==null)
{ {
path = new Path("messageFile.dtd"); path = new Path("messageFile.dtd");
} }
} }
@ -630,7 +756,7 @@ public class SystemMessageFile implements ErrorHandler
if (dtdInputStream != null) if (dtdInputStream != null)
{ {
return new InputSource(dtdInputStream); return new InputSource(dtdInputStream);
} }
else // if we have the directory containing the DTD use that else // if we have the directory containing the DTD use that
{ {
// yantzi:artemis6.2 changed to use URI instead of URL (URIs handle the spaces) // yantzi:artemis6.2 changed to use URI instead of URL (URIs handle the spaces)
@ -650,66 +776,66 @@ public class SystemMessageFile implements ErrorHandler
{ {
// ignore and continue // ignore and continue
} }
return new InputSource(systemId); return new InputSource(systemId);
} }
} }
}); });
parser.setErrorHandler(this); parser.setErrorHandler(this);
return parser; return parser;
} }
/** /**
* loadAndParseXMLFile: * loadAndParseXMLFile:
* tries to load and parse the specified XML file . * tries to load and parse the specified XML file .
* @param String messageFile: InputStream containing the XML file * @param String messageFile: InputStream containing the XML file
*/ */
private Document loadAndParseXMLFile (InputStream messageFile) private Document loadAndParseXMLFile (InputStream messageFile)
{ {
DocumentBuilder parser = createXmlParser(); DocumentBuilder parser = createXmlParser();
try try
{ {
InputSource in = new InputSource(messageFile); InputSource in = new InputSource(messageFile);
// DKM - hack! // DKM - hack!
// If systemId is null for the InputSource, then // If systemId is null for the InputSource, then
// the current parser hits a fatal exception. // the current parser hits a fatal exception.
// This hack prevents that exception so that the // This hack prevents that exception so that the
// specified EntityResolver will get used. // specified EntityResolver will get used.
in.setSystemId("foo"); //$NON-NLS-1$ in.setSystemId("foo"); //$NON-NLS-1$
Document document = parser.parse(in); Document document = parser.parse(in);
//Document document = parser.parse(messageFile); //Document document = parser.parse(messageFile);
return document; return document;
} }
catch (SAXException e) catch (SAXException e)
{ {
e.printStackTrace(); e.printStackTrace();
// the parser was unable to parse the file. // the parser was unable to parse the file.
return null; return null;
} }
catch (IOException e) catch (IOException e)
{ {
e.printStackTrace(); e.printStackTrace();
/** TODO - DKM move this somewhere else since system message now needs to be eclipse independent /** TODO - DKM move this somewhere else since system message now needs to be eclipse independent
*/ */
return null; return null;
} }
} }
/** /**
* XML Parser-required method: XML-parser warning. * XML Parser-required method: XML-parser warning.
*/ */
public void warning(SAXParseException ex) public void warning(SAXParseException ex)
{ {
/** TODO - DKM move this somewhere else since system message now needs to be eclipse independent /** TODO - DKM move this somewhere else since system message now needs to be eclipse independent
SystemBasePlugin.logError("SystemMessageFile: warning parsing message file: "+ex.toString()); SystemBasePlugin.logError("SystemMessageFile: warning parsing message file: "+ex.toString());
*/ */
} }
/** /**
* XML Parser-required method: XML-parser Error. * XML Parser-required method: XML-parser Error.
*/ */
public void error(SAXParseException ex) public void error(SAXParseException ex)
{ {
/** TODO - DKM move this somewhere else since system message now needs to be eclipse independent /** TODO - DKM move this somewhere else since system message now needs to be eclipse independent
SystemBasePlugin.logError("SystemMessageFile: Error parsing message file: "+ex.toString(), ex); SystemBasePlugin.logError("SystemMessageFile: Error parsing message file: "+ex.toString(), ex);
@ -724,15 +850,15 @@ public class SystemMessageFile implements ErrorHandler
*/ */
} }
/** /**
* XML Parser-required method: XML-parser Fatal error. * XML Parser-required method: XML-parser Fatal error.
*/ */
public void fatalError(SAXParseException ex) throws SAXException public void fatalError(SAXParseException ex) throws SAXException
{ {
/** TODO - DKM move this somewhere else since system message now needs to be eclipse independent /** TODO - DKM move this somewhere else since system message now needs to be eclipse independent
SystemBasePlugin.logError("SystemMessageFile: Fatal Error parsing message file: "+ex.toString(), ex); SystemBasePlugin.logError("SystemMessageFile: Fatal Error parsing message file: "+ex.toString(), ex);
*/ */
throw(ex); throw(ex);
} }
} }

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2 Bundle-ManifestVersion: 2
Bundle-Name: %pluginName Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.rse.ui;singleton:=true Bundle-SymbolicName: org.eclipse.rse.ui;singleton:=true
Bundle-Version: 3.0.100.qualifier Bundle-Version: 3.1.0.qualifier
Bundle-Activator: org.eclipse.rse.ui.RSEUIPlugin Bundle-Activator: org.eclipse.rse.ui.RSEUIPlugin
Bundle-Localization: plugin Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime, Require-Bundle: org.eclipse.core.runtime,
@ -14,7 +14,7 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.ui.ide, org.eclipse.ui.ide,
org.eclipse.ui.views, org.eclipse.ui.views,
org.eclipse.ui.workbench.texteditor, org.eclipse.ui.workbench.texteditor,
org.eclipse.rse.services;bundle-version="[3.0.0,4.0.0)", org.eclipse.rse.services;bundle-version="[3.1.0,4.0.0)",
org.eclipse.rse.core;bundle-version="[3.0.0,4.0.0)" org.eclipse.rse.core;bundle-version="[3.0.0,4.0.0)"
Import-Package: com.ibm.icu.lang, Import-Package: com.ibm.icu.lang,
com.ibm.icu.text, com.ibm.icu.text,

View file

@ -15,11 +15,11 @@
* Martin Oberhuber (Wind River) - [168870] refactor org.eclipse.rse.core package of the UI plugin * Martin Oberhuber (Wind River) - [168870] refactor org.eclipse.rse.core package of the UI plugin
* David McKnight (IBM) - [243263] NPE on expanding a filter * David McKnight (IBM) - [243263] NPE on expanding a filter
* David McKnight (IBM) - [244454] SystemBasePlugin.getWorkBench() incorrectly returns null when called during Eclipse startup * David McKnight (IBM) - [244454] SystemBasePlugin.getWorkBench() incorrectly returns null when called during Eclipse startup
* David McKnight (IBM) [246406] [performance] Timeout waiting when loading SystemPreferencesManager$ModelChangeListener during startup
********************************************************************************/ ********************************************************************************/
package org.eclipse.rse.ui; package org.eclipse.rse.ui;
import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Locale; import java.util.Locale;
@ -302,9 +302,7 @@ public abstract class SystemBasePlugin extends AbstractUIPlugin
try { try {
URL url = resolveBundleNameNL(bundle, fileName); URL url = resolveBundleNameNL(bundle, fileName);
if (url != null) { if (url != null) {
InputStream messageFileStream = url.openStream(); mf = SystemUIMessageFile.getMessageFile(fileName, url);
mf = SystemUIMessageFile.getMessageFile(fileName, messageFileStream);
messageFileStream.close();
ok = true; ok = true;
} }
} catch (Throwable t) { } catch (Throwable t) {
@ -345,10 +343,8 @@ public abstract class SystemBasePlugin extends AbstractUIPlugin
boolean ok = false; boolean ok = false;
try { try {
URL url = bundle.getEntry("/"+fileName); //$NON-NLS-1$ URL url = bundle.getEntry("/"+fileName); //$NON-NLS-1$
if (url != null) { if (url != null) {
InputStream messageFileStream = url.openStream(); mf = SystemUIMessageFile.getMessageFile(fileName, url);
mf = SystemUIMessageFile.getMessageFile(fileName, messageFileStream);
messageFileStream.close();
ok = true; ok = true;
} }
} catch (Throwable t) { } catch (Throwable t) {

View file

@ -1,5 +1,5 @@
/******************************************************************************** /********************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and others. All rights reserved. * Copyright (c) 2004, 2008 IBM Corporation and others. All rights reserved.
* This program and the accompanying materials are made available under the terms * 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 * of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html * available at http://www.eclipse.org/legal/epl-v10.html
@ -12,6 +12,7 @@
* *
* Contributors: * Contributors:
* Martin Oberhuber (Wind River) - [168870] refactor org.eclipse.rse.core package of the UI plugin * Martin Oberhuber (Wind River) - [168870] refactor org.eclipse.rse.core package of the UI plugin
* David McKnight (IBM) [246406] [performance] Timeout waiting when loading SystemPreferencesManager$ModelChangeListener during startup
********************************************************************************/ ********************************************************************************/
package org.eclipse.rse.ui.messages; package org.eclipse.rse.ui.messages;
@ -33,8 +34,8 @@ import org.eclipse.rse.ui.SystemBasePlugin;
public class SystemUIMessageFile extends SystemMessageFile { public class SystemUIMessageFile extends SystemMessageFile {
/** /**
* Factory method for constructing a SystemUIMessageFile. If an error occurs when * Factory method for constructing a SystemUIMessageFile that loads the message file synchronously.
* reading the message file DTD then that is logged. * If an error occurs when reading the message file DTD then that is logged.
* @param messageFileName The "registered" name of the message file. Used to determine * @param messageFileName The "registered" name of the message file. Used to determine
* if the message file has been loaded. * if the message file has been loaded.
* @param messageFileStream The stream containing the message file. It is the * @param messageFileStream The stream containing the message file. It is the
@ -59,12 +60,57 @@ public class SystemUIMessageFile extends SystemMessageFile {
} }
return result; return result;
} }
/**
* Factory method for constructing a SystemUIMessageFile that loads the message file in a thread.
*
* The difference between {@link #getMessageFile(String,InputStream)} and this method
* is that the former calls the constructor that loads the message file synchronously
* while this one loads the message file in a worker thread. The message file URL is
* passed in here so that the opening of it's input stream can be deferred until the
* time when the worker thread is started and able to load the message file.
*
* @param messageFileName The name of the message file to load.
* @param messageFileURL The URL to the message file.
* @return The message file that was constructed.
*
* @since 3.1
*/
public static SystemUIMessageFile getMessageFile(String messageFileName,
URL messageFileURL) {
SystemUIMessageFile result = null;
URL dtdURL = RSEUIPlugin.getDefault().getMessageFileDTD();
if (dtdURL != null) {
result = new SystemUIMessageFile(messageFileName,messageFileURL, dtdURL);
} else {
SystemBasePlugin.logError("Could not find mesage file DTD."); //$NON-NLS-1$
}
return result;
}
/**
* Constructor for synchronous loading of the message file.
*
* This is private because this is not to be called directly, but rather
* from {@link #getMessageFile(String, InputStream)}.
*/
private SystemUIMessageFile(String messageFileName, private SystemUIMessageFile(String messageFileName,
InputStream messageFileStream, InputStream dtdStream) { InputStream messageFileStream, InputStream dtdStream) {
super(messageFileName, messageFileStream, dtdStream); super(messageFileName, messageFileStream, dtdStream);
} }
/**
* Constructor for lazy loading of the message file.
*
* This is private because this is not to be called directly, but rather
* from {@link #getMessageFile(String, URL)}.
*/
private SystemUIMessageFile(String messageFileName,
URL messageFileURL, URL dtdURL) {
super(messageFileName, messageFileURL, dtdURL);
}
/** /**
* Override this to provide different extended SystemMessage implementation * Override this to provide different extended SystemMessage implementation
* *