001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.console;
011:
012: import java.util.ArrayList;
013: import java.util.HashSet;
014: import java.util.Iterator;
015: import java.util.List;
016: import java.util.Set;
017: import java.util.regex.PatternSyntaxException;
018:
019: import org.eclipse.core.runtime.CoreException;
020: import org.eclipse.core.runtime.IConfigurationElement;
021: import org.eclipse.core.runtime.IExtensionPoint;
022: import org.eclipse.core.runtime.IProgressMonitor;
023: import org.eclipse.core.runtime.ISafeRunnable;
024: import org.eclipse.core.runtime.IStatus;
025: import org.eclipse.core.runtime.ListenerList;
026: import org.eclipse.core.runtime.Platform;
027: import org.eclipse.core.runtime.SafeRunner;
028: import org.eclipse.core.runtime.Status;
029: import org.eclipse.core.runtime.jobs.Job;
030: import org.eclipse.swt.widgets.Control;
031: import org.eclipse.ui.IViewPart;
032: import org.eclipse.ui.IWorkbenchPage;
033: import org.eclipse.ui.IWorkbenchWindow;
034: import org.eclipse.ui.PartInitException;
035: import org.eclipse.ui.PlatformUI;
036: import org.eclipse.ui.console.ConsolePlugin;
037: import org.eclipse.ui.console.IConsole;
038: import org.eclipse.ui.console.IConsoleConstants;
039: import org.eclipse.ui.console.IConsoleListener;
040: import org.eclipse.ui.console.IConsoleManager;
041: import org.eclipse.ui.console.IConsolePageParticipant;
042: import org.eclipse.ui.console.IConsoleView;
043: import org.eclipse.ui.console.IPatternMatchListener;
044: import org.eclipse.ui.console.TextConsole;
045: import org.eclipse.ui.progress.WorkbenchJob;
046:
047: /**
048: * The singleton console manager.
049: *
050: * @since 3.0
051: */
052: public class ConsoleManager implements IConsoleManager {
053:
054: /**
055: * Console listeners
056: */
057: private ListenerList fListeners = null;
058:
059: /**
060: * List of registered consoles
061: */
062: private List fConsoles = new ArrayList(10);
063:
064: // change notification constants
065: private final static int ADDED = 1;
066: private final static int REMOVED = 2;
067:
068: private List fPatternMatchListeners;
069:
070: private List fPageParticipants;
071:
072: private List fConsoleFactoryExtensions;
073:
074: private List fConsoleViews = new ArrayList();
075:
076: private boolean fWarnQueued = false;
077:
078: private RepaintJob fRepaintJob = new RepaintJob();
079:
080: private class RepaintJob extends WorkbenchJob {
081: private Set list = new HashSet();
082:
083: public RepaintJob() {
084: super ("schedule redraw() of viewers"); //$NON-NLS-1$
085: setSystem(true);
086: }
087:
088: void addConsole(IConsole console) {
089: synchronized (list) {
090: list.add(console);
091: }
092: }
093:
094: public IStatus runInUIThread(IProgressMonitor monitor) {
095: synchronized (list) {
096: if (list.isEmpty()) {
097: return Status.OK_STATUS;
098: }
099:
100: IWorkbenchWindow[] workbenchWindows = PlatformUI
101: .getWorkbench().getWorkbenchWindows();
102: for (int i = 0; i < workbenchWindows.length; i++) {
103: IWorkbenchWindow window = workbenchWindows[i];
104: if (window != null) {
105: IWorkbenchPage page = window.getActivePage();
106: if (page != null) {
107: IViewPart part = page
108: .findView(IConsoleConstants.ID_CONSOLE_VIEW);
109: if (part != null
110: && part instanceof IConsoleView) {
111: ConsoleView view = (ConsoleView) part;
112: if (list.contains(view.getConsole())) {
113: Control control = view
114: .getCurrentPage()
115: .getControl();
116: if (!control.isDisposed()) {
117: control.redraw();
118: }
119: }
120: }
121:
122: }
123: }
124: }
125: list.clear();
126: }
127: return Status.OK_STATUS;
128: }
129: }
130:
131: /**
132: * Notifies a console listener of additions or removals
133: */
134: class ConsoleNotifier implements ISafeRunnable {
135:
136: private IConsoleListener fListener;
137: private int fType;
138: private IConsole[] fChanged;
139:
140: /* (non-Javadoc)
141: * @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
142: */
143: public void handleException(Throwable exception) {
144: IStatus status = new Status(IStatus.ERROR, ConsolePlugin
145: .getUniqueIdentifier(),
146: IConsoleConstants.INTERNAL_ERROR,
147: ConsoleMessages.ConsoleManager_0, exception);
148: ConsolePlugin.log(status);
149: }
150:
151: /* (non-Javadoc)
152: * @see org.eclipse.core.runtime.ISafeRunnable#run()
153: */
154: public void run() throws Exception {
155: switch (fType) {
156: case ADDED:
157: fListener.consolesAdded(fChanged);
158: break;
159: case REMOVED:
160: fListener.consolesRemoved(fChanged);
161: break;
162: }
163: }
164:
165: /**
166: * Notifies the given listener of the adds/removes
167: *
168: * @param consoles the consoles that changed
169: * @param update the type of change
170: */
171: public void notify(IConsole[] consoles, int update) {
172: if (fListeners == null) {
173: return;
174: }
175: fChanged = consoles;
176: fType = update;
177: Object[] copiedListeners = fListeners.getListeners();
178: for (int i = 0; i < copiedListeners.length; i++) {
179: fListener = (IConsoleListener) copiedListeners[i];
180: SafeRunner.run(this );
181: }
182: fChanged = null;
183: fListener = null;
184: }
185: }
186:
187: public void registerConsoleView(ConsoleView view) {
188: synchronized (fConsoleViews) {
189: fConsoleViews.add(view);
190: }
191: }
192:
193: public void unregisterConsoleView(ConsoleView view) {
194: synchronized (fConsoleViews) {
195: fConsoleViews.remove(view);
196: }
197: }
198:
199: /* (non-Javadoc)
200: * @see org.eclipse.ui.console.IConsoleManager#addConsoleListener(org.eclipse.ui.console.IConsoleListener)
201: */
202: public void addConsoleListener(IConsoleListener listener) {
203: if (fListeners == null) {
204: fListeners = new ListenerList();
205: }
206: fListeners.add(listener);
207: }
208:
209: /* (non-Javadoc)
210: * @see org.eclipse.ui.console.IConsoleManager#removeConsoleListener(org.eclipse.ui.console.IConsoleListener)
211: */
212: public void removeConsoleListener(IConsoleListener listener) {
213: if (fListeners != null) {
214: fListeners.remove(listener);
215: }
216: }
217:
218: /* (non-Javadoc)
219: * @see org.eclipse.ui.console.IConsoleManager#addConsoles(org.eclipse.ui.console.IConsole[])
220: */
221: public synchronized void addConsoles(IConsole[] consoles) {
222: List added = new ArrayList(consoles.length);
223: for (int i = 0; i < consoles.length; i++) {
224: IConsole console = consoles[i];
225: if (console instanceof TextConsole) {
226: TextConsole ioconsole = (TextConsole) console;
227: createPatternMatchListeners(ioconsole);
228: }
229: if (!fConsoles.contains(console)) {
230: fConsoles.add(console);
231: added.add(console);
232: }
233: }
234: if (!added.isEmpty()) {
235: fireUpdate((IConsole[]) added.toArray(new IConsole[added
236: .size()]), ADDED);
237: }
238: }
239:
240: /* (non-Javadoc)
241: * @see org.eclipse.ui.console.IConsoleManager#removeConsoles(org.eclipse.ui.console.IConsole[])
242: */
243: public synchronized void removeConsoles(IConsole[] consoles) {
244: List removed = new ArrayList(consoles.length);
245: for (int i = 0; i < consoles.length; i++) {
246: IConsole console = consoles[i];
247: if (fConsoles.remove(console)) {
248: removed.add(console);
249: }
250: }
251: if (!removed.isEmpty()) {
252: fireUpdate((IConsole[]) removed
253: .toArray(new IConsole[removed.size()]), REMOVED);
254: }
255: }
256:
257: /* (non-Javadoc)
258: * @see org.eclipse.ui.console.IConsoleManager#getConsoles()
259: */
260: public synchronized IConsole[] getConsoles() {
261: return (IConsole[]) fConsoles.toArray(new IConsole[fConsoles
262: .size()]);
263: }
264:
265: /**
266: * Fires notification.
267: *
268: * @param consoles consoles added/removed
269: * @param type ADD or REMOVE
270: */
271: private void fireUpdate(IConsole[] consoles, int type) {
272: new ConsoleNotifier().notify(consoles, type);
273: }
274:
275: private class ShowConsoleViewJob extends WorkbenchJob {
276: private IConsole console;
277:
278: ShowConsoleViewJob() {
279: super ("Show Console View"); //$NON-NLS-1$
280: setSystem(true);
281: setPriority(Job.SHORT);
282: }
283:
284: void setConsole(IConsole console) {
285: this .console = console;
286: }
287:
288: public IStatus runInUIThread(IProgressMonitor monitor) {
289: boolean consoleFound = false;
290: IWorkbenchWindow window = PlatformUI.getWorkbench()
291: .getActiveWorkbenchWindow();
292: if (window != null && console != null) {
293: IWorkbenchPage page = window.getActivePage();
294: if (page != null) {
295: synchronized (fConsoleViews) {
296: for (Iterator iter = fConsoleViews.iterator(); iter
297: .hasNext();) {
298: ConsoleView consoleView = (ConsoleView) iter
299: .next();
300: if (consoleView.getSite().getPage().equals(
301: page)) {
302: boolean consoleVisible = page
303: .isPartVisible(consoleView);
304: if (consoleVisible) {
305: consoleFound = true;
306: boolean bringToTop = shouldBringToTop(
307: console, consoleView);
308: if (bringToTop) {
309: page.bringToTop(consoleView);
310: }
311: consoleView.display(console);
312: }
313: }
314: }
315: }
316:
317: if (!consoleFound) {
318: try {
319: IConsoleView consoleView = (IConsoleView) page
320: .showView(
321: IConsoleConstants.ID_CONSOLE_VIEW,
322: null,
323: IWorkbenchPage.VIEW_CREATE);
324: boolean bringToTop = shouldBringToTop(
325: console, consoleView);
326: if (bringToTop) {
327: page.bringToTop(consoleView);
328: }
329: consoleView.display(console);
330: } catch (PartInitException pie) {
331: ConsolePlugin.log(pie);
332: }
333: }
334: }
335: }
336: console = null;
337: return Status.OK_STATUS;
338: }
339: }
340:
341: private ShowConsoleViewJob showJob = new ShowConsoleViewJob();
342:
343: /**
344: * @see IConsoleManager#showConsoleView(IConsole)
345: */
346: public void showConsoleView(final IConsole console) {
347: showJob.setConsole(console);
348: showJob.schedule(100);
349: }
350:
351: /**
352: * Returns whether the given console view should be brought to the top.
353: * The view should not be brought to the top if the view is pinned on
354: * a console other than the given console.
355: */
356: private boolean shouldBringToTop(IConsole console,
357: IViewPart consoleView) {
358: boolean bringToTop = true;
359: if (consoleView instanceof IConsoleView) {
360: IConsoleView cView = (IConsoleView) consoleView;
361: if (cView.isPinned()) {
362: IConsole pinnedConsole = cView.getConsole();
363: bringToTop = console.equals(pinnedConsole);
364: }
365: }
366: return bringToTop;
367: }
368:
369: /* (non-Javadoc)
370: * @see org.eclipse.ui.console.IConsoleManager#warnOfContentChange(org.eclipse.ui.console.IConsole)
371: */
372: public void warnOfContentChange(final IConsole console) {
373: if (!fWarnQueued) {
374: fWarnQueued = true;
375: ConsolePlugin.getStandardDisplay().asyncExec(
376: new Runnable() {
377: public void run() {
378: IWorkbenchWindow window = PlatformUI
379: .getWorkbench()
380: .getActiveWorkbenchWindow();
381: if (window != null) {
382: IWorkbenchPage page = window
383: .getActivePage();
384: if (page != null) {
385: IConsoleView consoleView = (IConsoleView) page
386: .findView(IConsoleConstants.ID_CONSOLE_VIEW);
387: if (consoleView != null) {
388: consoleView
389: .warnOfContentChange(console);
390: }
391: }
392: }
393: fWarnQueued = false;
394: }
395: });
396: }
397: }
398:
399: /* (non-Javadoc)
400: * @see org.eclipse.ui.console.IConsoleManager#getPatternMatchListenerDelegates(org.eclipse.ui.console.IConsole)
401: */
402: public IPatternMatchListener[] createPatternMatchListeners(
403: IConsole console) {
404: if (fPatternMatchListeners == null) {
405: fPatternMatchListeners = new ArrayList();
406: IExtensionPoint extensionPoint = Platform
407: .getExtensionRegistry()
408: .getExtensionPoint(
409: ConsolePlugin.getUniqueIdentifier(),
410: IConsoleConstants.EXTENSION_POINT_CONSOLE_PATTERN_MATCH_LISTENERS);
411: IConfigurationElement[] elements = extensionPoint
412: .getConfigurationElements();
413: for (int i = 0; i < elements.length; i++) {
414: IConfigurationElement config = elements[i];
415: PatternMatchListenerExtension extension = new PatternMatchListenerExtension(
416: config);
417: fPatternMatchListeners.add(extension);
418: }
419: }
420: ArrayList list = new ArrayList();
421: for (Iterator i = fPatternMatchListeners.iterator(); i
422: .hasNext();) {
423: PatternMatchListenerExtension extension = (PatternMatchListenerExtension) i
424: .next();
425: try {
426: if (extension.getEnablementExpression() == null) {
427: i.remove();
428: continue;
429: }
430:
431: if (console instanceof TextConsole
432: && extension.isEnabledFor(console)) {
433: TextConsole textConsole = (TextConsole) console;
434: PatternMatchListener patternMatchListener = new PatternMatchListener(
435: extension);
436: try {
437: textConsole
438: .addPatternMatchListener(patternMatchListener);
439: list.add(patternMatchListener);
440: } catch (PatternSyntaxException e) {
441: ConsolePlugin.log(e);
442: i.remove();
443: }
444: }
445: } catch (CoreException e) {
446: ConsolePlugin.log(e);
447: }
448: }
449: return (PatternMatchListener[]) list
450: .toArray(new PatternMatchListener[0]);
451: }
452:
453: /* (non-Javadoc)
454: * @see org.eclipse.ui.console.IConsoleManager#getPageParticipants(org.eclipse.ui.console.IConsole)
455: */
456: public IConsolePageParticipant[] getPageParticipants(
457: IConsole console) {
458: if (fPageParticipants == null) {
459: fPageParticipants = new ArrayList();
460: IExtensionPoint extensionPoint = Platform
461: .getExtensionRegistry()
462: .getExtensionPoint(
463: ConsolePlugin.getUniqueIdentifier(),
464: IConsoleConstants.EXTENSION_POINT_CONSOLE_PAGE_PARTICIPANTS);
465: IConfigurationElement[] elements = extensionPoint
466: .getConfigurationElements();
467: for (int i = 0; i < elements.length; i++) {
468: IConfigurationElement config = elements[i];
469: ConsolePageParticipantExtension extension = new ConsolePageParticipantExtension(
470: config);
471: fPageParticipants.add(extension);
472: }
473: }
474: ArrayList list = new ArrayList();
475: for (Iterator i = fPageParticipants.iterator(); i.hasNext();) {
476: ConsolePageParticipantExtension extension = (ConsolePageParticipantExtension) i
477: .next();
478: try {
479: if (extension.isEnabledFor(console)) {
480: list.add(extension.createDelegate());
481: }
482: } catch (CoreException e) {
483: ConsolePlugin.log(e);
484: }
485: }
486: return (IConsolePageParticipant[]) list
487: .toArray(new IConsolePageParticipant[0]);
488: }
489:
490: /* (non-Javadoc)
491: * @see org.eclipse.ui.console.IConsoleManager#getConsoleFactories()
492: */
493: public ConsoleFactoryExtension[] getConsoleFactoryExtensions() {
494: if (fConsoleFactoryExtensions == null) {
495: fConsoleFactoryExtensions = new ArrayList();
496: IExtensionPoint extensionPoint = Platform
497: .getExtensionRegistry()
498: .getExtensionPoint(
499: ConsolePlugin.getUniqueIdentifier(),
500: IConsoleConstants.EXTENSION_POINT_CONSOLE_FACTORIES);
501: IConfigurationElement[] configurationElements = extensionPoint
502: .getConfigurationElements();
503: for (int i = 0; i < configurationElements.length; i++) {
504: fConsoleFactoryExtensions
505: .add(new ConsoleFactoryExtension(
506: configurationElements[i]));
507: }
508: }
509: return (ConsoleFactoryExtension[]) fConsoleFactoryExtensions
510: .toArray(new ConsoleFactoryExtension[0]);
511: }
512:
513: public void refresh(final IConsole console) {
514: fRepaintJob.addConsole(console);
515: fRepaintJob.schedule(50);
516: }
517:
518: }
|