diff options
-rw-r--r-- | org.eclipse.debug.ui/plugin.xml | 2 | ||||
-rw-r--r-- | org.eclipse.ui.console/plugin.xml | 2 | ||||
-rw-r--r-- | org.eclipse.ui.console/schema/consolePatternMatchListeners.exsd (renamed from org.eclipse.ui.console/schema/consolePatternMatchListener.exsd) | 246 | ||||
-rw-r--r-- | org.eclipse.ui.console/src/org/eclipse/ui/console/IConsoleConstants.java | 4 | ||||
-rw-r--r-- | org.eclipse.ui.console/src/org/eclipse/ui/console/IOConsole.java | 159 | ||||
-rw-r--r-- | org.eclipse.ui.console/src/org/eclipse/ui/console/IPatternMatchListener.java | 20 | ||||
-rw-r--r-- | org.eclipse.ui.console/src/org/eclipse/ui/internal/console/PatternMatchListener.java | 20 | ||||
-rw-r--r-- | org.eclipse.ui.console/src/org/eclipse/ui/internal/console/PatternMatchListenerExtension.java | 17 |
8 files changed, 219 insertions, 251 deletions
diff --git a/org.eclipse.debug.ui/plugin.xml b/org.eclipse.debug.ui/plugin.xml index 0c0a14ae9..760303b37 100644 --- a/org.eclipse.debug.ui/plugin.xml +++ b/org.eclipse.debug.ui/plugin.xml @@ -2126,7 +2126,7 @@ M4 = Platform-specific fourth key </rendering> </extension> <extension - point="org.eclipse.ui.console.consolePatternMatchListener"> + point="org.eclipse.ui.console.consolePatternMatchListeners"> <consolePatternMatchListener class="org.eclipse.debug.internal.ui.views.console.ConsoleLineNotifier" id="org.eclipse.debug.ui.consoleLineNotifier" diff --git a/org.eclipse.ui.console/plugin.xml b/org.eclipse.ui.console/plugin.xml index 23ccc3a38..9e6ef07ca 100644 --- a/org.eclipse.ui.console/plugin.xml +++ b/org.eclipse.ui.console/plugin.xml @@ -19,7 +19,7 @@ <import plugin="org.eclipse.core.runtime"/> <import plugin="org.eclipse.core.expressions"/> </requires> - <extension-point id="consolePatternMatchListener" name="%ConsolePatternMatchListenerName" schema="schema/consolePatternMatchListener.exsd"/> + <extension-point id="consolePatternMatchListeners" name="%ConsolePatternMatchListenerName" schema="schema/consolePatternMatchListeners.exsd"/> <extension-point id="consolePageParticipant" name="%ConsolePageParticipantName" schema="schema/consolePageParticipant.exsd"/> <extension-point id="consoleFactory" name="%ConsoleFactoryName" schema="schema/consoleFactory.exsd"/> diff --git a/org.eclipse.ui.console/schema/consolePatternMatchListener.exsd b/org.eclipse.ui.console/schema/consolePatternMatchListeners.exsd index cad32af12..40f7521cc 100644 --- a/org.eclipse.ui.console/schema/consolePatternMatchListener.exsd +++ b/org.eclipse.ui.console/schema/consolePatternMatchListeners.exsd @@ -1,103 +1,103 @@ -<?xml version='1.0' encoding='UTF-8'?> -<!-- Schema file written by PDE --> -<schema targetNamespace="org.eclipse.ui.console"> -<annotation> - <appInfo> - <meta.schema plugin="org.eclipse.ui.console" id="ConsolePatternMatchListener" name="%ConsolePatternMatchListenerName"/> - </appInfo> - <documentation> - This extension point provides notification when console input or output matches a specified regular expression. - </documentation> - </annotation> - - <include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/> - - <element name="extension"> - <complexType> - <sequence> - <element ref="consolePatternMatchListener" minOccurs="0" maxOccurs="unbounded"/> - </sequence> - <attribute name="point" type="string" use="required"> - <annotation> - <documentation> - a fully qualified identifier of the target extension point - </documentation> - </annotation> - </attribute> - <attribute name="id" type="string"> - <annotation> - <documentation> - an optional identifier of the extension instance - </documentation> - </annotation> - </attribute> - <attribute name="name" type="string"> - <annotation> - <documentation> - an optional name of the extension instance - </documentation> - </annotation> - </attribute> - </complexType> - </element> - - <element name="consolePatternMatchListener"> - <complexType> - <sequence> - <element ref="enablement"/> - </sequence> - <attribute name="id" type="string" use="required"> - <annotation> - <documentation> - specifies a unique identifier for this Console Pattern Match Listener - </documentation> - </annotation> - </attribute> - <attribute name="class" type="string" use="required"> - <annotation> - <documentation> - specifies a fully qualified name of a Java class that implements IPatternMatchListenerDelegate - </documentation> - </annotation> - </attribute> - <attribute name="regex" type="string" use="required"> - <annotation> - <documentation> - specifies the regular expression that should be matched - </documentation> - </annotation> - </attribute> - <attribute name="flags" type="string"> - <annotation> - <documentation> - specifies flags to be used when matching the pattern. Acceptable flags are defined in java.util.regex.Pattern and should be specified as Strings (eg "Pattern.MULTILINE" or "MULTILINE") - </documentation> - </annotation> - </attribute> - <attribute name="matchContext" type="string"> - <annotation> - <documentation> - Allows extension to decide whether a pattern should be matched against the entire document of each line of the document individually. Acceptable values are "line" and "document". If not explicitly specified, "line" matching is assumed. - </documentation> - </annotation> - </attribute> - </complexType> - </element> - - <annotation> - <appInfo> - <meta.section type="since"/> - </appInfo> - <documentation> - 3.1 - </documentation> - </annotation> - - <annotation> - <appInfo> - <meta.section type="examples"/> - </appInfo> - <documentation> +<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.ui.console">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.ui.console" id="consolePatternMatchListeners" name="Console Pattern Match Listeners"/>
+ </appInfo>
+ <documentation>
+ This extension point provides notification when console input or output matches a specified regular expression.
+ </documentation>
+ </annotation>
+
+ <include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="consolePatternMatchListener" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully qualified identifier of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional identifier of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="consolePatternMatchListener">
+ <complexType>
+ <sequence>
+ <element ref="enablement"/>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ specifies a unique identifier for this Console Pattern Match Listener
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ specifies a fully qualified name of a Java class that implements IPatternMatchListenerDelegate
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="regex" type="string" use="required">
+ <annotation>
+ <documentation>
+ specifies the regular expression that should be matched
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="flags" type="string">
+ <annotation>
+ <documentation>
+ specifies flags to be used when matching the pattern. Acceptable flags are defined in java.util.regex.Pattern and should be specified as Strings (eg "Pattern.MULTILINE" or "MULTILINE")
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="qualifier" type="string">
+ <annotation>
+ <documentation>
+ a simple regular expression used to identify a line that may contain this pattern match listener's complete regular expression <code>regex</code>. When a line is found containing this expression, a search is performed from the beginning of the line for this pattern matcher's complete <code>regex</code>. Use of this attribute is optional but can greatly improve performance as lines not containing this expression can be disqualified from the search.
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 3.1
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
The following is an example of a console pattern match listener extension point: <pre> <extension @@ -112,30 +112,30 @@ </consolePatternMatchListener> </extension> </pre> -In the above example, the contributed console pattern matcher will be used for console of type "ExampleConsole." - </documentation> - </annotation> - - <annotation> - <appInfo> - <meta.section type="apiInfo"/> - </appInfo> - <documentation> - Value of the attribute <b>class</b> must be a fully qualified name of a Java class that implements the interface <b>org.eclipse.ui.console.IPatternMatchListenerDelegate</b>. - </documentation> - </annotation> - - <annotation> - <appInfo> - <meta.section type="copyright"/> - </appInfo> - <documentation> +In the above example, the contributed console pattern matcher will be used for console of type "ExampleConsole."
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ Value of the attribute <b>class</b> must be a fully qualified name of a Java class that implements the interface <b>org.eclipse.ui.console.IPatternMatchListenerDelegate</b>.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
Copyright (c) 2000, 2004 IBM Corporation and others.<br> 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 -<a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a> - </documentation> - </annotation> - -</schema> +<a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/console/IConsoleConstants.java b/org.eclipse.ui.console/src/org/eclipse/ui/console/IConsoleConstants.java index 76fcd8354..6a7b5acc0 100644 --- a/org.eclipse.ui.console/src/org/eclipse/ui/console/IConsoleConstants.java +++ b/org.eclipse.ui.console/src/org/eclipse/ui/console/IConsoleConstants.java @@ -67,11 +67,11 @@ public interface IConsoleConstants { /** * Console Pattern Match Listener extension point identifier - * (value <code>"consolePatternMatchListener"</code>). + * (value <code>"consolePatternMatchListeners"</code>). * * @since 3.1 */ - public static final String EXTENSION_POINT_CONSOLE_PATTERN_MATCH_LISTENER = "consolePatternMatchListener"; //$NON-NLS-1$ + public static final String EXTENSION_POINT_CONSOLE_PATTERN_MATCH_LISTENER = "consolePatternMatchListeners"; //$NON-NLS-1$ /** * Console Page Participant extension point identifier diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/console/IOConsole.java b/org.eclipse.ui.console/src/org/eclipse/ui/console/IOConsole.java index 6f8f62ec2..a9487f3d8 100644 --- a/org.eclipse.ui.console/src/org/eclipse/ui/console/IOConsole.java +++ b/org.eclipse.ui.console/src/org/eclipse/ui/console/IOConsole.java @@ -415,14 +415,15 @@ public class IOConsole extends AbstractConsole implements IDocumentListener { } Pattern pattern = Pattern.compile(matchListener.getPattern(), matchListener.getCompilerFlags()); - CompiledPatternMatchListener notifier = new CompiledPatternMatchListener(pattern, matchListener); + String qualifier = matchListener.getLineQualifier(); + Pattern qPattern = null; + if (qualifier != null) { + qPattern = Pattern.compile(qualifier, matchListener.getCompilerFlags()); + } + CompiledPatternMatchListener notifier = new CompiledPatternMatchListener(pattern, qPattern, matchListener); patterns.add(notifier); matchListener.connect(this); - - try { - testForMatch(notifier, 0); - } catch (BadLocationException e){ - } + matchJob.schedule(100); } } @@ -453,107 +454,89 @@ public class IOConsole extends AbstractConsole implements IDocumentListener { * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent) */ public void documentChanged(DocumentEvent event) { - synchronized(patterns) { - for (Iterator iter = patterns.iterator(); iter.hasNext();) { - CompiledPatternMatchListener pattern = (CompiledPatternMatchListener) iter.next(); - try { - testForMatch(pattern, event.fOffset); - } catch (BadLocationException e) { - } - } - } + if (event.getOffset() == 0 && event.getLength() == 0) { + // buffer has been emptied, reset match listeners + synchronized (patterns) { + Iterator iter = patterns.iterator(); + while (iter.hasNext()) { + CompiledPatternMatchListener notifier = (CompiledPatternMatchListener)iter.next(); + notifier.end = 0; + } + } + } + matchJob.schedule(50); } - private void testForMatch(CompiledPatternMatchListener compiled, int eventOffset) throws BadLocationException { - switch (compiled.listener.getMatchContext()) { - case IPatternMatchListener.LINE_MATCH: - matchByLine(compiled, eventOffset); - break; - case IPatternMatchListener.DOCUMENT_MATCH: - matchByDocument(compiled, eventOffset); - break; - } - } - private void matchByLine(final CompiledPatternMatchListener compiled, final int eventOffset) throws BadLocationException { - IDocument document = getDocument(); - int curLine = document.getLineOfOffset(eventOffset); - int numLines = document.getNumberOfLines(); - - for(; curLine<numLines; curLine++) { - int start = document.getLineOffset(curLine); - String line = document.get(start, document.getLineLength(curLine)); - matchJob.addMatchUnit(new MatchUnit(compiled, line, start, false)); - } - } - - private void matchByDocument(final CompiledPatternMatchListener compiled, final int eventOffset) throws BadLocationException { - final int start = Math.min(compiled.end, eventOffset); - IDocument document = getDocument(); - final String contents = document.get(start, document.getLength()-start); - matchJob.addMatchUnit(new MatchUnit(compiled, contents, start, true)); - } - private class CompiledPatternMatchListener { Pattern pattern; + Pattern qualifier; IPatternMatchListener listener; int end = 0; - CompiledPatternMatchListener(Pattern pattern, IPatternMatchListener matchListener) { + CompiledPatternMatchListener(Pattern pattern, Pattern qualifier, IPatternMatchListener matchListener) { this.pattern = pattern; this.listener = matchListener; - } - } - - private class MatchUnit { - String content; - int docOffset; - CompiledPatternMatchListener listener; - boolean docMatch = false; - - public MatchUnit(CompiledPatternMatchListener listener, String content, int docOffset, boolean docMatch) { - this.listener = listener; - this.content = content; - this.docOffset = docOffset; - this.docMatch = docMatch; + this.qualifier = qualifier; } } private class MatchJob extends Job { - private ArrayList matchUnits = new ArrayList(); MatchJob() { super("Match Job"); //$NON-NLS-1$ setSystem(true); } - - void addMatchUnit(MatchUnit unit) { - synchronized(matchUnits) { - matchUnits.add(unit); - } - schedule(); - } - - protected IStatus run(IProgressMonitor monitor) { - while(!matchUnits.isEmpty()) { - ArrayList copy = matchUnits; - synchronized(matchUnits) { - matchUnits = new ArrayList(); - } - for (Iterator iter = copy.iterator(); iter.hasNext();) { - MatchUnit unit = (MatchUnit) iter.next(); - Matcher matcher = unit.listener.pattern.matcher(unit.content); - while(matcher.find()) { - String group = matcher.group(); - int matchOffset = unit.docOffset + matcher.start(); - unit.listener.listener.matchFound(new PatternMatchEvent(IOConsole.this, matchOffset, group.length())); - if(unit.docMatch) { - unit.listener.end = matcher.end() + unit.docOffset; - } - } - } - } - + protected IStatus run(IProgressMonitor monitor) { + IDocument doc = getDocument(); + String text = null; + int prevBaseOffset = -1; + if (doc != null) { + int docLength = doc.getLength(); + for (int i = 0; i < patterns.size(); i++) { + CompiledPatternMatchListener notifier = (CompiledPatternMatchListener) patterns.get(i); + int baseOffset = notifier.end; + int length = docLength - baseOffset; + if (length > 0) { + try { + if (prevBaseOffset != baseOffset) { + // reuse the text string if possible + text = doc.get(baseOffset, length); + } + Matcher reg = notifier.pattern.matcher(text); + Matcher quick = null; + if (notifier.qualifier != null) { + quick = notifier.qualifier.matcher(text); + } + int start = 0; + while (start < length) { + if (quick != null) { + if (quick.find(start)) { + int line = doc.getLineOfOffset(baseOffset + quick.start()); + start = doc.getLineOffset(line) - baseOffset; + } else { + start = length; + } + } + if (start < length) { + if (reg.find(start)) { + start = reg.end(); + int regStart = reg.start(); + notifier.listener.matchFound(new PatternMatchEvent(IOConsole.this, baseOffset + regStart, start - regStart)); + } else { + start = length; + } + } + notifier.end = baseOffset + start; + } + } catch (BadLocationException e) { + // TODO: + e.printStackTrace(); + } + } + prevBaseOffset = baseOffset; + } + } return Status.OK_STATUS; } diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/console/IPatternMatchListener.java b/org.eclipse.ui.console/src/org/eclipse/ui/console/IPatternMatchListener.java index cbdd51117..927575a77 100644 --- a/org.eclipse.ui.console/src/org/eclipse/ui/console/IPatternMatchListener.java +++ b/org.eclipse.ui.console/src/org/eclipse/ui/console/IPatternMatchListener.java @@ -19,8 +19,6 @@ package org.eclipse.ui.console; * @since 3.1 */ public interface IPatternMatchListener { - public static final int LINE_MATCH = 0; - public static final int DOCUMENT_MATCH = 1; /** * Returns the pattern to be used for matching. The pattern is * a string representing a regular expression. @@ -36,14 +34,18 @@ public interface IPatternMatchListener { public int getCompilerFlags(); /** - * Returns the match context for this pattern match listener. Allowable values - * are <code>LINE_MATCH</code> and <code>DOCUMENT_MATCH</code>. - * @return <code>LINE_MATCH</code> if pattern should be matched against individual lines - * or <code>DOCUMENT_MATCH</code> if pattern should be matched against the console's entire - * document. + * Returns a simple regular expression used to identify lines that may + * match this pattern matcher's complete pattern, or <code>null</code>. + * Use of this attribute can improve performance by disqualifying lines + * from the search. When a line is found containing a match for this expression, + * the line is searched from the beginning for this pattern matcher's + * complete pattern. + * + * @return a simple regular expression used to identify lines that may + * match this pattern matcher's complete pattern, or <code>null</code> */ - public int getMatchContext(); - + public String getLineQualifier(); + /** * Notification that a match has been found. * diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/PatternMatchListener.java b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/PatternMatchListener.java index 5d27e9278..afedfe6f7 100644 --- a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/PatternMatchListener.java +++ b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/PatternMatchListener.java @@ -20,16 +20,10 @@ public class PatternMatchListener implements IPatternMatchListener { private PatternMatchListenerExtension fExtension; private IPatternMatchListenerDelegate fDelegate; - private int fMatchContext; public PatternMatchListener(PatternMatchListenerExtension extension) throws CoreException { fExtension = extension; fDelegate = fExtension.createDelegate(); - if (fExtension.getMatchContext().equals("document")) { //$NON-NLS-1$ - fMatchContext = IPatternMatchListener.DOCUMENT_MATCH; - } else { - fMatchContext = IPatternMatchListener.LINE_MATCH; - } } /* (non-Javadoc) @@ -47,13 +41,6 @@ public class PatternMatchListener implements IPatternMatchListener { } /* (non-Javadoc) - * @see org.eclipse.ui.console.IPatternMatchListener#getMatchContext() - */ - public int getMatchContext() { - return fMatchContext; - } - - /* (non-Javadoc) * @see org.eclipse.ui.console.IPatternMatchListener#matchFound(org.eclipse.ui.console.PatternMatchEvent) */ public void matchFound(PatternMatchEvent event) { @@ -74,4 +61,11 @@ public class PatternMatchListener implements IPatternMatchListener { fDelegate.disconnect(); } + /* (non-Javadoc) + * @see org.eclipse.ui.console.IPatternMatchListener#getQuickPattern() + */ + public String getLineQualifier() { + return fExtension.getQuickPattern(); + } + } diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/PatternMatchListenerExtension.java b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/PatternMatchListenerExtension.java index a1847ca10..264134b24 100644 --- a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/PatternMatchListenerExtension.java +++ b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/PatternMatchListenerExtension.java @@ -30,7 +30,6 @@ public class PatternMatchListenerExtension implements IPluginContribution { private Expression fEnablementExpression; private String fPattern; private int fFlags = -1; - private String fMatchContext; public PatternMatchListenerExtension(IConfigurationElement extension) { fConfig = extension; @@ -108,19 +107,6 @@ public class PatternMatchListenerExtension implements IPluginContribution { } return fFlags; } - - /** - * @return - */ - public String getMatchContext() { - if (fMatchContext == null) { - fMatchContext = fConfig.getAttributeAsIs("matchContext"); //$NON-NLS-1$ - if (fMatchContext == null) { - fMatchContext = "line"; //$NON-NLS-1$ - } - } - return fMatchContext; - } /* (non-Javadoc) * @see org.eclipse.ui.IPluginContribution#getLocalId() @@ -136,4 +122,7 @@ public class PatternMatchListenerExtension implements IPluginContribution { return fConfig.getDeclaringExtension().getNamespace(); } + public String getQuickPattern() { + return fConfig.getAttribute("qualifier"); //$NON-NLS-1$ + } } |