Java tutorial
/******************************************************************************* * This file is protected by Copyright. * Please refer to the COPYRIGHT file distributed with this source distribution. * * This file is part of REDHAWK IDE. * * 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 *******************************************************************************/ package gov.redhawk.ide.octave.ui.wizard; import gov.redhawk.ide.codegen.ICodeGeneratorDescriptor; import gov.redhawk.ide.codegen.ImplementationSettings; import gov.redhawk.ide.codegen.jinja.cplusplus.CplusplusOctaveGenerator; import gov.redhawk.ide.codegen.ui.ICodegenWizardPage; import gov.redhawk.ide.octave.ui.OctaveProjectPlugin; import gov.redhawk.ide.octave.ui.OctaveFunctionVariables; import gov.redhawk.ide.octave.ui.OctaveProjectProperties; import gov.redhawk.ide.octave.ui.OctaveVariableMappingEnum; import gov.redhawk.ide.octave.ui.OctaveVariableTypeEnum; import gov.redhawk.mfile.parser.MFileParser; import gov.redhawk.mfile.parser.ParseException; import gov.redhawk.mfile.parser.TokenMgrError; import gov.redhawk.mfile.parser.model.MFile; import gov.redhawk.sca.util.Debug; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import mil.jpeojtrs.sca.spd.Implementation; import mil.jpeojtrs.sca.spd.SoftPkg; import org.eclipse.core.databinding.Binding; import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.UpdateValueStrategy; import org.eclipse.core.databinding.beans.BeanProperties; import org.eclipse.core.databinding.conversion.IConverter; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.databinding.validation.IValidator; import org.eclipse.core.databinding.validation.ValidationStatus; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.databinding.fieldassist.ControlDecorationSupport; import org.eclipse.jface.databinding.swt.WidgetProperties; import org.eclipse.jface.databinding.wizard.WizardPageSupport; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.ListViewer; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.plugin.AbstractUIPlugin; /** * @since 8.1 */ public class MFileSelectionWizardPage extends WizardPage implements ICodegenWizardPage { private static final Debug DEBUG = new Debug(OctaveProjectPlugin.PLUGIN_ID, "MFileSelectionWizardPage"); /** The Constant TITLE_IMAGE. */ private static final ImageDescriptor TITLE_IMAGE = AbstractUIPlugin .imageDescriptorFromPlugin(OctaveProjectPlugin.PLUGIN_ID, "icons/octaveLogo.png"); private static final int NUM_COLUMNS = 3; private ListViewer depsListViewer = null; private Text primaryMFileTextBox; private OctaveProjectProperties octaveProjProps; private Button dependencyCheckBox; private Text dependencyTextBox; private Button depsBrowseButton; private Button depsAddButton; private Button depsRemoveButton; private Binding currentDepBindValue; private Binding primaryMFileBindValue; private Implementation impl; private ImplementationSettings implSettings; public MFileSelectionWizardPage(final OctaveProjectProperties octaveProjProps, final String name, final String componenttype) { super(name, "New M-File", MFileSelectionWizardPage.TITLE_IMAGE); this.octaveProjProps = octaveProjProps; } @Override public void createControl(Composite parent) { final Composite client = new Composite(parent, SWT.NULL); // Creates the basic layout of the UI elements createUIElements(client); // A simple content provider for the List of IFile elements. this.depsListViewer.setContentProvider(new IStructuredContentProvider() { @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } @Override public void dispose() { } @Override public Object[] getElements(Object inputElement) { if (inputElement instanceof List<?>) { return ((List<?>) inputElement).toArray(); } return null; } }); // Label provider that prints the full OS Specific file path to the objects in the IFile array. this.depsListViewer.setLabelProvider(new LabelProvider() { @Override public String getText(Object element) { if (element instanceof File) { return ((File) element).getAbsolutePath(); } return super.getText(element); } }); this.depsListViewer.setInput(this.octaveProjProps.getmFileDepsList()); bindValues(); this.setControl(client); } private void createUIElements(final Composite client) { client.setLayout(new GridLayout(MFileSelectionWizardPage.NUM_COLUMNS, false)); final Label primaryMFileLabel = new Label(client, SWT.NULL); primaryMFileLabel.setText("Primary M-file:"); primaryMFileTextBox = new Text(client, SWT.BORDER); primaryMFileTextBox.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); final Button mFileSelectionBrowseButton = new Button(client, SWT.PUSH); mFileSelectionBrowseButton.setText("Browse"); mFileSelectionBrowseButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { FileDialog fd = new FileDialog(client.getShell(), SWT.OPEN); String selectedFile = fd.open(); if (selectedFile != null) { MFileSelectionWizardPage.this.primaryMFileTextBox.setText(selectedFile); } } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); final Group dependenciesGroup = new Group(client, SWT.None); dependenciesGroup.setText("Dependencies"); dependenciesGroup.setLayout(new GridLayout(3, false)); dependenciesGroup.setLayoutData(GridDataFactory.fillDefaults().grab(true, true) .span(MFileSelectionWizardPage.NUM_COLUMNS, 1).create()); dependencyCheckBox = new Button(dependenciesGroup, SWT.CHECK); dependencyCheckBox.setLayoutData(GridDataFactory.fillDefaults().span(3, 1).create()); dependencyCheckBox.setText("Primary M-file depends on non-standard M-files"); dependencyCheckBox.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { MFileSelectionWizardPage.this.dependencyTextBox.setText(""); } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); dependencyTextBox = new Text(dependenciesGroup, SWT.BORDER); dependencyTextBox.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); depsBrowseButton = new Button(dependenciesGroup, SWT.PUSH); depsBrowseButton.setText("Browse"); depsBrowseButton.setLayoutData(GridDataFactory.swtDefaults().create()); depsBrowseButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { FileDialog fd = new FileDialog(client.getShell(), SWT.MULTI); String firstFilePath = fd.open(); if (firstFilePath != null) { String filePath = (new File(firstFilePath)).getParent(); String[] selectedFiles = fd.getFileNames(); for (String fileName : selectedFiles) { MFileSelectionWizardPage.this.octaveProjProps.getmFileDepsList() .add(new File(filePath + File.separator + fileName)); } MFileSelectionWizardPage.this.depsListViewer.refresh(); } } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); depsAddButton = new Button(dependenciesGroup, SWT.PUSH); depsAddButton.setText("Add"); depsAddButton.setLayoutData(GridDataFactory.swtDefaults().create()); this.depsListViewer = new ListViewer(dependenciesGroup); depsListViewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create()); depsRemoveButton = new Button(dependenciesGroup, SWT.PUSH); depsRemoveButton.setText("Remove"); depsRemoveButton.setLayoutData(GridDataFactory.swtDefaults().align(SWT.BEGINNING, SWT.BEGINNING).create()); depsAddButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { // If the file is valid Object currentValidationStatus = MFileSelectionWizardPage.this.currentDepBindValue .getValidationStatus().getValue(); if (((IStatus) currentValidationStatus).isOK() && MFileSelectionWizardPage.this.octaveProjProps.getCurrentDepFile() != null) { // If the file is not already in the list. if (!MFileSelectionWizardPage.this.octaveProjProps.getmFileDepsList() .contains(MFileSelectionWizardPage.this.octaveProjProps.getCurrentDepFile())) { MFileSelectionWizardPage.this.octaveProjProps.getmFileDepsList() .add(MFileSelectionWizardPage.this.octaveProjProps.getCurrentDepFile()); MFileSelectionWizardPage.this.depsListViewer.refresh(); } } } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); depsRemoveButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { ISelection activeViewerSelection = MFileSelectionWizardPage.this.depsListViewer.getSelection(); if (activeViewerSelection instanceof StructuredSelection) { for (Object fileToRemove : ((StructuredSelection) activeViewerSelection).toArray()) { MFileSelectionWizardPage.this.octaveProjProps.getmFileDepsList().remove(fileToRemove); } MFileSelectionWizardPage.this.depsListViewer.refresh(); } } @Override public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); } private void bindValues() { // create new Context DataBindingContext ctx = new DataBindingContext(); // Defining the Model objects as Beans IObservableValue primaryMFileModel = BeanProperties.value("primaryMFile").observe(this.octaveProjProps); IObservableValue currentDepFileModel = BeanProperties.value("currentDepFile").observe(this.octaveProjProps); IObservableValue hasDepsModel = BeanProperties.value("hasDeps").observe(this.octaveProjProps); // Defining the Target objects IObservableValue primaryMFileTarget = WidgetProperties.text(SWT.Modify).observe(this.primaryMFileTextBox); IObservableValue currentDepFileTarget = WidgetProperties.text(SWT.Modify).observe(this.dependencyTextBox); IObservableValue hasDepsTarget = WidgetProperties.selection().observe(this.dependencyCheckBox); // The target objects that need to be disabled when the hasDeps model object changes. IObservableValue depsTextBoxTarget = WidgetProperties.enabled().observe(this.dependencyTextBox); IObservableValue depsAddButtonTarget = WidgetProperties.enabled().observe(this.depsAddButton); IObservableValue depsBrowseButtonTarget = WidgetProperties.enabled().observe(this.depsBrowseButton); IObservableValue depsRemoveButtonTarget = WidgetProperties.enabled().observe(this.depsRemoveButton); IObservableValue depsListViewerTarget = WidgetProperties.enabled() .observe(this.depsListViewer.getControl()); // Define my strategy for the Primary & Deps M-File bindings. UpdateValueStrategy primaryMFileUpdateStrat = new UpdateValueStrategy(); primaryMFileUpdateStrat.setConverter(getStringToFileConverter()); primaryMFileUpdateStrat.setAfterConvertValidator(getPrimaryMFileNameValidator()); UpdateValueStrategy depsMFileUpdateStrat = new UpdateValueStrategy(); depsMFileUpdateStrat.setConverter(getStringToFileConverter()); depsMFileUpdateStrat.setAfterConvertValidator(getDepMFileNameValidator()); // connect them primaryMFileBindValue = ctx.bindValue(primaryMFileTarget, primaryMFileModel, primaryMFileUpdateStrat, null); currentDepBindValue = ctx.bindValue(currentDepFileTarget, currentDepFileModel, depsMFileUpdateStrat, null); ctx.bindValue(hasDepsTarget, hasDepsModel); // The bindings for the disabling of the controls ctx.bindValue(depsTextBoxTarget, hasDepsModel, null, new UpdateValueStrategy()); ctx.bindValue(depsAddButtonTarget, hasDepsModel, null, new UpdateValueStrategy()); ctx.bindValue(depsBrowseButtonTarget, hasDepsModel, null, new UpdateValueStrategy()); ctx.bindValue(depsRemoveButtonTarget, hasDepsModel, null, new UpdateValueStrategy()); ctx.bindValue(depsListViewerTarget, hasDepsModel, null, new UpdateValueStrategy()); // add cool control decoration ControlDecorationSupport.create(primaryMFileBindValue, SWT.TOP | SWT.LEFT); ControlDecorationSupport.create(currentDepBindValue, SWT.TOP | SWT.LEFT); WizardPageSupport.create(this, ctx); } private IValidator getPrimaryMFileNameValidator() { return new IValidator() { @Override public IStatus validate(Object value) { if (value == null || !((File) value).exists() || ((File) value).isDirectory()) { return ValidationStatus.error("Primary M-File location must be provided"); } // Parse the current file selection and set the Octave Project Properties object try { parseFile((File) value); } catch (IOException e) { if (DEBUG.enabled) { DEBUG.catching("MFile Parse Error", e); } return ValidationStatus.error("Could not parse given Primary M-file", e); } catch (ParseException e) { if (DEBUG.enabled) { DEBUG.catching("MFile Parse Error", e); } return ValidationStatus.error("Could not parse given Primary M-file", e); } catch (TokenMgrError e) { if (DEBUG.enabled) { DEBUG.catching("MFile Parse Error", e); } return ValidationStatus.error("Could not parse given Primary M-file", e); } return ValidationStatus.ok(); } }; } private IValidator getDepMFileNameValidator() { return new IValidator() { @Override public IStatus validate(Object value) { if (!MFileSelectionWizardPage.this.octaveProjProps.getHasDeps() || value == null) { return ValidationStatus.ok(); } else if (value == null || !((File) value).exists()) { return ValidationStatus.error("M-File location must be provided"); } return ValidationStatus.ok(); } }; } private IConverter getStringToFileConverter() { return new IConverter() { @Override public Object getToType() { return File.class; } @Override public Object getFromType() { return String.class; } @Override public Object convert(Object fromObject) { if (fromObject == null || ((String) fromObject).equals("")) { return null; } else { return new File((String) fromObject); } } }; } /** * Parses the m-file set the function inputs and outputs. * @param file The m-file to parse * @throws ParseException If the M-File cannot be parsed the values are not set * @throws FileNotFoundException If the M-File cannot be found. */ private void parseFile(File file) throws IOException, ParseException { MFile mFile = MFileParser.parse(new FileInputStream(file), null); List<OctaveFunctionVariables> inputs = new ArrayList<OctaveFunctionVariables>(); for (String inputVar : mFile.getFunction().getInputs()) { OctaveFunctionVariables ofv = new OctaveFunctionVariables(true); ofv.setName(inputVar); // Default values ofv.setMapping(OctaveVariableMappingEnum.PORT); ofv.setType(OctaveVariableTypeEnum.Double_Real); inputs.add(ofv); } this.octaveProjProps.setFunctionInputs(inputs); List<OctaveFunctionVariables> outputs = new ArrayList<OctaveFunctionVariables>(); for (String outputVar : mFile.getFunction().getOutputs()) { OctaveFunctionVariables ofv = new OctaveFunctionVariables(false); ofv.setName(outputVar); // Default values ofv.setMapping(OctaveVariableMappingEnum.PORT); ofv.setType(OctaveVariableTypeEnum.Double_Real); outputs.add(ofv); } this.octaveProjProps.setFunctionOutputs(outputs); this.octaveProjProps.setFunctionName(mFile.getFunction().getName()); } @Override public void configure(SoftPkg softpkg, Implementation impl, ICodeGeneratorDescriptor desc, ImplementationSettings implSettings, String componentType) { this.impl = impl; this.implSettings = implSettings; this.implSettings.setOutputDir("cpp"); this.implSettings.setTemplate(CplusplusOctaveGenerator.TEMPLATE); } @Override public ImplementationSettings getSettings() { return this.implSettings; } public Implementation getImpl() { return this.impl; } @Override public boolean canFinish() { return false; } @Override public void setCanFlipToNextPage(boolean canFlip) { } @Override public void setCanFinish(boolean canFinish) { } }