Java tutorial
/** * AADL-RAMSES * * Copyright 2012 TELECOM ParisTech and CNRS * * TELECOM ParisTech/LTCI * * Authors: see AUTHORS * * This program is free software: you can redistribute it and/or modify * it under the terms of the Eclipse Public License as published by Eclipse, * either version 1.0 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Eclipse Public License for more details. * You should have received a copy of the Eclipse Public License * along with this program. If not, see * http://www.eclipse.org/org/documents/epl-v10.php */ package fr.tpt.aadl.ramses.control.osate.properties; import java.io.File; import java.io.FileNotFoundException; import org.apache.log4j.Logger; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.ContainerSelectionDialog; import org.eclipse.ui.dialogs.PreferencesUtil; import org.eclipse.ui.dialogs.PropertyPage; import org.osate.utils.FileUtils; import fr.tpt.aadl.ramses.control.osate.WorkbenchUtils; import fr.tpt.aadl.ramses.control.support.config.ConfigStatus; import fr.tpt.aadl.ramses.control.support.config.ConfigurationException; import fr.tpt.aadl.ramses.control.support.config.RamsesConfiguration; import fr.tpt.aadl.ramses.control.support.generator.Generator; import fr.tpt.aadl.ramses.control.support.services.ServiceProvider; import fr.tpt.aadl.ramses.control.support.services.ServiceRegistry; import fr.tpt.aadl.ramses.generation.arinc653.xml.XMLARINC653StdGeneratorFactory; import fr.tpt.aadl.ramses.generation.osek.OSEKGeneratorFactory; import fr.tpt.aadl.ramses.generation.pok.c.PokGeneratorFactory; public class RamsesPropertyPage extends PropertyPage { private static final String PATH_TITLE = "Output directory (where code will be generated)"; private static final String _PROPERTY_PAGE_ID = "fr.tpt.aadl.ramses.control.osate.properties.RamsesPropertyPage"; public static final String PREFIX = "fr.tpt.aadl.ramses."; public static final String OUTPUT_DIR = "output.directory"; public static final String TARGET_ID = "target.id"; public static final String RUNTIME_PATH = "runtime.path"; public static final String PREF = "pref_pok"; private static final String _OJR_PLATFORM = "ojr"; private String DEFAULT_PATH; private String PROJECT_NAME; protected static final int TEXT_FIELD_WIDTH = 43; protected Text outputDirText; private Button target; private Text runtimePathText; private Label selectedPathLabel; private RamsesConfiguration _config; protected IProject _project; private static Logger _LOGGER = Logger.getLogger(RamsesPropertyPage.class); /** * Constructor for SamplePropertyPage. */ public RamsesPropertyPage() { super(); } private void loadConfig() { try { _project = (IProject) getElement(); if (_config == null) _config = new RamsesConfiguration(); fetchProperties(_project, _config); } catch (ConfigurationException ee) { // Missing configuration or first time configuration. _config = new RamsesConfiguration(); } catch (Exception e) { String msg = "cannot load RAMSES configuration"; _LOGGER.fatal(msg, e); throw new RuntimeException(msg, e); } } private void addInformationSection(Composite parent) { Composite composite = createDefaultComposite(parent); //Label for information Label pathLabel = new Label(composite, SWT.CENTER); pathLabel.setText("This property page enable you to configure RAMSES code generator"); } protected void addSeparator(Composite parent) { Label separator = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); GridData gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; gridData.grabExcessHorizontalSpace = true; separator.setLayoutData(gridData); } public static String getDefaultOutputDir(IResource resource) { return resource.getLocation().makeAbsolute().toOSString(); } protected void addOutputDirectorySection(Composite parent, RamsesConfiguration config, String labelMessage) { Label label = new Label(parent, SWT.BOLD); label.setText("1 - " + labelMessage); Composite composite = createDefaultComposite(parent); // Label for output directory field Label ownerLabel = new Label(composite, SWT.BOLD); ownerLabel.setText(PATH_TITLE); // output Directory button field outputDirText = new Text(composite, SWT.SINGLE | SWT.BORDER); GridData gd = new GridData(); gd.widthHint = convertWidthInCharsToPixels(TEXT_FIELD_WIDTH); outputDirText.setLayoutData(gd); outputDirText.setEditable(false); // Populate output dir text field DEFAULT_PATH = getDefaultOutputDir((IResource) getElement()); PROJECT_NAME = (((IResource) getElement()).getName()); if (config.getRamsesOutputDir() == null) outputDirText.setText(DEFAULT_PATH); else outputDirText.setText(config.getRamsesOutputDir().getAbsolutePath()); // Move the cursor to the end. outputDirText.setSelection(outputDirText.getText().length()); Button button = new Button(composite, SWT.PUSH); button.setText("Browse existing directories in workspace..."); button.setAlignment(SWT.LEFT); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { ContainerSelectionDialog browseWorkspace = new ContainerSelectionDialog(getShell(), (IContainer) getElement(), true, "Select output directory for generated code"); if (browseWorkspace.open() == ContainerSelectionDialog.OK) { Object[] result = browseWorkspace.getResult(); if (result != null && result.length > 0) { Path outputDir = (Path) result[0]; outputDirText.setText(convertToAbsolutePath(outputDir)); // Move the cursor to the end. outputDirText.setSelection(outputDirText.getText().length()); } } } }); } private String convertToAbsolutePath(Path relativePath) { String root = File.separator + PROJECT_NAME; if (root.equals(relativePath.toOSString())) { return DEFAULT_PATH; } else { return DEFAULT_PATH + File.separator + relativePath.removeFirstSegments(1).toOSString(); } } protected Composite createDefaultComposite(Composite parent) { Composite composite = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(); layout.numColumns = 2; composite.setLayout(layout); GridData data = new GridData(); data.verticalAlignment = GridData.FILL; data.horizontalAlignment = GridData.FILL; composite.setLayoutData(data); return composite; } /** * @see PreferencePage#createContents(Composite) */ @Override protected Control createContents(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); composite.setLayout(layout); GridData data = new GridData(GridData.FILL); data.grabExcessHorizontalSpace = true; composite.setLayoutData(data); loadConfig(); addInformationSection(composite); addSeparator(composite); addSeparator(composite); addOutputDirectorySection(composite, _config, "Select output directory for generated code"); addSeparator(composite); addTargetSection(composite, _config); return composite; } private void addTargetSection(Composite composite, RamsesConfiguration config) { Label targetInfo = new Label(composite, SWT.BOLD); targetInfo.setText("2 - Select one of the following target platforms to generate code for:"); // Create checkboxes for targets supported by RAMSES // TODO : Should be deduced from the plugin.xml of generators; // see ramses (OSGI) Button arinc = new Button(composite, SWT.RADIO); arinc.setText("ARINC653 - POK (http://pok.tuxfamily.org/)"); arinc.setData(PokGeneratorFactory.POK_GENERATOR_NAME); Button ojr = new Button(composite, SWT.RADIO); ojr.setText("Java - OJR"); ojr.setData(_OJR_PLATFORM); Button xmlarinc653 = new Button(composite, SWT.RADIO); xmlarinc653.setText("ARINC653 - Standard"); xmlarinc653.setData(XMLARINC653StdGeneratorFactory.ARINC653_GENERATOR_NAME); Button osek = new Button(composite, SWT.RADIO); osek.setText("OSEX/NXT - nxtOSEK (http://lejos-osek.sourceforge.net/)"); osek.setData(OSEKGeneratorFactory.OSEK_GENERATOR_NAME); addSeparator(composite); Label installDirInfo = new Label(composite, SWT.BOLD); installDirInfo.setText("3 - Select install directory of target platforms"); if (config.getTargetId() != null) { if (config.getTargetId().equals(_OJR_PLATFORM)) { target = ojr; } else if (config.getTargetId().equals(PokGeneratorFactory.POK_GENERATOR_NAME)) { target = arinc; } else if (config.getTargetId().equals(OSEKGeneratorFactory.OSEK_GENERATOR_NAME)) { target = osek; } else if (config.getTargetId().equals(XMLARINC653StdGeneratorFactory.ARINC653_GENERATOR_NAME)) { target = xmlarinc653; } target.setSelection(true); } Listener listener = new Listener() { @Override public void handleEvent(Event event) { Button button = (Button) (event.widget); selectedPathLabel.setText("Select path for " + button.getText()); selectedPathLabel.redraw(); if (button.getSelection()) { target = button; } } }; osek.addListener(SWT.Selection, listener); arinc.addListener(SWT.Selection, listener); ojr.addListener(SWT.Selection, listener); xmlarinc653.addListener(SWT.Selection, listener); Button pathButton = new Button(composite, SWT.PUSH); pathButton.setText("Choose the target platform path"); pathButton.setAlignment(SWT.RIGHT); selectedPathLabel = new Label(composite, SWT.BOLD); selectedPathLabel.setText("Path for target not selected ..."); selectedPathLabel.setSize(90, 50); GridData grdPath = new GridData(); grdPath.widthHint = convertWidthInCharsToPixels(TEXT_FIELD_WIDTH); selectedPathLabel.setLayoutData(grdPath); runtimePathText = new Text(composite, SWT.BOLD | SWT.SINGLE | SWT.BORDER); runtimePathText.setEditable(false); GridData grd = new GridData(); grd.widthHint = convertWidthInCharsToPixels(TEXT_FIELD_WIDTH); runtimePathText.setLayoutData(grd); if (config.getRuntimePath() != null) { runtimePathText.setText(config.getRuntimePath().getAbsolutePath()); } pathButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { DirectoryDialog ddg = new DirectoryDialog(getShell()); File selectedFile = null; String file = ddg.open(); if (file != null && file.length() > 2) { selectedFile = new File(file); runtimePathText.setText(selectedFile.getAbsolutePath()); } } }); } private void saveConfiguration() throws CoreException { _project.setPersistentProperty(new QualifiedName(PREFIX, OUTPUT_DIR), outputDirText.getText()); _project.setPersistentProperty(new QualifiedName(PREFIX, TARGET_ID), target.getData().toString()); if (!_OJR_PLATFORM.equals(target.getData().toString())) { _project.setPersistentProperty(new QualifiedName(PREFIX, RUNTIME_PATH), runtimePathText.getText()); } } /** * @see PreferencePage#performDefaults() */ @Override protected void performDefaults() { super.performDefaults(); outputDirText.setText(DEFAULT_PATH); } /** * @see PreferencePage#performOk() */ @Override public boolean performOk() { try { short errno = configChecker(); if (errno == 0) { saveConfiguration(); return true; } else { popupConfigurationErrorMessage(errno); return false; } } catch (CoreException e) { String msg = "cannot save RAMSES configuration"; _LOGGER.fatal(msg, e); throw new RuntimeException(msg, e); } } private short configChecker() { short result = 0; // Zero means no error. if (outputDirText.getText() == null || outputDirText.getText().isEmpty()) { result += 10; } if (target != null && target.getData() != null) { ServiceRegistry sr = ServiceProvider.getServiceRegistry(); Generator gen = sr.getGenerator(target.getData().toString()); if (gen != null) { try { File runtimePath = null; if (runtimePathText.getText() != null && !runtimePathText.getText().isEmpty()) { runtimePath = FileUtils.stringToFile(runtimePathText.getText()); } // the runtime path can be null. if (!gen.runtimePathChecker(runtimePath)) { result += 400; } } catch (FileNotFoundException e) { result += 300; } } else { result += 200; } } else { result += 100; } return result; } private void popupConfigurationErrorMessage(short errno) { StringBuilder msg = new StringBuilder("Cannot save RAMSES configuration:\n\n"); if (errno == 1) { msg.append("\n\tCan't fetch the project."); } else { int tmp = errno / 100; switch (tmp) { case 1: { msg.append("\n\tTarget is missing."); break; } case 2: { msg.append("\n\tThe target " + target.getData().toString() + " is not supported."); break; } case 3: { msg.append("\n\tThe runtime is missing."); break; } case 4: { msg.append("\n\tThe given runtime is not a valid " + target.getData().toString() + " runtime."); break; } } if (errno % 100 != 0) { msg.append("\n\tMissing output directory."); } } ServiceProvider.SYS_ERR_REP.error(msg.toString(), false); } public static String fetchPropertiesValue(IProject project, String property) throws CoreException { String value = project.getPersistentProperty(new QualifiedName(RamsesPropertyPage.PREFIX, property)); if (value == null) value = project.getLocation().toString(); return value; } public static void fetchProperties(IProject project, RamsesConfiguration result) throws CoreException, ConfigurationException { ConfigStatus status; status = result.setRamsesOutputDir(fetchPropertiesValue(project, OUTPUT_DIR)); if (status != ConfigStatus.SET) { throw new ConfigurationException(status); } status = result.setGenerationTargetId(fetchPropertiesValue(project, TARGET_ID)); if (status != ConfigStatus.SET) { throw new ConfigurationException(status); } status = result.setRuntimePath(fetchPropertiesValue(project, RUNTIME_PATH)); if (status != ConfigStatus.SET) { throw new ConfigurationException(status); } } // Return false if user has canceled. public static boolean openPropertyDialog(IProject project) { Shell shell = WorkbenchUtils.getCurrentShell(); //Instantiate the project propertyPage. PreferenceDialog prefDiag = PreferencesUtil.createPropertyDialogOn(shell, project, _PROPERTY_PAGE_ID, null, null); // TODO: display the missing informations. return prefDiag.open() == Window.OK; } }