blob: 8faa2ea5bb0b14d3f4b4d4a25833bc3b9be554ee [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 Chase Technology Ltd - http://www.chasetechnology.co.uk
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Doug Satchwell (Chase Technology Ltd) - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.xsl.internal.debug.ui;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.ILaunchShortcut;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.StatusDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.wst.xsl.core.XSLCore;
import org.eclipse.wst.xsl.internal.debug.ui.tabs.main.InputFileBlock;
import org.eclipse.wst.xsl.launching.XSLLaunchConfigurationConstants;
import org.eclipse.wst.xsl.launching.config.BaseLaunchHelper;
import org.eclipse.wst.xsl.launching.config.LaunchPipeline;
import org.eclipse.wst.xsl.launching.config.LaunchTransform;
import org.eclipse.wst.xsl.debug.ui.Messages;
/**
* <table border=1>
* <th>
* <tr>
* <td>XML Files</td>
* <td>XSL Files</td>
* <td>Action</td>
* </tr>
* </th>
* <tbody>
* <tr>
* <td>1</td>
* <td>0</td>
* <td>Launch assuming embedded stylesheet instruction</td>
* </tr>
* <tr>
* <td>0</td>
* <td>&gt;=1</td>
* <td>Open dialog - prompt for input file</td>
* </tr>
* <tr>
* <td>1</td>
* <td>&gt;=1</td>
* <td>Launch</td>
* </tr>
* </tbody>
* </table>
*
* <p>The launch shortcut should not appear in the menu for any other combination of files</p>
* <p>In all cases, a check must be performed to find any existing launch configuration that uses the selected files.</p>
*
* @author Doug
* @since 1.0
*/
public class XSLLaunchShortcut implements ILaunchShortcut
{
private IFile xmlFile;
private IPath xmlFilePath;
private IFile[] xslFiles;
public void launch(ISelection selection, String mode)
{
if (selection instanceof IStructuredSelection)
{
IStructuredSelection ssel = (IStructuredSelection)selection;
searchAndLaunch(ssel.toArray(),mode);
}
}
public void launch(IEditorPart editor, String mode)
{
IEditorInput input = editor.getEditorInput();
if (input != null)
{
IFile file = (IFile) input.getAdapter(IFile.class);
if (file != null)
searchAndLaunch(new Object[]{ file }, mode);
}
}
private void searchAndLaunch(Object[] objects, String mode)
{
if (fillFiles(objects))
{
// ensure we have an input file
if (xmlFile == null)
promptForInput();
if (xmlFile != null || xmlFilePath != null)
launch(mode);
}
}
private void promptForInput()
{
// prompt for input xml file
StatusDialog dialog = new StatusDialog(getShell()){
private InputFileBlock inputFileBlock = new InputFileBlock(null);
@Override
protected Control createDialogArea(Composite parent)
{
Composite comp = (Composite)super.createDialogArea(parent);
comp.setFont(parent.getFont());
GridLayout layout = new GridLayout(1, false);
comp.setLayout(layout);
Label label = new Label(comp,SWT.NONE);
label.setFont(comp.getFont());
GridData gd = new GridData();
gd.horizontalIndent = 5;
gd.verticalIndent = 5;
gd.widthHint = 380;
label.setLayoutData(gd);
label.setText(Messages.getString("XSLLaunchShortcut.0")); //$NON-NLS-1$
inputFileBlock.createControl(comp);
return comp;
}
@Override
protected void okPressed()
{
IResource res = inputFileBlock.getResource();
if (res == null)
xmlFilePath = new Path(inputFileBlock.getText());
else if (ResourcesPlugin.getWorkspace().getRoot().exists(res.getFullPath()) && res.getType() == IResource.FILE)
xmlFile = (IFile)res;
super.okPressed();
}
};
dialog.setHelpAvailable(false);
dialog.setStatusLineAboveButtons(true);
dialog.setTitle(Messages.getString("XSLLaunchShortcut.1")); //$NON-NLS-1$
dialog.open();
}
private boolean fillFiles(Object[] selections)
{
xmlFile = null;
xmlFilePath = null;
List<IFile> xslFileList = new ArrayList<IFile>();
for (Object object : selections)
{
IResource resource = (IResource)object;
if (resource.getType() == IResource.FILE)
{
IFile file = (IFile)resource;
if (XSLCore.isXMLFile(file))
{
if (XSLCore.isXSLFile(file))
xslFileList.add(file);
else if (xmlFile==null)
xmlFile = file;
else
return false; // no action if we have more than than 1 xml file
}
}
}
xslFiles = xslFileList.toArray(new IFile[0]);
return true;
}
private void launch(String mode)
{
if (xmlFile!=null)
xmlFilePath = xmlFile.getLocation();
ILaunchConfiguration config = null;
try
{
config = findOrCreateLaunchConfiguration();
if (config!=null)
DebugUITools.launch(config, mode);
}
catch (CoreException e)
{
XSLDebugUIPlugin.log(e);
}
}
private ILaunchManager getLaunchManager()
{
return DebugPlugin.getDefault().getLaunchManager();
}
private ILaunchConfigurationType getConfigurationType()
{
return getLaunchManager().getLaunchConfigurationType(XSLLaunchConfigurationConstants.ID_LAUNCH_CONFIG_TYPE);
}
private ILaunchConfiguration findOrCreateLaunchConfiguration() throws CoreException
{
ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations(getConfigurationType());
List<ILaunchConfiguration> candidateConfigs = new ArrayList<ILaunchConfiguration>(configs.length);
for (ILaunchConfiguration config : configs)
{
String inputFile = config.getAttribute(XSLLaunchConfigurationConstants.ATTR_INPUT_FILE, (String) null);
try
{
inputFile = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(inputFile);
}
catch (CoreException e)
{
// just ignore this one
continue;
}
Path path = new Path(inputFile);
// the source xml file must be the same
if (path.equals(xmlFilePath))
{
BaseLaunchHelper lh = new BaseLaunchHelper(config);
// all the selected stylesheets must be in the pipeline
boolean found = false;
for (IFile stylesheet : xslFiles)
{
found = false;
for (Iterator<LaunchTransform> iter = lh.getPipeline().getTransformDefs().iterator(); iter.hasNext();)
{
LaunchTransform lt = iter.next();
if (lt.getLocation().equals(stylesheet.getLocation()))
{
found = true;
break;
}
}
if (!found)
break;
}
if (found)
candidateConfigs.add(config);
}
}
ILaunchConfiguration config = null;
int candidateCount = candidateConfigs.size();
if (candidateCount == 1)
config = (ILaunchConfiguration)candidateConfigs.get(0);
else if (candidateCount > 1)
config = chooseConfiguration(candidateConfigs);
else
config = createConfiguration();
return config;
}
private ILaunchConfiguration chooseConfiguration(List<ILaunchConfiguration> configList)
{
IDebugModelPresentation labelProvider = DebugUITools.newDebugModelPresentation();
ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), labelProvider);
dialog.setElements(configList.toArray());
dialog.setTitle(Messages.getString("XSLLaunchShortcut.2")); //$NON-NLS-1$
dialog.setMessage("&Select existing configuration:"); //$NON-NLS-1$
dialog.setMultipleSelection(false);
int result = dialog.open();
labelProvider.dispose();
if (result == Window.OK)
{
return (ILaunchConfiguration) dialog.getFirstResult();
}
return null;
}
private ILaunchConfiguration createConfiguration()
{
ILaunchConfiguration config = null;
try
{
ILaunchConfigurationType configType = getConfigurationType();
ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, getLaunchManager().generateUniqueLaunchConfigurationNameFrom(xmlFilePath.lastSegment()));
if (xmlFile != null)
wc.setAttribute(XSLLaunchConfigurationConstants.ATTR_INPUT_FILE, "${workspace_loc:" + xmlFile.getFullPath().toPortableString()+"}"); //$NON-NLS-1$ //$NON-NLS-2$
else
wc.setAttribute(XSLLaunchConfigurationConstants.ATTR_INPUT_FILE, xmlFilePath.toPortableString());
wc.setAttribute(XSLLaunchConfigurationConstants.ATTR_USE_DEFAULT_OUTPUT_FILE, true);
wc.setAttribute(XSLLaunchConfigurationConstants.ATTR_OPEN_FILE, true);
LaunchPipeline pipeline = new LaunchPipeline();
for (IFile element : xslFiles)
{
pipeline.addTransformDef(new LaunchTransform(element.getFullPath().toPortableString(), LaunchTransform.RESOURCE_TYPE));
}
wc.setAttribute(XSLLaunchConfigurationConstants.ATTR_PIPELINE, pipeline.toXML());
if (xmlFile!=null)
wc.setMappedResources(new IResource[]{ xmlFile.getProject() });
config = wc.doSave();
}
catch (CoreException exception)
{
MessageDialog.openError(getShell(), Messages.getString("XSLLaunchShortcut.6"), exception.getStatus().getMessage()); //$NON-NLS-1$
}
return config;
}
protected Shell getShell()
{
return XSLDebugUIPlugin.getActiveWorkbenchShell();
}
}