blob: f78c698225d5cc35ab2ab072f88d95bac441cd63 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2017 MEDEVIT, FHV and others.
* 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:
* Marco Descher <marco@descher.at> - initial API and implementation
*******************************************************************************/
package org.eclipse.e4.tools.emf.ui.internal.common.properties;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.inject.Named;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.core.services.nls.Translation;
import org.eclipse.e4.tools.emf.ui.common.IModelResource;
import org.eclipse.e4.tools.emf.ui.internal.Messages;
import org.eclipse.e4.tools.emf.ui.internal.ResourceProvider;
import org.eclipse.e4.tools.services.IResourcePool;
import org.eclipse.e4.ui.model.application.MApplicationElement;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.core.ICompilationUnit;
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.core.JavaProject;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TableViewerColumn;
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.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
/**
* This handler exports all Id values within the application model to a file for
* static reference. Currently the location of this file is fixed to be in the
* location of the selected projects main package with name
* <code>AppModelId.java</code>.
*/
public class ExportIdsHandler {
public static final String DEFAULT_APPMODELID_CLASSNAME = "AppModelId";
@Execute
public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell, @Translation Messages messages, IModelResource resource, IResourcePool pool, IProject project) {
TitleAreaDialog dialog = new ExportIdDialog(shell, messages, resource.getRoot(), pool, project);
dialog.open();
}
static class ExportIdDialog extends TitleAreaDialog {
private Messages messages;
private IObservableList list;
private IResourcePool pool;
private JavaClass clazz;
private CheckboxTableViewer viewer;
private Text textClassName;
public ExportIdDialog(Shell parentShell, Messages messages, IObservableList list, IResourcePool pool, IProject project) {
super(parentShell);
this.messages = messages;
this.list = list;
this.pool = pool;
clazz = new JavaClass();
if (JavaProject.hasJavaNature(project)) {
try {
IJavaProject javaProject = JavaCore.create(project);
for (IPackageFragmentRoot iPackageFragmentRoot : javaProject.getAllPackageFragmentRoots()) {
if (iPackageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE) {
clazz.packageFragment = iPackageFragmentRoot.createPackageFragment(project.getName(), false, new NullProgressMonitor());
break;
}
}
} catch (JavaModelException e) {
e.printStackTrace();
}
} else {
setErrorMessage(messages.ExportIdsHandler_Dialog_SelectProject);
getButton(IDialogConstants.OK_ID).setEnabled(false);
}
}
@Override
protected Control createDialogArea(Composite parent) {
getShell().setText(messages.ExportIdsHandler_Dialog_ShellTitle);
setTitle(messages.ExportIdsHandler_Dialog_DialogTitle);
setMessage(messages.ExportIdsHandler_Dialog_DialogMessage);
setTitleImage(pool.getImageUnchecked(ResourceProvider.IMG_Wizban16_extstr_wiz));
Composite content = (Composite) super.createDialogArea(parent);
content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Composite container = new Composite(content, SWT.NONE);
container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
GridLayout gl = new GridLayout(2, false);
gl.numColumns = 2;
gl.marginBottom = 4;
container.setLayout(gl);
Label lblTargetClass = new Label(container, SWT.NONE);
lblTargetClass.setText(messages.ExportIdsHandler_Dialog_TargetClassName);
textClassName = new Text(container, SWT.BORDER);
textClassName.setText(DEFAULT_APPMODELID_CLASSNAME);
GridData gdcn = new GridData();
gdcn.horizontalAlignment = SWT.FILL;
gdcn.grabExcessHorizontalSpace = true;
textClassName.setLayoutData(gdcn);
Table t = new Table(container, SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CHECK);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.heightHint = t.getItemHeight() * 18;
container.setLayoutData(gd);
GridData gd2 = new GridData(SWT.FILL, SWT.FILL, true, true);
gd2.horizontalSpan = 2;
gd2.heightHint = t.getItemHeight() * 17;
t.setHeaderVisible(true);
t.setLinesVisible(true);
t.setLayoutData(gd2);
viewer = new CheckboxTableViewer(t);
{
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
return ""; //$NON-NLS-1$
}
});
}
{
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column.getColumn().setText(messages.ExportIdsHandler_Dialog_ElementName);
column.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
Entry e = (Entry) element;
return ((EObject) e.object).eClass().getName();
}
});
}
{
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column.getColumn().setText(messages.ExportIdsHandler_Dialog_Key);
column.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
Entry e = (Entry) element;
return e.idFieldKey;
}
});
}
{
TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
column.getColumn().setText(messages.ExportIdsHandler_Dialog_Id_Value);
column.setLabelProvider(new ColumnLabelProvider() {
@Override
public String getText(Object element) {
Entry e = (Entry) element;
return e.elementId;
}
});
}
for (int i = 1; i < viewer.getTable().getColumnCount(); i++) {
TableColumn c = viewer.getTable().getColumn(i);
c.pack();
if (c.getWidth() < 120) {
c.setWidth(120);
}
}
{
Label l = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
l.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false, 3, 1));
}
List<Entry> entries = new ArrayList<>();
TreeIterator<EObject> it = EcoreUtil.getAllContents(list);
while (it.hasNext()) {
Object next = it.next();
if (next instanceof MApplicationElement) {
MApplicationElement o = (MApplicationElement) next;
if (o.getElementId() != null && o.getElementId().length() > 1) {
String idFieldKey = findIdFieldKey(o);
entries.add(new Entry(o, idFieldKey, o.getElementId()));
}
}
}
Collections.sort(entries);
viewer.setContentProvider(new ArrayContentProvider());
viewer.setInput(entries);
viewer.setAllChecked(true);
for (int i = 1; i < viewer.getTable().getColumnCount(); i++) {
TableColumn c = viewer.getTable().getColumn(i);
c.pack();
if (c.getWidth() < 120) {
c.setWidth(120);
}
}
return container;
}
@Override
protected void okPressed() { // See AbstractNewClassWizard
clazz.name = textClassName.getText();
Object[] els = viewer.getCheckedElements();
if (els.length > 0) {
try {
String content = compileFileContent(els);
IPackageFragment fragment = clazz.packageFragment;
String cuName = clazz.name + ".java"; //$NON-NLS-1$
ICompilationUnit unit = fragment.getCompilationUnit(cuName);
IResource resource = unit.getResource();
IFile file = (IFile) resource;
try (ByteArrayInputStream stream = new ByteArrayInputStream(content.toString().getBytes())) {
if (file.exists()) {
file.delete(true, new NullProgressMonitor());
}
createParent(file.getParent());
// NPE
file.create(stream, IResource.KEEP_HISTORY, new NullProgressMonitor());
}
super.okPressed();
} catch (CoreException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private String compileFileContent(Object[] els) {
StringBuilder b = new StringBuilder();
b.append("package " + clazz.packageFragment.getElementName() + ";" + System.getProperty("line.separator")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
b.append(System.getProperty("line.separator")); //$NON-NLS-1$
b.append("public class " + clazz.name + " {" + System.getProperty("line.separator")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
for (Object o : els) {
Entry e = (Entry) o;
b.append("\tpublic static final String " + e.idFieldKey + " = \"" + e.elementId + "\";" + System.getProperty("line.separator")); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
b.append("}"); //$NON-NLS-1$
return b.toString();
}
private void createParent(IContainer container) throws CoreException {
if (!container.exists()) {
createParent(container.getParent());
if (container instanceof IFolder) {
IFolder f = (IFolder) container;
f.create(true, true, new NullProgressMonitor());
}
}
}
}
private static String findIdFieldKey(MApplicationElement object) {
StringBuilder sb = new StringBuilder();
sb.append(((EObject) object).eClass().getName());
sb.append("_"); //$NON-NLS-1$
sb.append(replaceInvalidChar(object.getElementId()));
return sb.toString().toUpperCase();
}
private static String replaceInvalidChar(String elementId) {
return elementId.replaceAll("[^A-Za-z0-9]", "_"); //$NON-NLS-1$ //$NON-NLS-2$
}
private static class Entry implements Comparable<Entry> {
private MApplicationElement object;
private String idFieldKey;
private String elementId;
public Entry(MApplicationElement object, String idFieldKey, String elementId) {
this.object = object;
this.idFieldKey = idFieldKey;
this.elementId = elementId;
}
@Override
public int compareTo(Entry o) {
return this.idFieldKey.compareTo(o.idFieldKey);
}
}
/**
* @see org.eclipse.e4.internal.tools.wizards.classes.AbstractNewClassPage
*/
private static class JavaClass {
private IPackageFragment packageFragment;
private String name;
}
}