KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ant > internal > ui > launchConfigurations > RemoteAntBuildListener


1 /*******************************************************************************
2  * Copyright (c) 2003, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.ant.internal.ui.launchConfigurations;
13
14 import java.io.BufferedReader JavaDoc;
15 import java.io.File JavaDoc;
16 import java.io.IOException JavaDoc;
17 import java.io.InputStreamReader JavaDoc;
18 import java.net.ServerSocket JavaDoc;
19 import java.net.Socket JavaDoc;
20 import java.net.SocketException JavaDoc;
21 import java.net.SocketTimeoutException JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.StringTokenizer JavaDoc;
28
29 import org.apache.tools.ant.Project;
30 import org.apache.tools.ant.util.FileUtils;
31 import org.eclipse.ant.internal.core.AbstractEclipseBuildLogger;
32 import org.eclipse.ant.internal.ui.AntUIPlugin;
33 import org.eclipse.ant.internal.ui.AntUtil;
34 import org.eclipse.ant.internal.ui.ExternalHyperlink;
35 import org.eclipse.ant.internal.ui.IAntUIConstants;
36 import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants;
37 import org.eclipse.core.resources.IFile;
38 import org.eclipse.core.runtime.ISafeRunnable;
39 import org.eclipse.debug.core.DebugPlugin;
40 import org.eclipse.debug.core.ILaunch;
41 import org.eclipse.debug.core.ILaunchesListener;
42 import org.eclipse.debug.core.model.IProcess;
43 import org.eclipse.debug.ui.console.FileLink;
44 import org.eclipse.jface.preference.IPreferenceStore;
45 import org.eclipse.jface.text.Region;
46 import org.eclipse.ui.console.IHyperlink;
47
48 /**
49  * Parts adapted from org.eclipse.jdt.internal.junit.ui.RemoteTestRunnerClient
50  * The client side of the RemoteAntBuildLogger. Handles the
51  * marshalling of the different messages.
52  */

53 public class RemoteAntBuildListener implements ILaunchesListener {
54     public abstract class ListenerSafeRunnable implements ISafeRunnable {
55         public void handleException(Throwable JavaDoc exception) {
56             AntUIPlugin.log(exception);
57         }
58     }
59
60     /**
61      * The server socket
62      */

63     private ServerSocket JavaDoc fServerSocket;
64     private Socket JavaDoc fSocket;
65     private BufferedReader JavaDoc fBufferedReader;
66     private IProcess fProcess;
67     private String JavaDoc fProcessId;
68     private File JavaDoc fBuildFileParent= null;
69     private List JavaDoc fMessageQueue;
70     protected ILaunch fLaunch;
71     private Map JavaDoc fFileNameToIFile= new HashMap JavaDoc();
72     private String JavaDoc fLastFileName= null;
73     private String JavaDoc fLastTaskName= null;
74     private boolean fBuildFailed= false;
75     
76     /**
77      * Reads the message stream from the RemoteAntBuildLogger
78      */

79     private class ServerConnection extends Thread JavaDoc {
80         private int fServerPort;
81         
82         public ServerConnection(int port) {
83             super("Ant Build Server Connection"); //$NON-NLS-1$
84
setDaemon(true);
85             fServerPort= port;
86         }
87         
88         public void run() {
89             Exception JavaDoc exception= null;
90             try {
91                 fServerSocket= new ServerSocket JavaDoc(fServerPort);
92                 IPreferenceStore prefs = AntUIPlugin.getDefault().getPreferenceStore();
93                 int socketTimeout= prefs.getInt(IAntUIPreferenceConstants.ANT_COMMUNICATION_TIMEOUT);
94                 fServerSocket.setSoTimeout(socketTimeout);
95                 fSocket= fServerSocket.accept();
96                 fBufferedReader= new BufferedReader JavaDoc(new InputStreamReader JavaDoc(fSocket.getInputStream()));
97                 String JavaDoc message;
98                 while(fBufferedReader != null && (message= fBufferedReader.readLine()) != null) {
99                     receiveMessage(message);
100                 }
101             } catch (SocketException JavaDoc e) {
102             } catch (SocketTimeoutException JavaDoc e) {
103                 exception= e;
104             } catch (IOException JavaDoc e) {
105                 // fall through
106
exception= e;
107             }
108             if (exception != null) {
109                 AntUIPlugin.log(exception);
110             }
111             shutDown();
112         }
113     }
114     
115     public RemoteAntBuildListener(ILaunch launch) {
116         super();
117         fLaunch= launch;
118         DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
119     }
120
121     /**
122      * Start listening to an Ant build. Start a server connection that
123      * the RemoteAntBuildLogger can connect to.
124      *
125      * @param eventPort The port number to create the server connection on
126      */

127     public synchronized void startListening(int eventPort){
128         ServerConnection connection = new ServerConnection(eventPort);
129         connection.start();
130     }
131
132     protected synchronized void shutDown() {
133         fLaunch= null;
134         fFileNameToIFile= null;
135         if (DebugPlugin.getDefault() != null) {
136             DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this);
137         }
138         try {
139             if (fBufferedReader != null) {
140                 fBufferedReader.close();
141                 fBufferedReader= null;
142             }
143         } catch(IOException JavaDoc e) {
144         }
145         try{
146             if(fSocket != null) {
147                 fSocket.close();
148                 fSocket= null;
149             }
150         } catch(IOException JavaDoc e) {
151         }
152         try{
153             if(fServerSocket != null) {
154                 fServerSocket.close();
155                 fServerSocket= null;
156             }
157         } catch(IOException JavaDoc e) {
158         }
159     }
160         
161     protected void receiveMessage(String JavaDoc message) {
162         if (message.startsWith(MessageIds.TASK)) {
163             receiveTaskMessage(message);
164         } else if (message.startsWith(MessageIds.TARGET)) {
165             receiveTargetMessage(message);
166         } else if (message.startsWith(MessageIds.PROCESS_ID)) {
167             message= message.substring(MessageIds.PROCESS_ID.length());
168             fProcessId= message;
169         } else {
170             int index= message.indexOf(',');
171             if (index > 0) {
172                 int priority= Integer.parseInt(message.substring(0, index));
173                 message= message.substring(index + 1);
174                 
175                 writeMessage(message + System.getProperty("line.separator"), priority); //$NON-NLS-1$
176
if (message.startsWith("BUILD FAILED")) { //$NON-NLS-1$
177
fBuildFailed= true;
178                 } else if (fBuildFailed) {
179                     if (message.startsWith("Total time:")) { //$NON-NLS-1$
180
fBuildFailed= false;
181                     } else {
182                         AntUtil.linkBuildFailedMessage(message, getProcess());
183                     }
184                 }
185             }
186         }
187     }
188
189     private void receiveTargetMessage(String JavaDoc message) {
190         message= message.substring(MessageIds.TARGET.length());
191         StringTokenizer JavaDoc tokenizer= new StringTokenizer JavaDoc(message, ","); //$NON-NLS-1$
192
message= tokenizer.nextToken();
193         if (tokenizer.hasMoreTokens()) {
194             int locationLength= Integer.parseInt(tokenizer.nextToken());
195             String JavaDoc location= tokenizer.nextToken();
196             while (location.length() < locationLength) { //path with a comma in it
197
location+=","; //$NON-NLS-1$
198
location+= tokenizer.nextToken();
199             }
200             int lineNumber= Integer.parseInt(tokenizer.nextToken());
201             generateLink(message, location, lineNumber, 0, message.length() - 1);
202         }
203         writeMessage(message + System.getProperty("line.separator"), Project.MSG_INFO); //$NON-NLS-1$
204
}
205
206     private void receiveTaskMessage(String JavaDoc message) {
207         message= message.substring(MessageIds.TASK.length());
208         
209         int index= message.indexOf(',');
210         int priority= Integer.parseInt(message.substring(0, index));
211         int index2= message.indexOf(',', index + 1);
212         String JavaDoc taskName= message.substring(index + 1, index2);
213         if (taskName.length() == 0) {
214             taskName= fLastTaskName;
215         }
216         int index3= message.indexOf(',', index2 + 1);
217         int lineLength= Integer.parseInt(message.substring(index2 + 1, index3));
218         int index4= index3 + 1 + lineLength;
219         
220         String JavaDoc line= message.substring(index3 + 1, index4);
221         StringBuffer JavaDoc labelBuff= new StringBuffer JavaDoc();
222         labelBuff.append('[');
223         labelBuff.append(taskName);
224         labelBuff.append("] "); //$NON-NLS-1$
225
labelBuff.append(line);
226         line= labelBuff.toString();
227         
228         fLastTaskName= taskName;
229         
230         int locationIndex= message.indexOf(',', index4 + 1);
231         int finalIndex= locationIndex + 1;
232         String JavaDoc fileName= message.substring(index4 + 1, locationIndex);
233         int locationLength= 0;
234         if (fileName.length() == 0) {
235             fileName= fLastFileName;
236         } else {
237             finalIndex= message.indexOf(',', locationIndex) + 1;
238             locationLength= Integer.parseInt(fileName);
239             fileName= message.substring(finalIndex, finalIndex + locationLength);
240             locationLength+=1; //set past delimiter
241
}
242         fLastFileName= fileName;
243         int lineNumber= Integer.parseInt(message.substring(finalIndex + locationLength));
244
245         int size = IAntUIConstants.LEFT_COLUMN_SIZE - (taskName.length() + 3);
246         int offset = Math.max(size - 2, 1);
247         int length = IAntUIConstants.LEFT_COLUMN_SIZE - size - 3;
248         if (fileName != null) {
249             generateLink(line, fileName, lineNumber, offset, length);
250         }
251         
252         StringBuffer JavaDoc fullMessage= new StringBuffer JavaDoc();
253         adornMessage(taskName, line, fullMessage);
254         writeMessage(fullMessage.append(System.getProperty("line.separator")).toString(), priority); //$NON-NLS-1$
255
}
256
257     private void generateLink(String JavaDoc line, String JavaDoc fileName, int lineNumber, int offset, int length) {
258         IHyperlink taskLink= null;
259         if (lineNumber == -1) {
260             //fileName will actually be the String representation of Location
261
taskLink = AntUtil.getLocationLink(fileName, fBuildFileParent);
262         } else {
263             IFile file= (IFile) fFileNameToIFile.get(fileName);
264             if (file == null) {
265                 file= AntUtil.getFileForLocation(fileName, fBuildFileParent);
266                 if (file != null) {
267                     fFileNameToIFile.put(fileName, file);
268                     taskLink= new FileLink(file, null, -1, -1, lineNumber);
269                 } else {
270                     File JavaDoc javaIOFile= FileUtils.getFileUtils().resolveFile(fBuildFileParent, fileName);
271                     if (javaIOFile.exists()) {
272                         taskLink= new ExternalHyperlink(javaIOFile, lineNumber);
273                     }
274                 }
275             } else {
276                 taskLink= new FileLink(file, null, -1, -1, lineNumber);
277             }
278         }
279         if (taskLink != null) {
280             TaskLinkManager.addTaskHyperlink(getProcess(), taskLink, new Region(offset, length), line);
281         }
282     }
283     
284     /**
285      * Returns the associated process, finding it if necessary.
286      */

287     protected IProcess getProcess() {
288         if (fProcess == null) {
289             if (fProcessId != null) {
290                 IProcess[] all = DebugPlugin.getDefault().getLaunchManager().getProcesses();
291                 for (int i = 0; i < all.length; i++) {
292                     IProcess process = all[i];
293                     if (fProcessId.equals(process.getAttribute(AbstractEclipseBuildLogger.ANT_PROCESS_ID))) {
294                         fProcess = process;
295                         break;
296                     }
297                 }
298             }
299         }
300         return fProcess;
301     }
302     
303     private AntStreamMonitor getMonitor(int priority) {
304         IProcess process= getProcess();
305         if (process == null) {
306             return null;
307         }
308         AntStreamsProxy proxy = (AntStreamsProxy)process.getStreamsProxy();
309         if (proxy == null) {
310             return null;
311         }
312         AntStreamMonitor monitor = null;
313         switch (priority) {
314             case Project.MSG_INFO:
315                 monitor = (AntStreamMonitor)proxy.getOutputStreamMonitor();
316                 break;
317             case Project.MSG_ERR:
318                 monitor = (AntStreamMonitor)proxy.getErrorStreamMonitor();
319                 break;
320             case Project.MSG_DEBUG:
321                 monitor = (AntStreamMonitor)proxy.getDebugStreamMonitor();
322                 break;
323             case Project.MSG_WARN:
324                 monitor = (AntStreamMonitor)proxy.getWarningStreamMonitor();
325                 break;
326             case Project.MSG_VERBOSE:
327                 monitor = (AntStreamMonitor)proxy.getVerboseStreamMonitor();
328                 break;
329         }
330         return monitor;
331     }
332     
333     /**
334      * Builds a right justified task prefix for the given build event, placing it
335      * in the given string buffer.
336      *
337      * @param event build event
338      * @param fullMessage buffer to place task prefix in
339      */

340     private void adornMessage(String JavaDoc taskName, String JavaDoc line, StringBuffer JavaDoc fullMessage) {
341         if (taskName == null) {
342             taskName = "null"; //$NON-NLS-1$
343
}
344         
345         int size = IAntUIConstants.LEFT_COLUMN_SIZE - (taskName.length() + 6);
346         for (int i = 0; i < size; i++) {
347             fullMessage.append(' ');
348         }
349         
350         fullMessage.append(line);
351     }
352     
353     protected void writeMessage(String JavaDoc message, int priority) {
354         AntStreamMonitor monitor= getMonitor(priority);
355         if (monitor == null) {
356             if (fMessageQueue == null) {
357                 fMessageQueue= new ArrayList JavaDoc();
358             }
359             fMessageQueue.add(message);
360             return;
361         }
362         if (fMessageQueue != null) {
363             for (Iterator JavaDoc iter = fMessageQueue.iterator(); iter.hasNext();) {
364                 String JavaDoc oldMessage = (String JavaDoc) iter.next();
365                 monitor.append(oldMessage);
366             }
367             fMessageQueue= null;
368         }
369         monitor.append(message);
370     }
371     
372     /* (non-Javadoc)
373      * @see org.eclipse.debug.core.ILaunchesListener#launchesAdded(org.eclipse.debug.core.ILaunch[])
374      */

375     public void launchesAdded(ILaunch[] launches) {
376     }
377
378     /* (non-Javadoc)
379      * @see org.eclipse.debug.core.ILaunchesListener#launchesChanged(org.eclipse.debug.core.ILaunch[])
380      */

381     public void launchesChanged(ILaunch[] launches) {
382     }
383
384     /* (non-Javadoc)
385      * @see org.eclipse.debug.core.ILaunchesListener#launchesRemoved(org.eclipse.debug.core.ILaunch[])
386      */

387     public void launchesRemoved(ILaunch[] launches) {
388         for (int i = 0; i < launches.length; i++) {
389             ILaunch launch = launches[i];
390             if (launch.equals(fLaunch)) {
391                 shutDown();
392                 return;
393             }
394         }
395     }
396 }
Popular Tags