Commit ae209564 authored by Philip Makedonski's avatar Philip Makedonski
Browse files

+ refined import wizard with custom file list editor, #48

parent 83a55040
Loading
Loading
Loading
Loading
+183 −0
Original line number Diff line number Diff line
package org.etsi.mts.tdl.wizards.importWizards;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.core.runtime.Path;
import org.eclipse.jface.preference.ListEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.FileDialog;

/**
 * A field editor to edit directory paths.
 */
public class FileListEditor extends ListEditor {

	/**
	 * The last path, or <code>null</code> if none.
	 */
	private String lastPath;

	
	private String[] extensions = null;

	private File filterPath = null;

	/**
	 * The special label text for directory chooser,
	 * or <code>null</code> if none.
	 */
	private String dirChooserLabelText;

	/**
	 * Creates a new path field editor
	 */
	protected FileListEditor() {
	}

	/**
	 * Creates a path field editor.
	 *
	 * @param name the name of the preference this field editor works on
	 * @param labelText the label text of the field editor
	 * @param dirChooserLabelText the label text displayed for the directory chooser
	 * @param parent the parent of the field editor's control
	 */
	public FileListEditor(String name, String labelText,
			String dirChooserLabelText, Composite parent) {
		init(name, labelText);
		this.dirChooserLabelText = dirChooserLabelText;
		createControl(parent);
		adapt();
	}

	private void adapt() {
		getAddButton().removeListener(SWT.Selection, getAddButton().getListeners(SWT.Selection)[0]);
		getAddButton().addListener(SWT.Selection, e -> {
			addPressed();
		});
	}

	@Override
	protected String createList(String[] items) {
		StringBuilder path = new StringBuilder("");//$NON-NLS-1$

		for (String item : items) {
			path.append(item);
			path.append(File.pathSeparator);
		}
		return path.toString();
	}

	/**
	 * Notifies that the Add button has been pressed.
	 */
	private void addPressed() {
		setPresentsDefaultValue(false);
		String[] input = getNewFileListInputObject();

		if (input != null && input.length > 0) {
			int index = getList().getSelectionIndex();
			List<String> items = Arrays.asList(getList().getItems());
			if (index >= 0) {
				for (String i : input) {
					if (!items.contains(i)) {
						getList().add(i, index + 1);
					}
				}
			} else {
				for (String i : input) {
					if (!items.contains(i)) {
						getList().add(i, 0);
					}
				}
			}
			selectionChanged();
			getList().notifyListeners(SWT.Modify, null);
		}
	}

	
	protected String[] getNewFileListInputObject() {
		//TODO: add directory
		FileDialog dialog = new FileDialog(getShell(), SWT.OPEN | SWT.SHEET | SWT.MULTI);
		
//		if (startingDirectory != null) {
//			dialog.setFileName(startingDirectory.getPath());
//		}
//		else 
		if (lastPath != null) {
			dialog.setFilterPath(lastPath);
		}
		if (extensions != null) {
			dialog.setFilterExtensions(extensions);
		}
		String input = dialog.open();
		String[] files = dialog.getFileNames();
		for (int i = 0; i<files.length; i++) {
			files[i] = dialog.getFilterPath()+Path.SEPARATOR+files[i];
		}
		return files;
	}

	protected String getNewInputObject() {
		//TODO: add directory -> collect all files in it (recursively)
		DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.SHEET);
		
		if (dirChooserLabelText != null) {
			dialog.setMessage(dirChooserLabelText);
		}
		if (lastPath != null) {
			if (new File(lastPath).exists()) {
				dialog.setFilterPath(lastPath);
			}
		}
		String dir = dialog.open();
		if (dir != null) {
			dir = dir.trim();
			if (dir.isEmpty()) {
				return null;
			}
			lastPath = dir;
		}
		return dir;
	}

	
	@Override
	protected String[] parseString(String stringList) {
		StringTokenizer st = new StringTokenizer(stringList, File.pathSeparator
				+ "\n\r");//$NON-NLS-1$
		ArrayList<Object> v = new ArrayList<>();
		while (st.hasMoreElements()) {
			v.add(st.nextElement());
		}
		return v.toArray(new String[v.size()]);
	}

	/**
	 * Sets this file field editor's file extension filter.
	 *
	 * @param extensions a list of file extension, or <code>null</code>
	 * to set the filter to the system's default value
	 */
	public void setFileExtensions(String[] extensions) {
		this.extensions = extensions;
	}

	/**
	 * Sets the initial path for the Browse dialog.
	 * @param path initial path for the Browse dialog
	 * @since 3.6
	 */
	public void setFilterPath(File path) {
		filterPath = path;
	}

}
+10 −9
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ public class ImportWizard extends Wizard implements IImportWizard {
		//TODO: use eclipse way?
		//TODO: separate location for source?
		if (mainPage.isCopySource()) {
			IPath sourcePath = mainPage.getSourcePath();
			for (IPath sourcePath : mainPage.getSourcePaths()) {
				try {
					java.nio.file.Files.copy(
							Path.of(sourcePath.toOSString()),
@@ -39,6 +39,7 @@ public class ImportWizard extends Wizard implements IImportWizard {
					e.printStackTrace();
				}
			}
		}
        if (file == null)
            return false;
        return true;
+114 −55
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;

@@ -19,13 +20,18 @@ import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.preference.DirectoryFieldEditor;
import org.eclipse.jface.preference.FileFieldEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.ListEditor;
import org.eclipse.jface.preference.PathEditor;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
@@ -36,12 +42,15 @@ import org.osgi.service.prefs.Preferences;

public class ImportWizardPage extends WizardNewFileCreationPage {
	
	protected FileFieldEditor editor;
	protected FileFieldEditor fileEditor;
	private boolean inline = false;
	private boolean copySource = false;
	private boolean overwrite = true;
	private IPath sourcePath;
	private List<IPath> sourcePaths = new ArrayList<>();
	LinkedHashMap<String, String> dataFormats = new LinkedHashMap<>();
	private FileListEditor fileListEditor;
	private Composite fileSelectionArea;
	private String packageName;
	public ImportWizardPage(String pageName, IStructuredSelection selection) {
		super(pageName, selection);
		setTitle(pageName); //NON-NLS-1
@@ -57,7 +66,8 @@ public class ImportWizardPage extends WizardNewFileCreationPage {
	 * @see org.eclipse.ui.dialogs.WizardNewFileCreationPage#createAdvancedControls(org.eclipse.swt.widgets.Composite)
	 */	
	protected void createAdvancedControls(Composite parent) {
		Composite fileSelectionArea = new Composite(parent, SWT.NONE);
		parent.setLayout(new GridLayout(1, false));
		fileSelectionArea = new Composite(parent, SWT.NONE);
		GridData fileSelectionData = new GridData(GridData.GRAB_HORIZONTAL
				| GridData.FILL_HORIZONTAL);
		fileSelectionArea.setLayoutData(fileSelectionData);
@@ -73,53 +83,81 @@ public class ImportWizardPage extends WizardNewFileCreationPage {
		//DONE: store and pre-fill with last used -> consider expanding with injected preferences for other controls as well
		String lastUsed = "LAST_USED";
		Preferences preferences = InstanceScope.INSTANCE.getNode("org.etsi.mts.tdl.wizarads.import.data");
		List<String> extensions = new ArrayList<String>(); 
		extensions.add(String.join(";",dataFormats.values()));
		extensions.addAll(dataFormats.values());

		editor = new FileFieldEditor("fileSelect","Select Data File: ",fileSelectionArea); //NON-NLS-1 //NON-NLS-2
		editor.getTextControl(fileSelectionArea).addModifyListener(e -> {
			setSourcePath(new Path(ImportWizardPage.this.editor.getStringValue()));
			if (getSourcePath().lastSegment()!=null && !getSourcePath().lastSegment().equals("null")) {
				preferences.put(lastUsed, getSourcePath().toOSString());
				setFileName(getSourcePath().lastSegment()+".tdltx"); //TODO: generalise
		fileListEditor = new FileListEditor("pathSelect","Select Data Files: ","Select Data Files: ", fileSelectionArea); 
		fileListEditor.fillIntoGrid(fileSelectionArea, 2);
		fileListEditor.setFileExtensions(extensions.toArray(String[]::new));
		org.eclipse.swt.widgets.List list = fileListEditor.getListControl(fileSelectionArea);
		list.addListener(SWT.Modify, e -> {
			for (String item : list.getItems()) {
				sourcePaths.add(Path.fromOSString(item));
			}
			validatePage();
		});
		editor.getTextControl(fileSelectionArea).setText(preferences.get(lastUsed, ""));
		
//		editor = new FileFieldEditor("fileSelect","Select Data File: ",fileSelectionArea); //NON-NLS-1 //NON-NLS-2
//		editor.getTextControl(fileSelectionArea).addModifyListener(e -> {
//			setSourcePaths(List.of(new Path(ImportWizardPage.this.editor.getStringValue())));
//			if (getSourcePaths() != null && getSourcePaths().getFirst().lastSegment()!=null && !getSourcePaths().getFirst().lastSegment().equals("null")) {
//				preferences.put(lastUsed, getSourcePaths().getFirst().toOSString());
//				setFileName(getSourcePaths().getFirst().lastSegment()+".tdltx"); //TODO: generalise
//			}
//		});
//		editor.getTextControl(fileSelectionArea).setText(preferences.get(lastUsed, ""));
		
		//DONE: add option to copy source 
		//TODO: adapt extensions based on available bundles
		List<String> extensions = new ArrayList<String>(); 
		extensions.add(String.join(";",dataFormats.values()));
		extensions.addAll(dataFormats.values());
		editor.setFileExtensions(extensions.toArray(String[]::new));
//		editor.setFileExtensions(extensions.toArray(String[]::new));

		fileSelectionArea.moveAbove(null);

		Composite optionsArea = new Composite(parent, SWT.NONE);

		optionsArea.moveBelow(fileSelectionArea);

		GridData optionsData = new GridData(GridData.GRAB_HORIZONTAL
				| GridData.FILL_HORIZONTAL);
		optionsArea.setLayoutData(optionsData);

		GridLayout optionsLayout = new GridLayout();
		optionsLayout.numColumns = 3;
		optionsLayout.makeColumnsEqualWidth = false;
		optionsLayout.marginWidth = 0;
		optionsLayout.marginHeight = 0;
		optionsArea.setLayout(optionsLayout);
		
		Label labelCopy = new Label(fileSelectionArea, SWT.NONE);
        labelCopy.setText("Copy Data File:");
        Button buttonCopy = new Button(fileSelectionArea, SWT.CHECK);
        Button buttonCopy = new Button(optionsArea, SWT.CHECK);
        buttonCopy.setSelection(false);
        buttonCopy.addSelectionListener(SelectionListener.widgetSelectedAdapter(this::copyDataDefinitions));
        Label labelCopy = new Label(optionsArea, SWT.NONE);
        labelCopy.setText("Copy Data File(s)");
        //fill empty cell
		new Label(fileSelectionArea, SWT.NONE);
		new Label(optionsArea, SWT.NONE);

		Label labelFlatten = new Label(fileSelectionArea, SWT.NONE);
		//TODO: for OpenAPI only?
        labelFlatten.setText("Import Inline Definitions:");
        //TODO: link and verify results
        Button buttonFlatten = new Button(fileSelectionArea, SWT.CHECK);
        Button buttonFlatten = new Button(optionsArea, SWT.CHECK);
        buttonFlatten.setSelection(false);
        buttonFlatten.addSelectionListener(SelectionListener.widgetSelectedAdapter(this::flattenDataDefinitions));
        Label labelFlatten = new Label(optionsArea, SWT.NONE);
        //TODO: for OpenAPI only?
        labelFlatten.setText("Import Inline Definitions");
//        fill empty cell
		new Label(fileSelectionArea, SWT.NONE);
		new Label(optionsArea, SWT.NONE);

		Label labelOverwrite = new Label(fileSelectionArea, SWT.NONE);
		//TODO: for OpenAPI only?
		labelOverwrite.setText("Overwrite File:");
        //TODO: link and verify results
        Button buttonOverwrite = new Button(fileSelectionArea, SWT.CHECK);
        Button buttonOverwrite = new Button(optionsArea, SWT.CHECK);
        buttonOverwrite.setSelection(true);
        buttonOverwrite.addSelectionListener(SelectionListener.widgetSelectedAdapter(this::overwriteDefinitions));
        Label labelOverwrite = new Label(optionsArea, SWT.NONE);
        //TODO: for OpenAPI only?
        labelOverwrite.setText("Overwrite File");
//        fill empty cell
		new Label(fileSelectionArea, SWT.NONE);
		new Label(optionsArea, SWT.NONE);
		
		setFileName("Imported.tdltx");
	}
	
	private void loadDataFormat(String bundleName, String label, String extension) {
@@ -139,23 +177,39 @@ public class ImportWizardPage extends WizardNewFileCreationPage {
	 * @see org.eclipse.ui.dialogs.WizardNewFileCreationPage#getInitialContents()
	 */
	protected InputStream getInitialContents() {
		packageName = "Imported"; //TODO: provide input or align with name? or keep simple except for asn? but if more than one selected, it will always be the same...
		List<String> asnFiles = new ArrayList<>();
		String content = "";
		if (editor.getStringValue().endsWith(".yaml")) {
		//TODO: handle multiple yaml / json files?
		//TODO: handle mixed files?

		for (IPath path : sourcePaths) {
			String item = path.toOSString();
			if (item.endsWith(".yaml")) {
				Converter converter = Converter.getConverter("org.etsi.mts.tdl.openapi2tdl.next");
			content = converter.processToString(editor.getStringValue(), 
					getContainerFullPath().append(getFileName()).toOSString(),
				content += converter.processToString(item, 
						getContainerFullPath().append(getFileName()).toOSString(), //TODO: this being..?
						"SOURCE_MAPPING", 
						"TARGET_MAPPING",
						inline
						);
		} else if (editor.getStringValue().endsWith(".json")) {
			} else if (item.endsWith(".json")) {
				//TODO: also for syntaxes?
				Converter converter = Converter.getConverter("org.etsi.mts.tdl.json2tdl");
			content = converter.processToString(editor.getStringValue(), editor.getStringValue()+"-generated.tdltx");
				content += converter.processToString(item, item+"-generated.tdltx");
				//TODO: repeat for YAML
			} else if (item.endsWith(".asn") || item.endsWith(".asn1")) {
				//bundle all?
				asnFiles.add(item);
			} else {
				
			}
		}
		if (!asnFiles.isEmpty()) {
			Converter converter = Converter.getConverter("org.etsi.mts.tdl.asn2tdl");
			//TODO: implement properly
			content += converter.processToString(asnFiles, asnFiles.getFirst()+"-generated.tdltx");
		}

		if (overwrite) {
			IWorkspace workspace = ResourcesPlugin.getWorkspace();
@@ -201,13 +255,18 @@ public class ImportWizardPage extends WizardNewFileCreationPage {
	protected boolean validatePage() {
		boolean validatePage = super.validatePage();
		//basic check for referenced data file
		if (this.editor != null) {
			IPath sourcePath = Path.fromOSString(this.editor.getStringValue());
			boolean exists = sourcePath.toFile().exists();
			if (!overwrite && exists) {
				setErrorMessage("The selected data file path is not valid.");
			}
			return exists && validatePage;
//		if (this.editor.getStringValue() != null && !this.editor.getStringValue().isBlank()) {
//			IPath sourcePath = Path.fromOSString(this.editor.getStringValue());
//			boolean exists = sourcePath.toFile().exists();
//			if (!overwrite && exists) {
//				setErrorMessage("The selected data file path is not valid.");
//			}
//			return exists && validatePage;
//		} else 
		if (!sourcePaths.isEmpty() && getFileName().endsWith(".tdltx")) {
			//TODO: check target file name?
			return validatePage;
			
		} else {
			return false;
		}
@@ -235,12 +294,12 @@ public class ImportWizardPage extends WizardNewFileCreationPage {
		this.copySource = copySource;
	}

	public IPath getSourcePath() {
		return sourcePath;
	public List<IPath> getSourcePaths() {
		return sourcePaths;
	}

	public void setSourcePath(IPath sourcePath) {
		this.sourcePath = sourcePath;
	public void setSourcePaths(List<IPath> sourcePaths) {
		this.sourcePaths = sourcePaths;
	}

	public boolean isOverwrite() {