| /***************************************************************************** |
| * Copyright (c) 2010 Atos Origin. |
| * |
| * |
| * 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: |
| * Alexia Allanic (Atos Origin) alexia.allanic@atosorigin.com - Initial API and implementation |
| * Anne Haugommard (Atos) anne.haugommard@atos.net - Remove references to Papyrus Documentation services |
| * Mohamed Ali Bach Tobji (Atos) mohamed-ali.bachtobji@atos.net - fix bug #515404 : add getPapyrusTables method |
| * Antonio Campesino Robles (Ericsson) - Support for Tree tables. |
| *****************************************************************************/ |
| package org.eclipse.gendoc.bundle.acceleo.papyrus.service; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map.Entry; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.emf.common.util.BasicDiagnostic; |
| import org.eclipse.emf.common.util.Diagnostic; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.EMap; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.common.util.WrappedException; |
| import org.eclipse.emf.ecore.EAnnotation; |
| import org.eclipse.emf.ecore.EModelElement; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.edit.domain.EditingDomain; |
| import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl; |
| import org.eclipse.emf.transaction.util.TransactionUtil; |
| import org.eclipse.gendoc.bundle.acceleo.commons.files.CommonService; |
| import org.eclipse.gendoc.bundle.acceleo.gmf.service.GMFServices; |
| import org.eclipse.gendoc.bundle.acceleo.papyrus.Activator; |
| import org.eclipse.gendoc.services.GendocServices; |
| import org.eclipse.gendoc.services.IGendocDiagnostician; |
| import org.eclipse.gendoc.services.ILogger; |
| import org.eclipse.gendoc.services.exception.ModelNotFoundException; |
| import org.eclipse.gendoc.services.exception.ServiceException; |
| import org.eclipse.gendoc.tags.handlers.IEMFModelLoaderService; |
| import org.eclipse.gmf.runtime.notation.Diagram; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry; |
| import org.eclipse.nebula.widgets.nattable.grid.GridRegion; |
| import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer; |
| import org.eclipse.nebula.widgets.nattable.layer.DataLayer; |
| import org.eclipse.nebula.widgets.nattable.layer.ILayer; |
| import org.eclipse.nebula.widgets.nattable.layer.cell.ColumnOverrideLabelAccumulator; |
| import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell; |
| import org.eclipse.nebula.widgets.nattable.layer.cell.TranslatedLayerCell; |
| import org.eclipse.nebula.widgets.nattable.style.DisplayMode; |
| import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject; |
| import org.eclipse.papyrus.infra.nattable.dataprovider.BodyDataProvider; |
| import org.eclipse.papyrus.infra.nattable.manager.table.ITableAxisElementProvider; |
| import org.eclipse.papyrus.infra.nattable.manager.table.ITreeNattableModelManager; |
| import org.eclipse.papyrus.infra.nattable.manager.table.NattableModelManager; |
| import org.eclipse.papyrus.infra.nattable.selection.ObjectsSelectionExtractor; |
| import org.eclipse.papyrus.infra.nattable.utils.Constants; |
| import org.eclipse.papyrus.infra.nattable.utils.LabelProviderCellContextElementWrapper; |
| import org.eclipse.papyrus.infra.nattable.utils.NattableConfigAttributes; |
| import org.eclipse.papyrus.infra.nattable.utils.NattableModelManagerFactory; |
| import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService; |
| import org.eclipse.uml2.uml.Comment; |
| import org.eclipse.uml2.uml.Element; |
| import org.eclipse.uml2.uml.NamedElement; |
| |
| import org.eclipse.gendoc.table.Table; |
| import org.eclipse.gendoc.table.TableFactory; |
| import org.eclipse.gendoc.table.TableHeader; |
| |
| public class PapyrusServices extends GMFServices { |
| |
| private static final String ASSOCIATED_RESOURCES_SOURCE = "http://www.topcased.org/resources"; |
| private static final String PAPYRUS_DOCUMENTATION_STEREOTYPE_QUALIFIED_NAME = "Papyrus::Documentation::Documentation"; |
| private static final String PREFIX_WORKSPACE_RESOURCE = "WR"; //$NON-NLS-1$ |
| private static final String PREFIX_EXTERNAL_RESOURCE = "ER"; //$NON-NLS-1$ |
| private static final String PREFIX_REMOTE_RESOURCE = "RR"; //$NON-NLS-1$ |
| private static Pattern LINK_PATTERN = Pattern.compile("\\{@link #(\\w*)(\\s|$)*\\}"); |
| |
| @Override |
| public List<Diagram> getDiagrams(EObject e, URI uri) { |
| // ensure first diagrams resource is correctly loaded in Model set |
| IEMFModelLoaderService modelLoader = GendocServices.getDefault() |
| .getService(IEMFModelLoaderService.class); |
| try { |
| modelLoader.getModel(uri); |
| } catch (ModelNotFoundException e1) { |
| Activator |
| .getDefault() |
| .getLog() |
| .log(new Status(Status.WARNING, Activator.PLUGIN_ID, e1 |
| .getMessage(), e1)); |
| } |
| return super.getDiagrams(e, uri); |
| } |
| |
| /** |
| * Get the diagram list associated with the object. |
| * |
| * @param object |
| * the object |
| * |
| * @return the diagram list |
| */ |
| public List<Diagram> getPapyrusDiagrams(EObject object) { |
| |
| List<Diagram> result = getDiagramsUsingNotation(object); |
| // load main ".di" file in addition in resource set |
| // URI diURI = object.eResource().getURI().trimFileExtension().appendFileExtension("di");//$NON-NLS-1$ |
| // if (!object.eResource().getURI().equals(diURI)) |
| // { |
| // try |
| // { |
| // object.eResource().getResourceSet().getResource(diURI, true); |
| // } |
| // catch (WrappedException ex) |
| // { |
| // IGendocDiagnostician diag = |
| // GendocServices.getDefault().getService(IGendocDiagnostician.class); |
| // diag.addDiagnostic(new BasicDiagnostic(Diagnostic.ERROR, |
| // Activator.PLUGIN_ID, 0, |
| // String.format("Resource %s not found", diURI.toString()), new |
| // Object[] {object})); |
| // } |
| // |
| // } |
| return result; |
| } |
| |
| /** |
| * Get the documentation. |
| * |
| * @param eObject |
| * the object |
| * |
| * @return the documentation |
| */ |
| public String getDocumentation(EObject eObject) { |
| if (eObject instanceof Element) { |
| EList<Comment> ownedComments = ((Element) eObject) |
| .getOwnedComments(); |
| |
| for (Comment comment : ownedComments) { |
| if (comment |
| .getAppliedStereotype(PAPYRUS_DOCUMENTATION_STEREOTYPE_QUALIFIED_NAME) != null) { |
| String body = comment.getBody(); |
| return body; |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Get the documentation resources. |
| * |
| * @param object |
| * the object |
| * |
| * @return the documentation resources list. A list of absolute path |
| * resources. |
| */ |
| public List<String> getDocumentationResources(EObject object) { |
| List<String> absolutePaths = new ArrayList<String>(); |
| List<URI> uris = getAssociatedResources(object); |
| for (URI uri : uris) { |
| String absolutePath; |
| if (uri.isPlatform()) { |
| // transform relative uri to absolute |
| IPath filePath = Path.fromPortableString(uri |
| .toPlatformString(true)); |
| absolutePath = ResourcesPlugin.getWorkspace().getRoot() |
| .getLocation().toOSString() |
| + filePath; |
| } else if (uri.isFile()) { |
| absolutePath = uri.toFileString(); |
| } else { |
| absolutePath = uri.toString(); |
| } |
| absolutePaths.add(absolutePath); |
| } |
| return absolutePaths; |
| } |
| |
| /** |
| * Replace links text with the appropriate name of the linked object |
| * @param body, the string potentially containing {@link #(\w*)(\s|$)*} |
| * @param context, a given EObject, links will be searched inside this eobject's resource |
| * @return the modified String |
| */ |
| public String replaceLinksByNameOrLabel(String body, EObject context){ |
| ILogger logger = GendocServices.getDefault().getService(ILogger.class); |
| String result = "" ; |
| Matcher m = LINK_PATTERN.matcher(body); |
| int startIndex = 0; |
| int lastIndex = 0 ; |
| if (context == null || context.eResource() == null){ |
| IGendocDiagnostician diag = GendocServices.getDefault().getService(IGendocDiagnostician.class); |
| diag.addDiagnostic(new BasicDiagnostic(Diagnostic.WARNING, Activator.PLUGIN_ID, 0, String.format("error in script, invalid parameter for operation replaceLinksByNameOrLabel for text : %s",body), new Object[]{body})); |
| return body; |
| } |
| while(m.find()){ |
| String theLink = m.group(1); |
| startIndex = m.start(); |
| EObject linkedEObject = context.eResource().getEObject(theLink); |
| if (linkedEObject == null){ |
| logger.log(String.format("The linked object (%s) from %s is null", theLink, CommonService.getText(context)), IStatus.WARNING); |
| } |
| String toInsert = null; |
| if (linkedEObject == null){ |
| // Papyrus displays UNKNOWN when the element does not exist |
| toInsert = "UNKNOWN" ; |
| } |
| //it the object is a NamedElement return its name, otherwise get the label |
| else if(linkedEObject instanceof NamedElement){ |
| toInsert = ((NamedElement) linkedEObject).getName(); |
| } |
| else{ |
| toInsert = CommonService.getText(linkedEObject); |
| } |
| // part between the linked objects |
| String staticPart = body.substring(lastIndex, startIndex); |
| result += staticPart + toInsert ; |
| lastIndex = m.end(); |
| } |
| return result.concat(body.substring(lastIndex)); |
| } |
| |
| private List<URI> getAssociatedResources(EObject eObject) { |
| if (eObject instanceof EModelElement |
| && !(eObject instanceof EAnnotation)) { |
| EAnnotation annotation = ((EModelElement) eObject) |
| .getEAnnotation(ASSOCIATED_RESOURCES_SOURCE); |
| if (annotation != null) { |
| return convertDetailsToURIs(annotation.getDetails()); |
| } |
| } |
| return Collections.emptyList(); |
| } |
| |
| private static List<URI> convertDetailsToURIs(EMap<String, String> details) { |
| List<URI> uris = new LinkedList<URI>(); |
| for (Entry<String, String> detail : details) { |
| String value = detail.getValue(); |
| |
| String prefix = detail.getKey().substring(0, 2); |
| URI uri = null; |
| if (PREFIX_REMOTE_RESOURCE.equals(prefix)) { |
| uri = URI.createURI(value, false); |
| } else if (PREFIX_EXTERNAL_RESOURCE.equals(prefix)) { |
| uri = URI.createFileURI(value); |
| } else if (PREFIX_WORKSPACE_RESOURCE.equals(prefix)) { |
| uri = URI.createPlatformResourceURI(value, true); |
| } |
| uris.add(uri); |
| } |
| return uris; |
| } |
| |
| |
| |
| /** |
| * Get a collection of papyrus tables |
| * @param modelElement |
| * @return |
| * @throws ServiceException |
| * @throws org.eclipse.papyrus.infra.core.services.ServiceException |
| */ |
| public Collection<Table> getPapyrusTables(EObject modelElement) throws ServiceException, org.eclipse.papyrus.infra.core.services.ServiceException { |
| Collection<Table> result = null; |
| |
| URI uri = modelElement.eResource().getURI(); |
| Resource diResource = getDiResouce(modelElement, uri.trimFileExtension().appendFileExtension("notation")); |
| EditingDomain domain = TransactionUtil.getEditingDomain(diResource.getResourceSet()); |
| if (domain == null) { |
| domain = TransactionalEditingDomainImpl.FactoryImpl.INSTANCE.createEditingDomain(diResource.getResourceSet()); |
| } |
| |
| |
| for (Iterator<EObject> i = EcoreUtil.getAllProperContents(diResource, true); i.hasNext();) { |
| EObject eobject = i.next(); |
| if (eobject instanceof org.eclipse.papyrus.infra.nattable.model.nattable.Table) { |
| |
| org.eclipse.papyrus.infra.nattable.model.nattable.Table table = (org.eclipse.papyrus.infra.nattable.model.nattable.Table) eobject; |
| if (table.getOwner() != null && table.getOwner().equals(modelElement)) { |
| if(result == null) |
| { |
| result = new LinkedList<org.eclipse.gendoc.table.Table>(); |
| |
| } |
| result.add(getGendocTable(table)); |
| } |
| |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Transform a Papyrus Table to a GendocTable |
| * @param table Papyrus Nattable table |
| * @return the corresponding Gendoc table |
| * @throws ServiceException LabelProviderService not accessible |
| * @throws org.eclipse.papyrus.infra.core.services.ServiceException |
| */ |
| private Table getGendocTable(org.eclipse.papyrus.infra.nattable.model.nattable.Table table) throws ServiceException, org.eclipse.papyrus.infra.core.services.ServiceException { |
| Table gendocTable = TableFactory.eINSTANCE.createTable(); |
| // Set Papyrus table name |
| gendocTable.setName(table.getName()); |
| // Set Papyrus table type |
| gendocTable.setType(table.getTableConfiguration().getType()); |
| // Initialize useful services accessors |
| final NattableModelManager nattableModelManager = (NattableModelManager) NattableModelManagerFactory.INSTANCE |
| .createNatTableModelManager(table, new ObjectsSelectionExtractor()); |
| ITableAxisElementProvider axisElementProvider = nattableModelManager.getTableAxisElementProvider(); |
| List<Object> horizontalHeader = axisElementProvider.getColumnElementsList(); |
| LabelProviderService labelProviderService = ServiceUtilsForEObject.getInstance().getServiceRegistry(table.getContext()).getService(LabelProviderService.class); |
| ConfigRegistry configRegistry = new ConfigRegistry(); |
| configRegistry.registerConfigAttribute(NattableConfigAttributes.NATTABLE_MODEL_MANAGER_CONFIG_ATTRIBUTE, nattableModelManager, DisplayMode.NORMAL, NattableConfigAttributes.NATTABLE_MODEL_MANAGER_ID); |
| configRegistry.registerConfigAttribute(NattableConfigAttributes.LABEL_PROVIDER_SERVICE_CONFIG_ATTRIBUTE, labelProviderService, DisplayMode.NORMAL, NattableConfigAttributes.LABEL_PROVIDER_SERVICE_ID); |
| LabelProviderService serv = configRegistry.getConfigAttribute(NattableConfigAttributes.LABEL_PROVIDER_SERVICE_CONFIG_ATTRIBUTE, DisplayMode.NORMAL, NattableConfigAttributes.LABEL_PROVIDER_SERVICE_ID); |
| |
| // extracting data from axis |
| TableHeader header = TableFactory.eINSTANCE.createTableHeader(); |
| for (Object axis : horizontalHeader) { |
| org.eclipse.gendoc.table.Cell cell = TableFactory.eINSTANCE.createCell(); |
| cell.setLabel( getColumnLabel(nattableModelManager, configRegistry, serv, axis)); |
| header.getCells().add(cell); |
| } |
| gendocTable.setTableheader(header); |
| |
| // extracting data from body cells |
| |
| //FIXME remove references to ILayer, ILayerCell |
| ILayer dataLayer = new DataLayer(new BodyDataProvider(nattableModelManager)); |
| ((AbstractLayer) dataLayer).setConfigLabelAccumulator(new ColumnOverrideLabelAccumulator(dataLayer)); |
| ((AbstractLayer) dataLayer).setRegionName(GridRegion.BODY); |
| ILayerCell layer = new TranslatedLayerCell(null, dataLayer,0, 0, 0, 0); |
| for (int rowPosition = 0; rowPosition < nattableModelManager.getRowCount(); rowPosition++) { |
| boolean isEmpty = (nattableModelManager instanceof ITreeNattableModelManager); |
| org.eclipse.gendoc.table.Row row = TableFactory.eINSTANCE.createRow(); |
| for (int columnPosition = 0; columnPosition < nattableModelManager.getColumnCount(); columnPosition++) { |
| org.eclipse.gendoc.table.Cell cell = TableFactory.eINSTANCE.createCell(); |
| Object value = nattableModelManager.getDataValue(columnPosition, rowPosition); |
| LabelProviderCellContextElementWrapper contextElement = new LabelProviderCellContextElementWrapper(); |
| contextElement.setObject(value); |
| contextElement.setConfigRegistry(configRegistry); |
| ILabelProvider bodylabelProvider = serv.getLabelProvider(Constants.TABLE_LABEL_PROVIDER_CONTEXT, contextElement); |
| contextElement.setCell(layer); |
| String label = bodylabelProvider.getText(value); |
| cell.setLabel(label); |
| isEmpty = isEmpty && label.isEmpty(); |
| row.getCells().add(cell); |
| if (nattableModelManager instanceof ITreeNattableModelManager) { |
| ((ITreeNattableModelManager)nattableModelManager).getTreeList().setExpanded(rowPosition, true); |
| } |
| } |
| if (!isEmpty) |
| gendocTable.getRows().add(row); |
| } |
| return gendocTable; |
| } |
| |
| /** |
| * Get a label of Papyrus table axis |
| * @param nattableModelManager |
| * @param configRegistry |
| * @param serv |
| * @param axis |
| * @return |
| */ |
| private String getColumnLabel(final NattableModelManager nattableModelManager, ConfigRegistry configRegistry, |
| LabelProviderService serv, Object axis) { |
| LabelProviderCellContextElementWrapper contextElement = new LabelProviderCellContextElementWrapper(); |
| contextElement.setObject(axis); |
| contextElement.setConfigRegistry(configRegistry); |
| |
| //FIXME remove references to ILayer, ILayerCell |
| ILayer dataLayer = new DataLayer(new BodyDataProvider(nattableModelManager)); |
| ((AbstractLayer) dataLayer).setConfigLabelAccumulator(new ColumnOverrideLabelAccumulator(dataLayer)); |
| ((AbstractLayer) dataLayer).setRegionName(GridRegion.COLUMN_HEADER); |
| ILayerCell layer = new TranslatedLayerCell(null, dataLayer,0, 0, 0, 0); |
| contextElement.setCell(layer); |
| ILabelProvider headerlabelProvider = serv.getLabelProvider(Constants.HEADER_LABEL_PROVIDER_CONTEXT, contextElement); |
| return headerlabelProvider.getText(contextElement); |
| } |
| |
| /** |
| * @param modelElement |
| * @param notationFile |
| * @return |
| */ |
| private Resource getDiResouce(EObject modelElement, URI notationFile) { |
| Resource diResource = null; |
| if (modelElement.eResource().getURI().equals(notationFile)) { |
| diResource = modelElement.eResource(); |
| } else { |
| try { |
| diResource = modelElement.eResource().getResourceSet().getResource(notationFile, true); |
| } catch (WrappedException ex) { |
| IGendocDiagnostician diag = GendocServices.getDefault().getService(IGendocDiagnostician.class); |
| diag.addDiagnostic(new BasicDiagnostic(Diagnostic.ERROR, Activator.PLUGIN_ID, 0, |
| String.format("Resource %s not found", notationFile.toString()), new Object[] { modelElement })); |
| ex.printStackTrace(); |
| } |
| |
| } |
| return diResource; |
| } |
| |
| } |