/** * Copyright (c) 2013 Stefan Prisca. * 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: * Stefan Prisca - initial API and implementation */ package org.eclipse.recommenders.snipmatch.rcp; import static com.google.common.base.Strings.isNullOrEmpty; import static java.util.Arrays.asList; import static java.util.UUID.randomUUID; import static org.eclipse.recommenders.snipmatch.Location.*; import static org.eclipse.recommenders.utils.Checks.ensureIsInstanceOf; import java.io.IOException; import java.text.MessageFormat; import java.util.List; import javax.inject.Inject; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.recommenders.internal.snipmatch.rcp.Constants; import org.eclipse.recommenders.internal.snipmatch.rcp.Repositories; import org.eclipse.recommenders.internal.snipmatch.rcp.SelectRepositoryDialog; import org.eclipse.recommenders.internal.snipmatch.rcp.editors.JavaSnippetSourceValidator; import org.eclipse.recommenders.internal.snipmatch.rcp.editors.TextSnippetSourceValidator; import org.eclipse.recommenders.internal.snipmatch.rcp.l10n.LogMessages; import org.eclipse.recommenders.internal.snipmatch.rcp.l10n.Messages; import org.eclipse.recommenders.snipmatch.ISnippet; import org.eclipse.recommenders.snipmatch.ISnippetRepository; import org.eclipse.recommenders.snipmatch.Snippet; import org.eclipse.recommenders.snipmatch.rcp.model.SnippetRepositoryConfigurations; import org.eclipse.recommenders.utils.Logs; import org.eclipse.swt.SWT; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.forms.AbstractFormPart; import org.eclipse.ui.forms.IFormPart; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.editor.IFormPage; import com.google.common.base.Function; import com.google.common.collect.Lists; import com.google.common.collect.Ordering; public class SnippetEditor extends FormEditor implements IResourceChangeListener { private static final int DEFAULT_PRIORITY = 100; private final Repositories repos; private final SnippetRepositoryConfigurations configs; @Inject public SnippetEditor(Repositories repos, SnippetRepositoryConfigurations configs) { this.repos = repos; this.configs = configs; ResourcesPlugin.getWorkspace().addResourceChangeListener(this); } @Override public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException { ensureIsInstanceOf(editorInput, SnippetEditorInput.class); setPartName(editorInput.getName()); super.init(site, editorInput); } @Override public void setFocus() { super.setFocus(); IFormPage activePage = getActivePageInstance(); if (activePage == null) { return; } activePage.setFocus(); } @Override protected void addPages() { try { for (IFormPage page : readExtensionPoint(this)) { addPage(page); } } catch (PartInitException e) { Logs.log(LogMessages.ERROR_FAILED_TO_LOAD_EDITOR_PAGE, e); } } private static List<IFormPage> readExtensionPoint(SnippetEditor editor) { IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor( Constants.EXT_POINT_PAGE_FACTORIES); List<IFormPage> pages = Lists.newLinkedList(); for (final IConfigurationElement element : Ordering.natural() .onResultOf(new Function<IConfigurationElement, Integer>() { @Override public Integer apply(IConfigurationElement element) { String priorityString = element.getAttribute("priority"); //$NON-NLS-1$ return priorityString == null ? DEFAULT_PRIORITY : Integer.parseInt(priorityString); } }).sortedCopy(asList(elements))) { try { String id = element.getAttribute("id"); //$NON-NLS-1$ String name = element.getAttribute("name"); //$NON-NLS-1$ ISnippetEditorPageFactory pageFactory; pageFactory = (ISnippetEditorPageFactory) element.createExecutableExtension("class"); //$NON-NLS-1$ IFormPage page = pageFactory.createPage(editor, id, name); pages.add(page); } catch (CoreException e) { continue; } } return pages; } @Override public boolean isSaveAsAllowed() { return false; } @Override public void doSave(IProgressMonitor monitor) { SnippetEditorInput input = (SnippetEditorInput) getEditorInput(); Snippet snippet = input.getSnippet(); if (isNullOrEmpty(snippet.getName())) { MessageDialog.openError(getSite().getShell(), Messages.DIALOG_TITLE_INAVLID_SNIPPET_NAME, Messages.DIALOG_MESSAGE_INVALID_SNIPPET_NAME); monitor.setCanceled(true); return; } if (snippet.getLocation() == null || snippet.getLocation() == NONE) { MessageDialog.openError(getSite().getShell(), Messages.DIALOG_TITLE_INVALID_SNIPPET_LOCATION, Messages.DIALOG_MESSAGE_INVALID_SNIPPET_LOCATION); monitor.setCanceled(true); return; } final String sourceValid; if (snippet.getLocation() == FILE) { sourceValid = TextSnippetSourceValidator.isSourceValid(snippet.getCode()); } else { sourceValid = JavaSnippetSourceValidator.isSourceValid(snippet.getCode()); } if (!sourceValid.isEmpty()) { MessageDialog.openError(getSite().getShell(), Messages.DIALOG_TITLE_ERROR_SNIPPET_SOURCE_INVALID, MessageFormat.format(Messages.DIALOG_MESSAGE_ERROR_SNIPPET_SOURCE_INVALID, sourceValid)); monitor.setCanceled(true); return; } ISnippetRepository repo = input.getRepository(); if (repo == null) { repo = SelectRepositoryDialog.openSelectRepositoryDialog(getSite().getShell(), repos, configs).orNull(); if (repo == null) { return; } input.setRepository(repo); } ISnippet oldSnippet = input.getOldSnippet(); if (!oldSnippet.getCode().isEmpty() && !snippet.getCode().equals(oldSnippet.getCode())) { int status = new MessageDialog(getSite().getShell(), Messages.DIALOG_TITLE_SAVE_SNIPPET, null, Messages.DIALOG_MESSAGE_SAVE_SNIPPET_WITH_MODIFIED_CODE, MessageDialog.QUESTION, new String[] { Messages.DIALOG_OPTION_SAVE, Messages.DIALOG_OPTION_SAVE_AS_NEW, Messages.DIALOG_OPTION_CANCEL }, 0).open(); if (status == 1) { // Store as new snippet.setUuid(randomUUID()); setInputWithNotify(new SnippetEditorInput(snippet, input.getRepository())); } if (status == 2) { // Explicit Cancel monitor.setCanceled(true); return; } if (status == SWT.DEFAULT) { // Dialog closed => implicit Cancel monitor.setCanceled(true); return; } } try { commitPages(true); input.setOldSnippet(Snippet.copy(snippet)); repo.importSnippet(snippet); setPartName(getEditorInput().getName()); editorDirtyStateChanged(); } catch (IOException e) { Logs.log(LogMessages.ERROR_FAILED_TO_STORE_SNIPPET, e); } } @Override public void doSaveAs() { } @Override public void resourceChanged(IResourceChangeEvent event) { } public void markDirtyUponSnippetCreation() { for (Object page : pages) { if (page instanceof IFormPage && ((IFormPage) page).getManagedForm() != null) { for (IFormPart part : ((IFormPage) page).getManagedForm().getParts()) { if (part instanceof AbstractFormPart) { ((AbstractFormPart) part).markDirty(); } } } } } }