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