Java tutorial
/******************************************************************************* * Copyright (c) 2011 THALES GLOBAL SERVICES. * 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: * Obeo - initial API and implementation *******************************************************************************/ package org.eclipse.sirius.ui.tools.api.wizards.page; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTableViewer; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.DecorationOverlayIcon; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.IDecoration; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.sirius.business.api.componentization.ViewpointRegistry; import org.eclipse.sirius.business.api.query.IdentifiedElementQuery; import org.eclipse.sirius.business.api.query.ViewpointQuery; import org.eclipse.sirius.business.api.session.Session; import org.eclipse.sirius.common.tools.api.util.StringUtil; import org.eclipse.sirius.ui.business.api.viewpoint.ViewpointSelection; import org.eclipse.sirius.ui.tools.api.views.ViewHelper; import org.eclipse.sirius.viewpoint.description.Viewpoint; import org.eclipse.sirius.viewpoint.provider.SiriusEditPlugin; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTError; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.osgi.framework.Bundle; import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import com.google.common.collect.Sets; /** * A wizard page to select viewpoints. * * @author mchauvin */ public class ViewpointsSelectionWizardPage extends WizardPage { /** The title of the page. */ private static final String PAGE_TITLE = "Select viewpoints"; private static final String PAGE_MESSAGE = "Select viewpoints to activate"; /** The table viewer. */ private TableViewer tableViewer; /** The browser for documentation */ private Browser browser; private Composite pageComposite; /** * The list of selected viewpoints */ private List<Viewpoint> viewpoints; /** * List of file extensions used to compute the available viewpoints. */ private Collection<String> fileExtensions; /** * List of viewpoints names that must be activate by default (ie checked in * the list). */ private ArrayList<String> viewpointsNamesToActivateByDefault; /** * Create a new <code>RepresentationSelectionWizardPage</code>. * * @param session * the session */ public ViewpointsSelectionWizardPage(final Session session) { super(PAGE_TITLE); this.setTitle(PAGE_TITLE); this.setMessage(PAGE_MESSAGE); this.fileExtensions = computeSemanticFileExtensions(session); this.viewpoints = Lists.newArrayList(); this.viewpointsNamesToActivateByDefault = Lists.newArrayList(); } /** * Create a new <code>RepresentationSelectionWizardPage</code> with default * viewpoints activation. This constructor makes this page optional. * * @param session * the session * @param viewpointsNamesToActivateByDefault * list of viewpoints names to activate by default. */ public ViewpointsSelectionWizardPage(final Session session, List<String> viewpointsNamesToActivateByDefault) { super(PAGE_TITLE); this.setTitle(PAGE_TITLE); this.setMessage(PAGE_MESSAGE); this.fileExtensions = computeSemanticFileExtensions(session); this.viewpoints = Lists.newArrayList(); this.viewpointsNamesToActivateByDefault = Lists.newArrayList(viewpointsNamesToActivateByDefault); } /** * compute the semantic file extensions to restrict the choice of viewpoint * based on the session. * * @param session * the session * @return a collection of file extension */ protected Collection<String> computeSemanticFileExtensions(Session session) { final Collection<String> extensions = new HashSet<String>(); for (final Resource resource : session.getSemanticResources()) { if (resource != null && resource.getURI() != null) { final String currentFileExtension = resource.getURI().fileExtension(); if (currentFileExtension != null) { extensions.add(currentFileExtension); } } } return extensions; } /** * {@inheritDoc} * * @see org.eclipse.jface.wizard.WizardPage#isPageComplete() */ @Override public boolean isPageComplete() { String errorMessage = null; boolean complete = false; if (!viewpoints.isEmpty()) { Map<String, Collection<String>> missingDependencies = ViewpointSelection .getMissingDependencies(Sets.newHashSet(viewpoints)); if (missingDependencies.isEmpty()) { complete = true; } else { errorMessage = ViewpointSelection.getMissingDependenciesErrorMessage(missingDependencies); } } setErrorMessage(errorMessage); return complete; } /** * Return the list of selected viewpoints of this page. * * @return the list of selected viewpoints */ public List<Viewpoint> getViewpoints() { return viewpoints; } /** * {@inheritDoc} * * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl(final Composite parent) { initializeDialogUnits(parent); pageComposite = new Composite(parent, SWT.NONE); pageComposite.setLayout(GridLayoutFactory.swtDefaults().numColumns(2).equalWidth(true).create()); pageComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); this.tableViewer = createTableViewer(pageComposite); tableViewer.setInput(getAvailableViewpoints()); this.browser = createBrowser(pageComposite); setBrowserInput(null); if (!viewpointsNamesToActivateByDefault.isEmpty()) { // Search the viewpoints to activate by their name for (int i = 0; i < tableViewer.getTable().getItemCount(); i++) { Object object = tableViewer.getElementAt(i); if (object instanceof Viewpoint && viewpointsNamesToActivateByDefault.contains(((Viewpoint) object).getName())) { viewpoints.add((Viewpoint) object); } } if (!viewpoints.isEmpty() && tableViewer instanceof CheckboxTableViewer) { // Check all the default viewpoints ((CheckboxTableViewer) tableViewer).setCheckedElements(viewpoints.toArray(new Object[0])); // Set the focus on the first one tableViewer.setSelection(new StructuredSelection(viewpoints.get(0))); } } setControl(pageComposite); } private Browser createBrowser(final Composite parent) { try { Browser aBrowser = new Browser(parent, SWT.NONE); final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); aBrowser.setLayoutData(gridData); return aBrowser; } catch (SWTError error) { /* * the browser could not be created, do not display further * information */ return null; } } private Collection<Viewpoint> getAvailableViewpoints() { ViewpointRegistry registry = ViewpointRegistry.getInstance(); return Collections2.filter(registry.getViewpoints(), new Predicate<Viewpoint>() { public boolean apply(Viewpoint viewpoint) { for (final String ext : fileExtensions) { if (new ViewpointQuery(viewpoint).handlesSemanticModelExtension(ext)) return true; } return false; } }); } /** * Create the table viewer. * * @param parent * the parent composite. * @return the table viewer. */ private TableViewer createTableViewer(final Composite parent) { final int style = SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER; CheckboxTableViewer viewer = CheckboxTableViewer.newCheckList(parent, style); Table table = viewer.getTable(); final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); viewer.getControl().setLayoutData(gridData); TableLayout layout = new TableLayout(); table.setLayout(layout); table.setHeaderVisible(false); table.setLinesVisible(false); TableColumn objectColumn = new TableColumn(table, SWT.NONE); layout.addColumnData(new ColumnWeightData(1, 60, true)); objectColumn.setResizable(true); viewer.setContentProvider(new ArrayContentProvider()); viewer.setLabelProvider(new ViewpointsTableLabelProvider()); viewer.addCheckStateListener(new ICheckStateListener() { public void checkStateChanged(final CheckStateChangedEvent event) { if (event.getChecked()) { viewpoints.add((Viewpoint) event.getElement()); } else { viewpoints.remove(event.getElement()); } setPageComplete(isPageComplete()); } }); viewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { Object firstElement = ((IStructuredSelection) selection).getFirstElement(); if (firstElement instanceof Viewpoint) { setBrowserInput((Viewpoint) firstElement); } } } }); viewer.setSorter(new ViewerSorter() { @Override public int compare(Viewer viewer, Object e1, Object e2) { final String e1label = new IdentifiedElementQuery((Viewpoint) e1).getLabel(); final String e2label = new IdentifiedElementQuery((Viewpoint) e2).getLabel(); return e1label.compareTo(e2label); } }); return viewer; } /*** * Set the browser input.A jface like browser viewer would have been better. * * @param viewpoint * the viewpoint to document */ protected void setBrowserInput(final Viewpoint viewpoint) { /* browser may be null if its creation fail */ if (browser != null) { String content = null; if (containsHTMLDocumentation(viewpoint)) { content = getContentWhenHtml(viewpoint); } else { content = getContentWhenNoHtml(viewpoint); } browser.setText(content); } } /* * The following code (HTML handling ) and methods could move to another * class. */ private boolean containsHTMLDocumentation(Viewpoint viewpoint) { if (viewpoint != null) { final String doc = viewpoint.getEndUserDocumentation(); if (!StringUtil.isEmpty(doc)) return doc.startsWith("<html>"); } return false; } private String getContentWhenHtml(Viewpoint viewpoint) { final String document = viewpoint.getEndUserDocumentation(); Set<String> urlToRewrite = Sets.newLinkedHashSet(); extractUrlToRewrite(document, urlToRewrite); return rewriteURLs(viewpoint, document, urlToRewrite); } private void extractUrlToRewrite(String document, Set<String> urlToRewrite) { String imgSrcPattern = "img src=\""; int patternStartIndex = document.indexOf(imgSrcPattern); if (patternStartIndex != -1) { int imgSrcStartIndex = patternStartIndex + imgSrcPattern.length(); int imgSrcStopIndex = document.indexOf("\"", imgSrcStartIndex); if (imgSrcStopIndex != -1) { String newToRewrite = document.substring(imgSrcStartIndex, imgSrcStopIndex); urlToRewrite.add(newToRewrite); extractUrlToRewrite(document.substring(imgSrcStopIndex), urlToRewrite); } } } private String rewriteURLs(Viewpoint viewpoint, String document, Set<String> urls) { String newDocument = document; for (final String url : urls) { newDocument = newDocument.replace(url, rewriteURL(viewpoint, url)); } StringBuilder css = new StringBuilder(); appendCss(css); String headClose = "</head>"; newDocument = newDocument.replace(headClose, css.append(headClose)); return newDocument; } private String rewriteURL(Viewpoint viewpoint, String url) { final URI uri = viewpoint.eResource().getURI(); String pluginId = uri.segment(1); String rewrittenURL = ""; if (uri.isPlatformPlugin()) { Bundle bundle = Platform.getBundle(pluginId); URL imageURL = bundle.getEntry(url); rewrittenURL = imageURL != null ? imageURL.toString() : rewrittenURL; if (imageURL != null) { try { URL fileURL = FileLocator.toFileURL(imageURL); rewrittenURL = fileURL.toString(); } catch (IOException e) { // do nothing } } } else { final IWorkspace workspace = ResourcesPlugin.getWorkspace(); final IPath path = new Path("/" + pluginId + url); if (workspace.getRoot().exists(path)) { IResource resource = workspace.getRoot().findMember(path); rewrittenURL = resource.getLocation().toFile().toURI().toString(); } } return rewrittenURL; } private String getContentWhenNoHtml(Viewpoint viewpoint) { StringBuilder content = new StringBuilder(); return begin(content).head(content).body(content, viewpoint).end(content); } private ViewpointsSelectionWizardPage begin(StringBuilder content) { content.append("<html>"); return this; } private ViewpointsSelectionWizardPage head(StringBuilder content) { content.append("<head>"); appendCss(content); content.append("</head>"); return this; } private ViewpointsSelectionWizardPage body(StringBuilder content, Viewpoint viewpoint) { content.append("<body>"); if (viewpoint == null) { content.append("<br><br><center><b>Documentation</b></center>"); } else { final String endUserDocumentation = viewpoint.getEndUserDocumentation(); if (!StringUtil.isEmpty(endUserDocumentation)) content.append(viewpoint.getEndUserDocumentation()); else content.append("no documentation for this viewpoint"); } content.append("</body>"); return this; } private StringBuilder appendCss(StringBuilder content) { Font currentFont = JFaceResources.getDialogFont(); FontData data = currentFont.getFontData()[0]; String fontName = data.getName(); int fontHeight = data.getHeight() + 3; content.append("<style type=\"text/css\">"); content.append("body{font-family:" + fontName + ",Arial, sans-serif;}"); content.append("body{font-size:" + fontHeight + "px;}"); content.append("</style>"); return content; } private String end(StringBuilder content) { content.append("</html>"); return content.toString(); } /** * return if the page is the current page. * * @return if the page is the current page. */ public boolean isCurrentPageOnWizard() { return super.isCurrentPage(); } /** * * @author mchauvin */ private class ViewpointsTableLabelProvider extends AdapterFactoryLabelProvider implements ITableLabelProvider { public ViewpointsTableLabelProvider() { super(ViewHelper.INSTANCE.createAdapterFactory()); } /** * {@inheritDoc} */ @Override public Image getColumnImage(Object element, int columnIndex) { Image image = null; if (columnIndex == 0) { if (element instanceof Viewpoint) { final Viewpoint vp = (Viewpoint) element; if (vp.getIcon() != null && vp.getIcon().length() > 0) { final ImageDescriptor desc = SiriusEditPlugin.Implementation .findImageDescriptor(vp.getIcon()); if (desc != null) { image = SiriusEditPlugin.getPlugin().getImage(desc); image = getEnhancedImage(image, vp); } } if (image == null) { image = SiriusEditPlugin.getPlugin() .getImage(SiriusEditPlugin.getPlugin().getItemImageDescriptor(vp)); image = getEnhancedImage(image, vp); } } else { image = super.getImage(element); } } return image; } private ImageDescriptor getOverlayedDescriptor(final Image baseImage, final String decoratorPath) { final ImageDescriptor decoratorDescriptor = SiriusEditPlugin.Implementation .getBundledImageDescriptor(decoratorPath); return new DecorationOverlayIcon(baseImage, decoratorDescriptor, IDecoration.BOTTOM_LEFT); } private Image getEnhancedImage(final Image image, final Viewpoint viewpoint) { // Add decorator if the viewpoint comes from workspace if (!ViewpointRegistry.getInstance().isFromPlugin(viewpoint) && image != null) { return SiriusEditPlugin.getPlugin() .getImage(getOverlayedDescriptor(image, "icons/full/decorator/folder_close.gif")); } return image; } } }