Java tutorial
/* * Copyright 2013 Modeliosoft * * This file is part of Modelio. * * Modelio is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Modelio 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 * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Modelio. If not, see <http://www.gnu.org/licenses/>. * */ package org.modelio.mda.infra.catalog; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.TreeMap; import com.modeliosoft.modelio.javadesigner.annotations.objid; import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.modelio.app.core.ModelioEnv; import org.modelio.app.preferences.ScopedPreferenceStore; import org.modelio.gproject.module.IModuleCatalog; import org.modelio.gproject.module.IModuleHandle; import org.modelio.gproject.module.catalog.FileModuleStore; import org.modelio.mda.infra.catalog.CompatibilityHelper.CompatibilityLevel; import org.modelio.mda.infra.catalog.update.CatalogUpdatePreferencesPage; import org.modelio.mda.infra.plugin.MdaInfra; import org.modelio.ui.panel.IPanelProvider; import org.modelio.vbasic.version.Version; @objid("ec2b1457-8850-4ced-832a-f00a45fa18bc") public class ModuleCatalogPanel implements IPanelProvider { @objid("53d4e0bf-5c4d-4d62-baad-19ed7af05943") final ModelioEnv modelioEnv; @objid("ddee6091-d8e8-4975-aeca-9c682c5ffa33") ModuleCatalogPanelController controller; @objid("5eaa56a1-68f8-45c7-b099-f396707933d0") Composite top; @objid("2516ebc7-7c79-4b3d-8f81-2707722db7b0") TreeViewer treeViewer; @objid("6f2bb4ee-bb87-43ab-aa10-a53da5638b22") Label loading; @objid("e44ca7fd-7522-4921-86b4-bc5b1c9e8c0e") public ModuleCatalogPanel(ModelioEnv env) { this.modelioEnv = env; } @objid("e53a50b6-ab02-4300-b9f6-0b2e2a199ad6") @Override public Object createPanel(Composite parent) { // top level container this.top = new Composite(parent, SWT.BORDER); this.top.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); this.top.setLayout(new FormLayout()); this.loading = new Label(this.top, SWT.CENTER); this.loading.setImage(MdaInfra.getImageDescriptor("icons/hourglass.png").createImage()); // List of modules from catalog this.treeViewer = new TreeViewer(this.top, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); Tree tree = this.treeViewer.getTree(); tree.setHeaderVisible(true); this.treeViewer.getTree().setLinesVisible(true); // The first column displays the module name and version (or the // category) TreeViewerColumn col1 = new TreeViewerColumn(this.treeViewer, SWT.NONE); col1.getColumn().setWidth(200); col1.getColumn().setText(MdaInfra.I18N.getString("ModuleCatalogPanel.Module.label")); col1.getColumn().setToolTipText(MdaInfra.I18N.getString("ModuleCatalogPanel.Module.tooltip")); col1.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { if (element instanceof IModuleHandle) { // display a module IModuleHandle mh = (IModuleHandle) element; return mh.getName() + " " + mh.getVersion().toString("V.R.C"); } else { // display a category CatalogModulesProvider cp = (CatalogModulesProvider) ModuleCatalogPanel.this.treeViewer .getContentProvider(); int totalNb = cp.getAllVersionsOfModule((String) element).size(); return element.toString() + " [" + totalNb + "]"; } } @Override public Image getImage(Object element) { if (element instanceof IModuleHandle) { return MdaInfra.getImageDescriptor("icons/module.png").createImage(); } else { return MdaInfra.getImageDescriptor("icons/modulelist.png").createImage(); } } }); // The second column display the minimal version of Modelio that is // required to run the module TreeViewerColumn col2 = new TreeViewerColumn(this.treeViewer, SWT.CENTER); col2.getColumn().setWidth(200); col2.getColumn().setText(MdaInfra.I18N.getString("ModuleCatalogPanel.ModelioRequiredVersion.label")); col2.getColumn() .setToolTipText(MdaInfra.I18N.getString("ModuleCatalogPanel.ModelioRequiredVersion.tooltip")); col2.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { if (element instanceof IModuleHandle) { IModuleHandle mh = (IModuleHandle) element; return mh.getBinaryVersion().toString("V.R.C"); } return ""; } }); // The third column displays the predictable compatibility of the module // with the current Modelio version TreeViewerColumn col3 = new TreeViewerColumn(this.treeViewer, SWT.NONE); col3.getColumn().setWidth(200); col3.getColumn().setText(MdaInfra.I18N.getString("ModuleCatalogPanel.Compatibility.label")); col3.getColumn().setToolTipText(MdaInfra.I18N.getString("ModuleCatalogPanel.Compatibility.tooltip")); col3.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { if (element instanceof IModuleHandle) { IModuleHandle mh = (IModuleHandle) element; switch (CompatibilityHelper.getCompatibilityLevel(ModuleCatalogPanel.this.modelioEnv, mh)) { case COMPATIBLE: return MdaInfra.I18N.getString("ModuleCatalogPanel.message.Compatible"); case FULLYCOMPATIBLE: return MdaInfra.I18N.getString("ModuleCatalogPanel.message.FullyCompatible"); case MODELIO_TOO_OLD: return MdaInfra.I18N.getString("ModuleCatalogPanel.message.ModelioTooOld"); case MODULE_TOO_OLD: return MdaInfra.I18N.getString("ModuleCatalogPanel.message.ModuleTooOld"); default: break; } } return ""; } @Override public Color getForeground(Object element) { if (element instanceof IModuleHandle) { IModuleHandle mh = (IModuleHandle) element; switch (CompatibilityHelper.getCompatibilityLevel(ModuleCatalogPanel.this.modelioEnv, mh)) { case COMPATIBLE: return Display.getCurrent().getSystemColor(SWT.COLOR_BLUE); case FULLYCOMPATIBLE: return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GREEN); case MODELIO_TOO_OLD: case MODULE_TOO_OLD: return Display.getCurrent().getSystemColor(SWT.COLOR_RED); default: break; } } return super.getForeground(element); } }); // Activate the tooltip support for the viewer // ColumnViewerToolTipSupport.enableFor(treeViewer, // org.eclipse.jface.window.ToolTip.NO_RECREATE); // Option 'show only latest version' final Button latestOnly = new Button(this.top, SWT.CHECK); latestOnly.setText(MdaInfra.I18N.getString("ModuleCatalogPanel.ShowLatestVersions")); latestOnly.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { ModuleCatalogPanel.this.controller.onShowLatestOnly(latestOnly.getSelection()); } @Override public void widgetDefaultSelected(SelectionEvent e) { // } }); // Option 'show only compatible versions' final Button compatibleOnly = new Button(this.top, SWT.CHECK); compatibleOnly.setText(MdaInfra.I18N.getString("ModuleCatalogPanel.ShowCompatibleVersions")); compatibleOnly.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { ModuleCatalogPanel.this.controller.onShowCompatibleOnly(compatibleOnly.getSelection()); } @Override public void widgetDefaultSelected(SelectionEvent e) { // } }); // Carry out attachments (as the different widgets are attached // together, can only set their attachements here, when they all have // been created) FormData fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.right = new FormAttachment(100, 0); fd.bottom = new FormAttachment(100, 0); compatibleOnly.setLayoutData(fd); fd = new FormData(); fd.left = new FormAttachment(0, 0); fd.bottom = new FormAttachment(compatibleOnly, 0, SWT.TOP); fd.right = new FormAttachment(100, 0); latestOnly.setLayoutData(fd); fd = new FormData(); fd.top = new FormAttachment(0, 0); fd.left = new FormAttachment(0, 0); fd.bottom = new FormAttachment(latestOnly, -4); fd.right = new FormAttachment(100, 0); tree.setLayoutData(fd); this.loading.setLayoutData(fd); // FIXME // GUI is available, init the contents this.controller = new ModuleCatalogPanelController(this, this.modelioEnv); this.controller.init(); // Init checkbox states latestOnly.setSelection(this.controller.isShowLatestOnly()); compatibleOnly.setSelection(this.controller.isShowCompatibleOnly()); this.treeViewer.getTree().setVisible(false); return this; } @objid("45218eab-da58-41f2-9bd8-a92841497250") @Override public Object getPanel() { return this.top; } @objid("02b92101-9b04-4d36-97f9-9db07e677f6a") @Override public void setInput(Object input) { if (input instanceof IModuleCatalog) { this.controller.setInput((IModuleCatalog) input); this.refresh(true, true); } } @objid("7b9e08c6-1668-4575-9c13-cfca5667a2a7") @Override public Object getInput() { return this.controller.getInput(); } @objid("efb62edc-169f-4543-afdf-92a4a16e89c6") public Viewer getViewer() { return this.treeViewer; } @objid("10969d18-58ee-4cae-9a42-c2b2b3895607") void refresh(boolean updateLabels, boolean packColumns) { this.treeViewer.refresh(updateLabels); this.treeViewer.expandToLevel(3); if (packColumns) { for (TreeColumn tc : this.treeViewer.getTree().getColumns()) { tc.pack(); } } } @objid("836654f7-dbf0-4443-a99f-be30bb413ea0") public boolean isShowLatestOnly() { return this.controller.isShowLatestOnly(); } @objid("9da7101b-a0ce-4bca-94d6-60250b15b8fe") public List<IModuleHandle> allModules() { return this.controller.allModules(); } @objid("16e7ef0a-c575-4b5a-9199-3f514061151c") public void addDoubleClickListener(IDoubleClickListener listener) { this.treeViewer.addDoubleClickListener(listener); } @objid("4e6fd132-53f4-4577-869d-7ab0d93f074a") @Override public boolean isRelevantFor(Object obj) { return true; } @objid("3860d55b-9f3c-4451-94c7-35bfb6b4e8ce") @Override public String getHelpTopic() { return null; } @objid("231b1002-7740-4497-a09c-0241aa9d061e") private static class ModuleCatalogPanelController { @objid("c4a4466f-f357-4694-893b-365bbe5413ed") boolean compatibleOnly; @objid("9177f67b-b387-458a-bbec-5110fc2c4617") boolean lastestOnly; @objid("56905826-bb0d-4247-9f2d-bd3f4ecf3510") ModuleCatalogPanel dialog; @objid("6a6bb302-af11-4d63-88c7-93c26dc3c32f") private ModelioEnv modelioEnv; @objid("d0f8aa95-371d-4ad4-b291-ab6a262b278c") private IModuleCatalog catalog; @objid("fa2e94df-f646-4048-8865-d1e0d6f12b18") private CatalogModulesProvider contentProvider; @objid("c0c4da98-c93a-4436-a938-6ab6b7cdceea") private ScopedPreferenceStore prefs; @objid("2a400064-6431-4df7-bbe3-83b42bc05628") public ModuleCatalogPanelController(ModuleCatalogPanel dialog, ModelioEnv modelioEnv) { this.dialog = dialog; this.modelioEnv = modelioEnv; this.catalog = new FileModuleStore(modelioEnv.getModuleCatalogPath()); } @objid("6ff78e30-b221-4b3a-8001-18be25212587") public Object getInput() { return this.catalog; } @objid("2c49e20d-d813-42c6-b3d2-24522ed49513") public void setInput(IModuleCatalog input) { this.catalog = input; this.dialog.treeViewer.setInput(this.catalog); this.dialog.refresh(true, true); } @objid("b127bf2b-afed-4911-a4f4-67592d1a2bf4") public void init() { this.prefs = new ScopedPreferenceStore(InstanceScope.INSTANCE, MdaInfra.PLUGIN_ID); this.prefs.setDefault(CatalogUpdatePreferencesPage.CATALOG_SHOW_COMPATIBLE, true); this.prefs.setDefault(CatalogUpdatePreferencesPage.CATALOG_SHOW_LATEST, true); this.compatibleOnly = this.prefs.getBoolean(CatalogUpdatePreferencesPage.CATALOG_SHOW_COMPATIBLE); this.lastestOnly = this.prefs.getBoolean(CatalogUpdatePreferencesPage.CATALOG_SHOW_LATEST); this.contentProvider = new CatalogModulesProvider(this.dialog, this.modelioEnv.getVersion()); this.dialog.treeViewer.setContentProvider(this.contentProvider); this.dialog.treeViewer.setInput(this.catalog); this.dialog.refresh(true, true); } @objid("398a0633-5204-448d-906e-21b5ec0987f2") public void onShowCompatibleOnly(boolean onOff) { this.prefs.setValue(CatalogUpdatePreferencesPage.CATALOG_SHOW_COMPATIBLE, onOff); this.compatibleOnly = onOff; this.contentProvider.setCompatibleOnly(onOff); this.dialog.refresh(true, true); } @objid("f9d43c33-aa63-498b-9a01-b73308a4322c") public void onShowLatestOnly(boolean onOff) { this.prefs.setValue(CatalogUpdatePreferencesPage.CATALOG_SHOW_LATEST, onOff); this.lastestOnly = onOff; this.dialog.refresh(true, true); } @objid("92fd0ab2-5ed2-40a3-a347-9485099f40db") public boolean isShowLatestOnly() { return this.lastestOnly; } @objid("7d89c530-dde9-495b-8d12-c016ec69bedc") public boolean isShowCompatibleOnly() { return this.compatibleOnly; } @objid("727aeebb-bdde-4686-9c61-2b0458dd91a1") public List<IModuleHandle> allModules() { return this.contentProvider.allModules; } } /** * The module content provider is configured by two booleans: * <ul> * <li>compatibleOnly => list only modules that are compatible</li> * <li>latestOnly => list only the latest version of each module</li> * </ul> * * When NOT in 'latestOnly' mode, all the available versions of the modules are listed and organized by categories, a category * lists all the versions of a given module (ie there is one category per module type). In 'latestOnly' mode the datamodel does * not define categories as there is only one version for each module. * * @author phv */ @objid("6e22d92e-589f-4b9d-8e21-c4189d9a91da") private static class CatalogModulesProvider implements ITreeContentProvider { @objid("00985aae-7abe-4c61-b9f5-affa8791434b") List<IModuleHandle> allModules = new ArrayList<>(); @objid("02a749c5-5f20-454f-88e7-2468accf0a47") private Version modelioVersion; @objid("2cfab431-8ea4-46b0-a974-0913b57ff2c1") ModuleCatalogPanel panel; @objid("101e6f84-3307-46b9-bac2-0cc64bb3f500") TreeMap<String, List<IModuleHandle>> modules = new TreeMap<>(); @objid("3eeb6ede-175d-476f-97f2-13f986d45b1a") public CatalogModulesProvider(ModuleCatalogPanel panel, Version modelioVersion) { this.panel = panel; this.modelioVersion = modelioVersion; } @objid("2057f28a-700b-4e17-aa86-8497379c2cae") public List<IModuleHandle> getAllVersionsOfModule(String name) { if (this.modules.containsKey(name)) { return this.modules.get(name); } else { return new ArrayList<>(); } } @objid("0472384f-6821-419e-8b28-9e1954cfc6cd") @Override public void dispose() { // Nothing to dispose } @objid("ec24d068-99c8-4629-9603-42e8ed23f5a6") @Override public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) { if (newInput == null) { this.allModules = new ArrayList<>(); this.modules = computeModules(); this.panel.refresh(true, true); return; } if (newInput instanceof IModuleCatalog) { final IModuleCatalog catalog = (IModuleCatalog) newInput; Thread loadingThread = new Thread(new Runnable() { @Override public void run() { try { CatalogModulesProvider.this.allModules = catalog.findAllModules(null); } catch (IOException e) { MdaInfra.LOG.error(e); CatalogModulesProvider.this.allModules = new ArrayList<>(); } CatalogModulesProvider.this.modules = computeModules(); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { if (!CatalogModulesProvider.this.panel.top.isDisposed()) { CatalogModulesProvider.this.panel.treeViewer.getTree().setVisible(true); CatalogModulesProvider.this.panel.loading.setVisible(false); CatalogModulesProvider.this.panel.refresh(true, true); } } }); } }); loadingThread.setPriority(Thread.MAX_PRIORITY); loadingThread.start(); } } @objid("413a2bd2-83c3-44e8-93e9-b86cc031cc2e") TreeMap<String, List<IModuleHandle>> computeModules() { TreeMap<String, List<IModuleHandle>> results = new TreeMap<>(); for (IModuleHandle mh : this.allModules) { if (mh == null) continue; CompatibilityLevel level = CompatibilityHelper.getCompatibilityLevel(this.modelioVersion, mh.getBinaryVersion()); if (this.panel.controller.compatibleOnly && !CompatibilityHelper.isCompatible(level)) { // Skip it continue; } List<IModuleHandle> entries = results.get(mh.getName()); if (entries == null) { entries = new ArrayList<>(); results.put(mh.getName(), entries); } entries.add(mh); } // Sort by descending version for (List<IModuleHandle> entries : results.values()) { Collections.sort(entries, new ModuleComparator()); } return results; } @objid("bdf2c8eb-5232-4d8b-8a3f-62c673ef2f43") @Override public Object[] getElements(Object inputElement) { if (this.panel.controller.lastestOnly) { // return the latest versions of the modules ArrayList<IModuleHandle> latestVersions = new ArrayList<>(); for (String key : this.modules.keySet()) { latestVersions.add(this.modules.get(key).get(0)); } return latestVersions.toArray(); } else { // return categories => the keys return this.modules.keySet().toArray(); } } @objid("df580f3b-1ac0-47d3-b562-169a4501763e") @Override public Object[] getChildren(Object parentElement) { List<IModuleHandle> versions = this.modules.get(parentElement); if (!this.panel.controller.lastestOnly && versions != null) { return versions.toArray(); } return null; } @objid("b90c2fe6-29b8-4b9d-b5ea-82e9e8e16f3d") @Override public Object getParent(Object element) { return null; } @objid("30d6a036-57a7-4e4a-a281-86018bb0fb36") @Override public boolean hasChildren(Object element) { if (element instanceof String && getChildren(element) != null) { Object[] childrens = getChildren(element); if (childrens != null) { return childrens.length > 0; } } return false; } @objid("9e0d2eb6-a620-4002-b94d-1ec5fff986f7") public void setCompatibleOnly(boolean onOff) { this.modules = computeModules(); } } @objid("a3492460-7913-403e-8513-0e4de433f269") private static class ModuleComparator implements Comparator<IModuleHandle> { @objid("fc87f91e-6bb2-4c93-99bd-68250dbbeeb1") @Override public int compare(IModuleHandle o1, IModuleHandle o2) { if (o1.getVersion().isNewerThan(o2.getVersion())) { return -1; } else if (o1.getVersion().isOlderThan(o2.getVersion())) { return 1; } else return 0; } @objid("854c7c0e-45d3-4f2b-b468-7cb9a2c78aac") public ModuleComparator() { // Empty constructor } } }