Fixed #1721079 - Can not set breakpoint in different files on the same line
[phpeclipse.git] / net.sourceforge.phpeclipse.externaltools / src / net / sourceforge / phpdt / externaltools / internal / registry / ExternalToolMigration.java
1 package net.sourceforge.phpdt.externaltools.internal.registry;
2
3 /**********************************************************************
4  Copyright (c) 2002 IBM Corp. and others. All rights reserved.
5  This file is made available under the terms of the Common Public License v1.0
6  which accompanies this distribution, and is available at
7  http://www.eclipse.org/legal/cpl-v10.html
8  �
9  Contributors:
10  **********************************************************************/
11
12 import java.io.File;
13 import java.io.FileInputStream;
14 import java.io.FileNotFoundException;
15 import java.io.IOException;
16 import java.io.InputStreamReader;
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.Map;
20 import java.util.StringTokenizer;
21
22 import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
23 import net.sourceforge.phpdt.externaltools.model.ToolUtil;
24 import net.sourceforge.phpeclipse.externaltools.ExternalToolsPlugin;
25
26 import org.eclipse.core.runtime.CoreException;
27 import org.eclipse.core.runtime.IPath;
28 import org.eclipse.debug.core.DebugPlugin;
29 import org.eclipse.debug.core.ILaunchConfigurationType;
30 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
31 import org.eclipse.debug.core.ILaunchManager;
32 import org.eclipse.ui.IMemento;
33 import org.eclipse.ui.WorkbenchException;
34 import org.eclipse.ui.XMLMemento;
35
36 /**
37  * Responsible reading an old external tool format and creating and migrating it
38  * to create a new external tool.
39  */
40 public final class ExternalToolMigration {
41         private static final String SEPERATOR = ";"; //$NON-NLS-1$      
42
43         private static final String STATE_FILE_NAME_OLD = "oldexternaltools.xml"; //$NON-NLS-1$
44
45         private static final String STATE_FILE_NAME = "externaltools.xml"; //$NON-NLS-1$
46
47         private static final String TAG_EXTERNALTOOLS = "externaltools"; //$NON-NLS-1$
48
49         private static final String TAG_TOOL = "tool"; //$NON-NLS-1$
50
51         private static final String TAG_ENTRY = "entry"; //$NON-NLS-1$
52
53         // private static final String TAG_KEY = "key"; //$NON-NLS-1$
54         private static final String TAG_VALUE = "value"; //$NON-NLS-1$
55
56         /*
57          * Ant tags
58          */
59         // public static final String RUN_TARGETS_ATTRIBUTE =
60         // IExternalToolConstants.TOOL_TYPE_ANT_BUILD + ".runTargets";
61         // //$NON-NLS-1$;
62         /*
63          * 2.0 External Tool Tags
64          */
65         private static final String TAG_TOOL_TYPE = "!{tool_type}"; //$NON-NLS-1$
66
67         private static final String TAG_TOOL_NAME = "!{tool_name}"; //$NON-NLS-1$
68
69         private static final String TAG_TOOL_LOCATION = "!{tool_loc}"; //$NON-NLS-1$
70
71         private static final String TAG_TOOL_ARGUMENTS = "!{tool_args}"; //$NON-NLS-1$
72
73         private static final String TAG_TOOL_DIRECTORY = "!{tool_dir}"; //$NON-NLS-1$
74
75         private static final String TAG_TOOL_REFRESH = "!{tool_refresh}"; //$NON-NLS-1$
76
77         private static final String TAG_TOOL_SHOW_LOG = "!{tool_show_log}"; //$NON-NLS-1$
78
79         private static final String TAG_TOOL_BUILD_TYPES = "!{tool_build_types}"; //$NON-NLS-1$
80
81         private static final String TAG_TOOL_BLOCK = "!{tool_block}"; //$NON-NLS-1$
82
83         // Known kind of tools
84         private static final String TOOL_TYPE_PROGRAM = "net.sourceforge.phpdt.externaltools.type.program"; //$NON-NLS-1$
85
86         // private static final String TOOL_TYPE_ANT =
87         // "org.eclipse.ui.externaltools.type.ant"; //$NON-NLS-1$
88
89         /*
90          * 2.1 External Tool Keys
91          */
92         private static final String TAG_EXTERNAL_TOOL = "externalTool"; //$NON-NLS-1$
93
94         private static final String TAG_TYPE = "type"; //$NON-NLS-1$
95
96         private static final String TAG_NAME = "name"; //$NON-NLS-1$
97
98         private static final String TAG_LOCATION = "location"; //$NON-NLS-1$
99
100         private static final String TAG_WORK_DIR = "workDirectory"; //$NON-NLS-1$
101
102         private static final String TAG_CAPTURE_OUTPUT = "captureOutput"; //$NON-NLS-1$
103
104         private static final String TAG_SHOW_CONSOLE = "showConsole"; //$NON-NLS-1$
105
106         private static final String TAG_RUN_BKGRND = "runInBackground"; //$NON-NLS-1$
107
108         private static final String TAG_OPEN_PERSP = "openPerspective"; //$NON-NLS-1$
109
110         private static final String TAG_PROMPT_ARGS = "promptForArguments"; //$NON-NLS-1$
111
112         private static final String TAG_SHOW_MENU = "showInMenu"; //$NON-NLS-1$
113
114         private static final String TAG_SAVE_DIRTY = "saveDirtyEditors"; //$NON-NLS-1$
115
116         private static final String TAG_ARGS = "arguments"; //$NON-NLS-1$
117
118         private static final String TAG_REFRESH_SCOPE = "refreshScope"; //$NON-NLS-1$
119
120         private static final String TAG_REFRESH_RECURSIVE = "refreshRecursive"; //$NON-NLS-1$
121
122         private static final String TAG_RUN_BUILD_KINDS = "runForBuildKinds"; //$NON-NLS-1$
123
124         private static final String TAG_EXTRA_ATTR = "extraAttribute"; //$NON-NLS-1$
125
126         private static final String TAG_KEY = "key"; //$NON-NLS-1$
127
128         private static final String TAG_VERSION = "version"; //$NON-NLS-1$
129
130         private static final String BUILD_TYPE_SEPARATOR = ","; //$NON-NLS-1$
131
132         private static final String EXTRA_ATTR_SEPARATOR = "="; //$NON-NLS-1$
133
134         private static final String VERSION_21 = "2.1"; //$NON-NLS-1$;
135
136         private static final String TRUE = "true"; //$NON-NLS-1$
137
138         private static final String FALSE = "false"; //$NON-NLS-1$
139
140         /**
141          * Allows no instances.
142          */
143         private ExternalToolMigration() {
144                 super();
145         }
146
147         /**
148          * Loads the external tools from storage and adds them to the registry.
149          */
150         /* package */
151         // This method is not called. It is left here in case
152         // we decide to do tool migration in the future
153         private static void readInOldTools() {
154                 readIn20Tools();
155                 readIn21Tools();
156         }
157
158         private static void readIn21Tools() {
159         }
160
161         public static void readIn20Tools() {
162                 boolean migrationSuccessful = true;
163                 IPath path = ExternalToolsPlugin.getDefault().getStateLocation();
164                 File file = path.append(STATE_FILE_NAME).toFile();
165                 if (!file.exists())
166                         return;
167
168                 InputStreamReader reader = null;
169                 try {
170                         FileInputStream input = new FileInputStream(file);
171                         reader = new InputStreamReader(input, "utf-8"); //$NON-NLS-1$
172                         XMLMemento memento = XMLMemento.createReadRoot(reader);
173
174                         // Get the external tool children element
175                         IMemento[] tools = memento.getChildren(TAG_TOOL);
176                         for (int i = 0; i < tools.length; i++) {
177                                 HashMap args = new HashMap();
178                                 IMemento[] entries = tools[i].getChildren(TAG_ENTRY);
179                                 for (int j = 0; j < entries.length; j++) {
180                                         String key = entries[j].getString(TAG_KEY);
181                                         if (key != null) {
182                                                 String value = entries[j].getTextData();
183                                                 args.put(key, value);
184                                         }
185                                 }
186                                 ILaunchConfigurationWorkingCopy config = configFromArgumentMap(args);
187                                 if (config != null) {
188                                         try {
189                                                 config.doSave();
190                                         } catch (CoreException e) {
191                                                 // TODO: Decide what to do when saving fails.
192                                         }
193                                 }
194                         }
195                 } catch (FileNotFoundException e) {
196                         // Silently ignore this...
197                 } catch (IOException e) {
198                         ExternalToolsPlugin.getDefault().log(
199                                         "File I/O error with reading old external tools.", e);
200                         migrationSuccessful = false;
201                 } catch (WorkbenchException e) {
202                         ExternalToolsPlugin.getDefault().getLog().log(e.getStatus());
203                         System.err
204                                         .println("Error reading old external tools. See .log file for more details");
205                         migrationSuccessful = false;
206                 } finally {
207                         if (reader != null) {
208                                 try {
209                                         reader.close();
210                                 } catch (IOException e) {
211                                         ExternalToolsPlugin.getDefault().log(
212                                                         "Unable to close external tool old state reader.",
213                                                         e);
214                                 }
215                         }
216                 }
217
218                 if (migrationSuccessful) {
219                         if (!file.renameTo(path.append(STATE_FILE_NAME_OLD).toFile())) {
220                                 ExternalToolsPlugin
221                                                 .getDefault()
222                                                 .log(
223                                                                 "Unable to rename old external tool state file. Please rename externaltools.xml to oldexternaltools.xml manually.",
224                                                                 null);
225                                 System.err
226                                                 .println("Unable to rename old external tool state file. Please rename externaltools.xml to oldexternaltools.xml manually.");
227                         }
228                 }
229         }
230
231         /**
232          * Returns a launch configuration working copy from the argument map or
233          * <code>null</code> if the given map cannot be interpreted as a 2.0 or
234          * 2.1 branch external tool. The returned working copy will be unsaved and
235          * its location will be set to the metadata area.
236          */
237         public static ILaunchConfigurationWorkingCopy configFromArgumentMap(Map args) {
238                 String version = (String) args.get(TAG_VERSION);
239                 if (VERSION_21.equals(version)) {
240                         return configFrom21ArgumentMap(args);
241                 }
242                 return configFrom20ArgumentMap(args);
243         }
244
245         public static ILaunchConfigurationWorkingCopy configFrom21ArgumentMap(
246                         Map commandArgs) {
247                 String name = (String) commandArgs.get(TAG_NAME);
248                 String type = (String) commandArgs.get(TAG_TYPE);
249
250                 ILaunchConfigurationWorkingCopy config = newConfig(type, name);
251                 if (config == null) {
252                         return null;
253                 }
254
255                 config.setAttribute(IExternalToolConstants.ATTR_LOCATION,
256                                 (String) commandArgs.get(TAG_LOCATION));
257                 config.setAttribute(IExternalToolConstants.ATTR_WORKING_DIRECTORY,
258                                 (String) commandArgs.get(TAG_WORK_DIR));
259                 config.setAttribute(IExternalToolConstants.ATTR_CAPTURE_OUTPUT, TRUE
260                                 .equals((String) commandArgs.get(TAG_CAPTURE_OUTPUT)));
261                 config.setAttribute(IExternalToolConstants.ATTR_SHOW_CONSOLE, TRUE
262                                 .equals((String) commandArgs.get(TAG_SHOW_CONSOLE)));
263                 config.setAttribute(IExternalToolConstants.ATTR_RUN_IN_BACKGROUND, TRUE
264                                 .equals((String) commandArgs.get(TAG_RUN_BKGRND)));
265                 config.setAttribute(IExternalToolConstants.ATTR_PROMPT_FOR_ARGUMENTS,
266                                 TRUE.equals((String) commandArgs.get(TAG_PROMPT_ARGS)));
267                 config.setAttribute(IExternalToolConstants.ATTR_REFRESH_SCOPE,
268                                 (String) commandArgs.get(TAG_REFRESH_SCOPE));
269                 config.setAttribute(IExternalToolConstants.ATTR_REFRESH_RECURSIVE, TRUE
270                                 .equals((String) commandArgs.get(TAG_REFRESH_RECURSIVE)));
271
272                 config.setAttribute(IExternalToolConstants.ATTR_RUN_BUILD_KINDS,
273                                 (String) commandArgs.get(TAG_RUN_BUILD_KINDS));
274
275                 String args = (String) commandArgs.get(TAG_ARGS);
276                 if (args != null) {
277                         config.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS,
278                                         args);
279                 }
280
281                 String extraAttributes = (String) commandArgs.get(TAG_EXTRA_ATTR);
282                 if (extraAttributes != null) {
283                         StringTokenizer tokenizer = new StringTokenizer(extraAttributes,
284                                         EXTRA_ATTR_SEPARATOR);
285                         while (tokenizer.hasMoreTokens()) {
286                                 String key = tokenizer.nextToken();
287                                 if (!tokenizer.hasMoreTokens())
288                                         break;
289                                 String value = tokenizer.nextToken();
290                                 // if (key.equals(RUN_TARGETS_ATTRIBUTE)) {
291                                 // // 2.1 implementation only defined 1 "extra attribute"
292                                 // config.setAttribute(IExternalToolConstants.ATTR_ANT_TARGETS,
293                                 // value);
294                                 // }
295                         }
296                 }
297                 return config;
298         }
299
300         /**
301          * Creates an external tool from the map.
302          */
303         public static ILaunchConfigurationWorkingCopy configFrom20ArgumentMap(
304                         Map args) {
305                 // Update the type...
306                 String type = (String) args.get(TAG_TOOL_TYPE);
307                 // if (TOOL_TYPE_ANT.equals(type))
308                 // type = IExternalToolConstants.TOOL_TYPE_ANT_BUILD;
309                 // else
310                 type = IExternalToolConstants.TOOL_TYPE_PROGRAM;
311
312                 String name = (String) args.get(TAG_TOOL_NAME);
313
314                 ILaunchConfigurationWorkingCopy config = newConfig(type, name);
315                 if (config == null) {
316                         return null;
317                 }
318
319                 // Update the location...
320                 String location = (String) args.get(TAG_TOOL_LOCATION);
321                 if (location != null) {
322                         ToolUtil.VariableDefinition varDef = ToolUtil.extractVariableTag(
323                                         location, 0);
324                         if (IExternalToolConstants.VAR_WORKSPACE_LOC.equals(varDef.name)) {
325                                 location = ToolUtil.buildVariableTag(
326                                                 IExternalToolConstants.VAR_RESOURCE_LOC,
327                                                 varDef.argument);
328                         }
329                         config.setAttribute(IExternalToolConstants.ATTR_LOCATION, location);
330                 }
331
332                 // Update the refresh scope...
333                 String refresh = (String) args.get(TAG_TOOL_REFRESH);
334                 if (refresh != null) {
335                         ToolUtil.VariableDefinition varDef = ToolUtil.extractVariableTag(
336                                         refresh, 0);
337                         if ("none".equals(varDef.name)) { //$NON-NLS-1$
338                                 refresh = null;
339                         }
340                         config.setAttribute(IExternalToolConstants.ATTR_REFRESH_SCOPE,
341                                         refresh);
342                 }
343
344                 // Update the arguments
345                 String arguments = (String) args.get(TAG_TOOL_ARGUMENTS);
346                 String targetNames = null;
347                 if (arguments != null) {
348                         int start = 0;
349                         ArrayList targets = new ArrayList();
350                         StringBuffer buffer = new StringBuffer();
351                         ToolUtil.VariableDefinition varDef = ToolUtil.extractVariableTag(
352                                         arguments, start);
353                         while (varDef.end != -1) {
354                                 if ("ant_target".equals(varDef.name) && varDef.argument != null) { //$NON-NLS-1$
355                                         targets.add(varDef.argument);
356                                         buffer.append(arguments.substring(start, varDef.start));
357                                 } else {
358                                         buffer.append(arguments.substring(start, varDef.end));
359                                 }
360                                 start = varDef.end;
361                                 varDef = ToolUtil.extractVariableTag(arguments, start);
362                         }
363                         buffer.append(arguments.substring(start, arguments.length()));
364                         arguments = buffer.toString();
365
366                         buffer.setLength(0);
367                         for (int i = 0; i < targets.size(); i++) {
368                                 String target = (String) targets.get(i);
369                                 if (target != null && target.length() > 0) {
370                                         buffer.append(target);
371                                         buffer.append(","); //$NON-NLS-1$
372                                 }
373                         }
374                         targetNames = buffer.toString();
375                 }
376                 if (targetNames != null && targetNames.length() > 0) {
377                         config.setAttribute(IExternalToolConstants.ATTR_ANT_TARGETS,
378                                         targetNames);
379                 }
380
381                 // Collect the rest of the information
382                 config.setAttribute(IExternalToolConstants.ATTR_SHOW_CONSOLE, TRUE
383                                 .equals((String) args.get(TAG_TOOL_SHOW_LOG)));
384                 config.setAttribute(IExternalToolConstants.ATTR_CAPTURE_OUTPUT, TRUE
385                                 .equals((String) args.get(TAG_TOOL_SHOW_LOG)));
386                 config.setAttribute(IExternalToolConstants.ATTR_RUN_IN_BACKGROUND,
387                                 FALSE.equals((String) args.get(TAG_TOOL_BLOCK)));
388                 config.setAttribute(IExternalToolConstants.ATTR_RUN_BUILD_KINDS,
389                                 (String) args.get(TAG_TOOL_BUILD_TYPES));
390                 config.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS,
391                                 arguments);
392                 config.setAttribute(IExternalToolConstants.ATTR_WORKING_DIRECTORY,
393                                 (String) args.get(TAG_TOOL_DIRECTORY));
394                 return config;
395         }
396
397         /**
398          * Returns a new working copy with the given external tool name and external
399          * tool type or <code>null</code> if no config could be created.
400          */
401         private static ILaunchConfigurationWorkingCopy newConfig(String type,
402                         String name) {
403                 if (type == null || name == null) {
404                         return null;
405                 }
406                 ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
407                 ILaunchConfigurationType configType;
408                 // if (IExternalToolConstants.TOOL_TYPE_ANT_BUILD.equals(type)) {
409                 // configType =
410                 // manager.getLaunchConfigurationType(IExternalToolConstants.ID_ANT_BUILDER_LAUNCH_CONFIGURATION_TYPE);
411                 // } else
412                 if (IExternalToolConstants.TOOL_TYPE_PROGRAM.equals(type)) {
413                         configType = manager
414                                         .getLaunchConfigurationType(IExternalToolConstants.ID_PROGRAM_BUILDER_LAUNCH_CONFIGURATION_TYPE);
415                 } else {
416                         return null;
417                 }
418                 try {
419                         return configType.newInstance(null, name);
420                 } catch (CoreException e) {
421                         return null;
422                 }
423         }
424
425         /**
426          * Returns the tool name extracted from the given command argument map.
427          * Extraction is attempted using 2.0 and 2.1 external tool formats.
428          */
429         public static String getNameFromCommandArgs(Map commandArgs) {
430                 String name = (String) commandArgs.get(TAG_NAME);
431                 if (name == null) {
432                         name = (String) commandArgs.get(TAG_TOOL_NAME);
433                 }
434                 return name;
435         }
436
437 }