c1b0bb19919b88428498095c7db8aaf9b9d48771
[phpeclipse.git] / net.sourceforge.phpeclipse.xdebug.ui / src / net / sourceforge / phpeclipse / xdebug / ui / views / logview / OpenLogDialog.java
1 /*******************************************************************************
2  * Copyright (c) 2003, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpeclipse.xdebug.ui.views.logview;
13
14 import java.io.BufferedReader;
15 import java.io.File;
16 import java.io.FileNotFoundException;
17 import java.io.FileReader;
18 import java.io.IOException;
19 import java.io.PrintWriter;
20 import java.io.RandomAccessFile;
21 import java.io.StringWriter;
22 import java.lang.reflect.InvocationTargetException;
23
24 import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin;
25 import net.sourceforge.phpeclipse.xdebug.ui.XDebugUIPlugin;
26
27 import org.eclipse.core.runtime.IProgressMonitor;
28 import org.eclipse.jface.dialogs.Dialog;
29 import org.eclipse.jface.dialogs.IDialogConstants;
30 import org.eclipse.jface.dialogs.IDialogSettings;
31 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
32 import org.eclipse.jface.operation.IRunnableWithProgress;
33 import org.eclipse.swt.SWT;
34 import org.eclipse.swt.graphics.Point;
35 import org.eclipse.swt.layout.GridData;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.widgets.Control;
38 import org.eclipse.swt.widgets.Shell;
39 import org.eclipse.swt.widgets.Text;
40
41 /**
42  * Displays the error log in non-Win32 platforms - see bug 55314.
43  */
44 public final class OpenLogDialog extends Dialog {
45     // input log file
46     private File logFile;
47     // location/size configuration
48     private IDialogSettings dialogSettings;
49     private Point dialogLocation;
50     private Point dialogSize;
51     private int DEFAULT_WIDTH = 750;
52     private int DEFAULT_HEIGHT = 800;
53
54     public OpenLogDialog(Shell parentShell, File logFile) {
55         super(parentShell);
56         this.logFile = logFile;
57         setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX | SWT.MIN | SWT.MODELESS);
58
59     }
60
61     /*
62      * (non-Javadoc) Method declared on Window.
63      */
64     protected void configureShell(Shell newShell) {
65         super.configureShell(newShell);
66         newShell.setText(XDebugUIPlugin.getString("OpenLogDialog.title")); //$NON-NLS-1$
67         readConfiguration();
68     }
69
70     /*
71      * (non-Javadoc) Method declared on Dialog.
72      */
73     protected void createButtonsForButtonBar(Composite parent) {
74         createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL,
75                 true);
76     }
77
78     public void create() {
79         super.create();
80         // dialog location
81         if (dialogLocation != null)
82             getShell().setLocation(dialogLocation);
83         // dialog size
84         if (dialogSize != null)
85             getShell().setSize(dialogSize);
86         else
87             getShell().setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
88         getButton(IDialogConstants.CLOSE_ID).setFocus();
89     }
90
91     /*
92      * (non-Javadoc) Method declared on Dialog.
93      */
94     protected Control createDialogArea(Composite parent) {
95         Composite outer = (Composite) super.createDialogArea(parent);
96         Text text = new Text(outer, SWT.MULTI | SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL
97                 | SWT.NO_FOCUS | SWT.H_SCROLL);
98         text.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
99         GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL
100                 | GridData.VERTICAL_ALIGN_FILL);
101         gridData.grabExcessVerticalSpace = true;
102         gridData.grabExcessHorizontalSpace = true;
103         text.setLayoutData(gridData);
104         text.setText(getLogSummary());
105         return outer;
106     }
107
108     private String getLogSummary() {
109         StringWriter out = new StringWriter();
110         PrintWriter writer = new PrintWriter(out);
111         if (logFile.length() > LogReader.MAX_FILE_LENGTH) {
112             readLargeFileWithMonitor(writer);
113         } else {
114             readFileWithMonitor(writer);
115         }
116         writer.close();
117         return out.toString();
118     }
119
120     /*
121      * (non-Javadoc)
122      * 
123      * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
124      */
125     protected void buttonPressed(int buttonId) {
126         if (buttonId == IDialogConstants.CLOSE_ID) {
127             storeSettings();
128             close();
129         }
130         super.buttonPressed(buttonId);
131     }
132
133     //--------------- configuration handling --------------
134     /**
135      * Stores the current state in the dialog settings.
136      * 
137      * @since 2.0
138      */
139     private void storeSettings() {
140         writeConfiguration();
141     }
142
143     /**
144      * Returns the dialog settings object used to share state between several
145      * event detail dialogs.
146      * 
147      * @return the dialog settings to be used
148      */
149     private IDialogSettings getDialogSettings() {
150         IDialogSettings settings = XDebugCorePlugin.getDefault().getDialogSettings();
151         dialogSettings = settings.getSection(getClass().getName());
152         if (dialogSettings == null)
153             dialogSettings = settings.addNewSection(getClass().getName());
154         return dialogSettings;
155     }
156
157     /**
158      * Initializes itself from the dialog settings with the same state as at the
159      * previous invocation.
160      */
161     private void readConfiguration() {
162         IDialogSettings s = getDialogSettings();
163         try {
164             int x = s.getInt("x"); //$NON-NLS-1$
165             int y = s.getInt("y"); //$NON-NLS-1$
166             dialogLocation = new Point(x, y);
167             x = s.getInt("width"); //$NON-NLS-1$
168             y = s.getInt("height"); //$NON-NLS-1$
169             dialogSize = new Point(x, y);
170         } catch (NumberFormatException e) {
171             dialogLocation = null;
172             dialogSize = null;
173         }
174     }
175
176     private void writeConfiguration() {
177         IDialogSettings s = getDialogSettings();
178         Point location = getShell().getLocation();
179         s.put("x", location.x); //$NON-NLS-1$
180         s.put("y", location.y); //$NON-NLS-1$
181         Point size = getShell().getSize();
182         s.put("width", size.x); //$NON-NLS-1$
183         s.put("height", size.y); //$NON-NLS-1$
184     }
185
186     // reading file within MAX_FILE_LENGTH size
187     private void readFile(PrintWriter writer) throws FileNotFoundException, IOException {
188         BufferedReader bReader = new BufferedReader(new FileReader(logFile));
189         while (bReader.ready())
190             writer.println(bReader.readLine());
191     }
192
193     // reading large files
194     private void readLargeFile(PrintWriter writer) throws FileNotFoundException,
195             IOException {
196         RandomAccessFile random = null;
197         boolean hasStarted = false;
198         try {
199             random = new RandomAccessFile(logFile, "r"); //$NON-NLS-1$
200             random.seek(logFile.length() - LogReader.MAX_FILE_LENGTH);
201             for (;;) {
202                 String line = random.readLine();
203                 if (line == null)
204                     break;
205                 line = line.trim();
206                 if (line.length() == 0)
207                     continue;
208                 if (!hasStarted
209                         && (line.startsWith("!ENTRY") || line.startsWith("!SESSION"))) //$NON-NLS-1$ //$NON-NLS-2$
210                     hasStarted = true;
211                 if (hasStarted)
212                     writer.println(line);
213                 continue;
214             }
215         } finally {
216             try {
217                 if (random != null)
218                     random.close();
219             } catch (IOException e1) {
220             }
221         }
222     }
223
224     private void readLargeFileWithMonitor(final PrintWriter writer) {
225         IRunnableWithProgress runnable = new IRunnableWithProgress() {
226             public void run(IProgressMonitor monitor) throws InvocationTargetException,
227                     InterruptedException {
228                 monitor
229                         .beginTask(
230                                 XDebugUIPlugin.getString("OpenLogDialog.message"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$
231                 try {
232                     readLargeFile(writer);
233                 } catch (IOException e) {
234                     writer.println(XDebugUIPlugin.getString("OpenLogDialog.cannotDisplay")); //$NON-NLS-1$
235                 }
236             }
237         };
238         ProgressMonitorDialog dialog = new ProgressMonitorDialog(getParentShell());
239         try {
240             dialog.run(true, true, runnable);
241         } catch (InvocationTargetException e) {
242         } catch (InterruptedException e) {
243         }
244     }
245
246     private void readFileWithMonitor(final PrintWriter writer) {
247         IRunnableWithProgress runnable = new IRunnableWithProgress() {
248             public void run(IProgressMonitor monitor) throws InvocationTargetException,
249                     InterruptedException {
250                 monitor
251                         .beginTask(
252                                 XDebugUIPlugin
253                                         .getString("OpenLogDialog.message"), IProgressMonitor.UNKNOWN); //$NON-NLS-1$
254                 try {
255                     readFile(writer);
256                 } catch (IOException e) {
257                     writer.println(XDebugUIPlugin
258                             .getString("OpenLogDialog.cannotDisplay")); //$NON-NLS-1$
259                 }
260             }
261         };
262         ProgressMonitorDialog dialog = new ProgressMonitorDialog(getParentShell());
263         try {
264             dialog.run(true, true, runnable);
265         } catch (InvocationTargetException e) {
266         } catch (InterruptedException e) {
267         }
268     }
269 }