package org.xtest.ui.wizards; import java.io.ByteArrayInputStream; import java.lang.reflect.InvocationTargetException; import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; import org.eclipse.jdt.ui.wizards.NewTypeWizardPage; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.views.contentoutline.ContentOutline; import org.eclipse.xtext.ui.editor.XtextEditor; import org.eclipse.xtext.ui.editor.model.IXtextDocument; /** * Custom wizard page for creating a new Xtest file. Similar to NewXtend2ClassWizardPage, but * removes the parts that are unneccessary for Xtest files. * * @author Michael Barry */ public class NewXtestFileWizardPage extends NewTypeWizardPage { /** * Default contents of a brand-new Xtest file. */ protected static final String DEFAULT_XTEST_FILE = "xtest test {\n assert true\n}"; private IResource resource; /** * Constructs a new Xtest file wizard page. */ public NewXtestFileWizardPage() { super(0, "New Xtest File"); this.setDescription("Create a new Xtest File"); } @Override public void createControl(Composite parent) { initializeDialogUnits(parent); Composite composite = new Composite(parent, SWT.NONE); composite.setFont(parent.getFont()); int cols = 4; GridLayout layout = new GridLayout(); layout.numColumns = cols; composite.setLayout(layout); createContainerControls(composite, cols); createPackageControls(composite, cols); createSeparator(composite, cols); createTypeNameControls(composite, cols); setControl(composite); } /** * Runs a new "Create Xtest file" Job * * @return The number of bytes created in the new file. */ public int createType() { final AtomicInteger size = new AtomicInteger(0); IRunnableWithProgress op = new CreateXtestFile(size, this); try { getContainer().run(true, false, op); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { Throwable realException = e.getTargetException(); MessageDialog.openError(getShell(), "Error creating Xtest File", realException.getMessage()); } return size.get(); } @Override public void createType(IProgressMonitor monitor) throws CoreException, InterruptedException { throw new UnsupportedOperationException(); } /** * Returns the newly created resource * * @return The newly created resource */ public IResource getResource() { return resource; } /** * Returns the selected resource from which this wizard was opened * * @param selection * The selection input * @return The selected resource from which this wizard was opened */ public IJavaElement getSelectedResource(IStructuredSelection selection) { IJavaElement elem = null; if (selection != null && !selection.isEmpty()) { Object o = selection.getFirstElement(); if (o == null) { } else if (o instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable) o; elem = (IJavaElement) adaptable.getAdapter(IJavaElement.class); if (elem == null) { elem = getPackage(adaptable); } } } if (elem == null) { IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow() .getActivePage(); IWorkbenchPart part = activePage.getActivePart(); if (part instanceof ContentOutline) { part = activePage.getActiveEditor(); } if (part instanceof XtextEditor) { IXtextDocument doc = ((XtextEditor) part).getDocument(); IFile file = doc.getAdapter(IFile.class); elem = getPackage(file); } } if (elem == null || elem.getElementType() == IJavaElement.JAVA_MODEL) { try { IJavaProject[] projects = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()) .getJavaProjects(); if (projects.length == 1) { elem = projects[0]; } } catch (JavaModelException e) { throw new RuntimeException(e.getMessage()); } } return elem; } @Override public String getTypeName() { String typeName2 = super.getTypeName(); return typeName2.endsWith(".xtest") ? typeName2 : typeName2 + ".xtest"; } @Override public void setVisible(boolean visible) { super.setVisible(visible); if (visible) { setFocus(); } } /* * @see NewContainerWizardPage#handleFieldChanged */ @Override protected void handleFieldChanged(String fieldName) { super.handleFieldChanged(fieldName); doStatusUpdate(); } /** * Initialize this wizard page from the selection provided. * * @param selection * The initially selected item */ protected void init(IStructuredSelection selection) { IJavaElement elem = getSelectedResource(selection); initContainerPage(elem); initTypePage(elem); } @Override protected IStatus typeNameChanged() { IStatus status = Status.OK_STATUS; IPackageFragment packageFragment = getPackageFragment(); if (packageFragment != null) { IResource resource = packageFragment.getResource(); if (resource instanceof IFolder) { IFolder folder = (IFolder) resource; if (folder.getFile(getTypeName()).exists()) { String packageName = ""; if (!packageFragment.isDefaultPackage()) { packageName = packageFragment.getElementName() + "."; } status = new StatusInfo(IStatus.ERROR, packageName + getTypeName() + " already exists."); } } } return status; } private void createXtestFile(IProgressMonitor monitor, AtomicInteger size) throws InvocationTargetException { // similar to NewXtend2ClassWizardPage.createXtendClass, although changed to work // specifically for xtest files try { if (monitor == null) { monitor = new NullProgressMonitor(); } IPackageFragment packageFragment = getPackageFragment(); if (!packageFragment.exists()) { try { IPackageFragmentRoot packageFragmentRoot = getPackageFragmentRoot(); String elementName = packageFragment.getElementName(); packageFragmentRoot.createPackageFragment(elementName, true, monitor); } catch (JavaModelException e) { displayError("Error creating package", e.getMessage()); } } IResource res = packageFragment.getResource(); IFile xtestFile = null; IFolder iFolder = (IFolder) res; String typeName = getTypeName(); xtestFile = iFolder.getFile(typeName); try { String contents = DEFAULT_XTEST_FILE; byte[] bytes = contents.getBytes(); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); xtestFile.create(byteArrayInputStream, true, monitor); int length = contents.length(); size.set(length); resource = xtestFile; } catch (CoreException e) { displayError("Error creating Xtest file", e.getMessage()); } } catch (Exception e) { throw new InvocationTargetException(e); } finally { monitor.done(); } } private void displayError(final String title, final String message) { Display.getDefault().syncExec(new Runnable() { @Override public void run() { MessageDialog.openError(getShell(), title, message); } }); } private void doStatusUpdate() { IStatus[] status = new IStatus[] { fContainerStatus, fPackageStatus, fTypeNameStatus, fSuperClassStatus, fSuperInterfacesStatus }; updateStatus(status); } private IJavaElement getPackage(IAdaptable adaptable) { IJavaElement elem = null; IResource resource = (IResource) adaptable.getAdapter(IResource.class); if (resource != null && resource.getType() != IResource.ROOT) { while (elem == null && resource.getType() != IResource.PROJECT) { resource = resource.getParent(); elem = (IJavaElement) resource.getAdapter(IJavaElement.class); } } if (elem == null) { elem = JavaCore.create(resource); } return elem; } private static class CreateXtestFile extends WorkspaceModifyOperation { private final NewXtestFileWizardPage page; private final AtomicInteger size; private CreateXtestFile(AtomicInteger size, NewXtestFileWizardPage page) { this.size = size; this.page = page; } @Override protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException { page.createXtestFile(monitor, size); } } }