001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 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.pde.internal.ui.launcher;
011:
012: import java.io.File;
013: import java.util.ArrayList;
014:
015: import org.eclipse.core.filesystem.EFS;
016: import org.eclipse.core.filesystem.IFileStore;
017: import org.eclipse.core.runtime.CoreException;
018: import org.eclipse.core.runtime.NullProgressMonitor;
019: import org.eclipse.core.runtime.Path;
020: import org.eclipse.debug.core.DebugEvent;
021: import org.eclipse.debug.core.DebugException;
022: import org.eclipse.debug.core.DebugPlugin;
023: import org.eclipse.debug.core.IDebugEventSetListener;
024: import org.eclipse.debug.core.ILaunch;
025: import org.eclipse.debug.core.ILaunchConfiguration;
026: import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
027: import org.eclipse.debug.core.ILaunchListener;
028: import org.eclipse.debug.core.ILaunchManager;
029: import org.eclipse.debug.core.model.IProcess;
030: import org.eclipse.jface.dialogs.IDialogConstants;
031: import org.eclipse.jface.dialogs.MessageDialog;
032: import org.eclipse.pde.internal.runtime.logview.LogView;
033: import org.eclipse.pde.internal.ui.IPDEUIConstants;
034: import org.eclipse.pde.internal.ui.PDEPlugin;
035: import org.eclipse.pde.internal.ui.PDEUIMessages;
036: import org.eclipse.swt.widgets.Display;
037: import org.eclipse.ui.IWorkbenchPage;
038: import org.eclipse.ui.IWorkbenchWindow;
039: import org.eclipse.ui.PartInitException;
040: import org.eclipse.ui.ide.IDE;
041:
042: public class LaunchListener implements ILaunchListener,
043: IDebugEventSetListener {
044: private ArrayList managedLaunches;
045: // maximum log file size
046: public static final long MAX_FILE_LENGTH = 1024 * 1024;
047: // different ways to open the error log
048: public static final int OPEN_IN_ERROR_LOG_VIEW = 0;
049: public static final int OPEN_IN_SYSTEM_EDITOR = 1;
050:
051: public LaunchListener() {
052: managedLaunches = new ArrayList();
053: }
054:
055: public void manage(ILaunch launch) {
056: if (managedLaunches.size() == 0)
057: hookListener(true);
058: if (!managedLaunches.contains(launch))
059: managedLaunches.add(launch);
060: }
061:
062: /**
063: * @see org.eclipse.debug.core.ILaunchesListener#launchesRemoved(org.eclipse.debug.core.ILaunch)
064: */
065: public void launchRemoved(ILaunch launch) {
066: update(launch, true);
067: }
068:
069: /**
070: * @see org.eclipse.debug.core.ILaunchesListener#launchesAdded(org.eclipse.debug.core.ILaunch)
071: */
072: public void launchAdded(ILaunch launch) {
073: }
074:
075: /**
076: * @see org.eclipse.debug.core.ILaunchesListener#launchesChanged(org.eclipse.debug.core.ILaunch)
077: */
078: public void launchChanged(ILaunch launch) {
079: }
080:
081: private void update(ILaunch launch, boolean remove) {
082: if (managedLaunches.contains(launch)) {
083: if (remove || launch.isTerminated()) {
084: managedLaunches.remove(launch);
085: if (managedLaunches.size() == 0) {
086: hookListener(false);
087: }
088: }
089: }
090: }
091:
092: private void hookListener(boolean add) {
093: DebugPlugin debugPlugin = DebugPlugin.getDefault();
094: ILaunchManager launchManager = debugPlugin.getLaunchManager();
095: if (add) {
096: launchManager.addLaunchListener(this );
097: debugPlugin.addDebugEventListener(this );
098: } else {
099: launchManager.removeLaunchListener(this );
100: debugPlugin.removeDebugEventListener(this );
101: }
102: }
103:
104: private void doRestart(ILaunch launch) {
105: ILaunchConfiguration config = launch.getLaunchConfiguration();
106: try {
107: ILaunchConfigurationWorkingCopy copy = config
108: .getWorkingCopy();
109: copy.setAttribute(IPDEUIConstants.RESTART, true);
110: copy.launch(launch.getLaunchMode(),
111: new NullProgressMonitor());
112: } catch (CoreException e) {
113: PDEPlugin.logException(e);
114: }
115: }
116:
117: public void shutdown() {
118: hookListener(false);
119: }
120:
121: /**
122: * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent)
123: */
124: public void handleDebugEvents(DebugEvent[] events) {
125: for (int i = 0; i < events.length; i++) {
126: DebugEvent event = events[i];
127: Object source = event.getSource();
128: if (source instanceof IProcess
129: && event.getKind() == DebugEvent.TERMINATE) {
130: IProcess process = (IProcess) source;
131: ILaunch launch = process.getLaunch();
132: if (launch != null) {
133: try {
134: launchTerminated(launch, process.getExitValue());
135: } catch (DebugException e) {
136: }
137: }
138: }
139: }
140: }
141:
142: private void launchTerminated(final ILaunch launch, int returnValue) {
143: if (managedLaunches.contains(launch)) {
144: update(launch, true);
145: if (returnValue == 23) {
146: doRestart(launch);
147: return;
148: }
149: // launch failed because the associated workspace is in use
150: if (returnValue == 15) {
151: Display.getDefault().asyncExec(new Runnable() {
152: public void run() {
153: MessageDialog.openError(PDEPlugin
154: .getActiveWorkbenchShell(),
155: PDEUIMessages.Launcher_error_title,
156: PDEUIMessages.Launcher_error_code15);
157: }
158: });
159: return;
160: }
161: // launch failed for reasons printed to the log.
162: if (returnValue == 13) {
163: Display.getDefault().asyncExec(new Runnable() {
164: public void run() {
165: try {
166: File log = getMostRecentLogFile(launch);
167: if (log != null && log.exists()) {
168: MessageDialog dialog = new MessageDialog(
169: PDEPlugin
170: .getActiveWorkbenchShell(),
171: PDEUIMessages.Launcher_error_title,
172: null, // accept the default window icon
173: PDEUIMessages.Launcher_error_code13,
174: MessageDialog.ERROR,
175: new String[] {
176: PDEUIMessages.Launcher_error_displayInLogView,
177: PDEUIMessages.Launcher_error_displayInSystemEditor,
178: IDialogConstants.NO_LABEL },
179: OPEN_IN_ERROR_LOG_VIEW);
180: int dialog_value = dialog.open();
181: if (dialog_value == OPEN_IN_ERROR_LOG_VIEW) {
182: LogView errlog = (LogView) PDEPlugin
183: .getActivePage()
184: .showView(
185: "org.eclipse.pde.runtime.LogView"); //$NON-NLS-1$
186: errlog.handleImportPath(log
187: .getAbsolutePath());
188: errlog.sortByDateDescending();
189: } else if (dialog_value == OPEN_IN_SYSTEM_EDITOR) {
190: openInEditor(log);
191: }
192: }
193: } catch (CoreException e) {
194: }
195: }
196: });
197: }
198: }
199: }
200:
201: private void openInEditor(File log) {
202: IFileStore fileStore = EFS.getLocalFileSystem().getStore(
203: new Path(log.getAbsolutePath()));
204: if (!fileStore.fetchInfo().isDirectory()
205: && fileStore.fetchInfo().exists()) {
206: IWorkbenchWindow ww = PDEPlugin.getActiveWorkbenchWindow();
207: IWorkbenchPage page = ww.getActivePage();
208: try {
209: IDE.openEditorOnFileStore(page, fileStore);
210: } catch (PartInitException e) {
211: }
212: }
213: }
214:
215: private File getMostRecentLogFile(ILaunch launch)
216: throws CoreException {
217: ILaunchConfiguration configuration = launch
218: .getLaunchConfiguration();
219: File latest = null;
220: String workspace = LaunchArgumentsHelper
221: .getWorkspaceLocation(configuration);
222: if (workspace.length() > 0) {
223: latest = new File(workspace, ".metadata/.log"); //$NON-NLS-1$
224: if (!latest.exists())
225: latest = null;
226: }
227: File configDir = LaunchConfigurationHelper
228: .getConfigurationLocation(configuration);
229: File[] children = configDir.listFiles();
230: if (children != null) {
231: for (int i = 0; i < children.length; i++) {
232: if (!children[i].isDirectory()
233: && children[i].getName().endsWith(".log")) { //$NON-NLS-1$
234: if (latest == null
235: || latest.lastModified() < children[i]
236: .lastModified())
237: latest = children[i];
238: }
239: }
240: }
241: return latest;
242: }
243:
244: }
|