| /** |
| * |
| * Copyright (c) 2011, 2016 - Lunifera GmbH (Gross Enzersdorf), Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Florian Pirchner (Lunifera GmbH) - initial implementation |
| */ |
| |
| package org.eclipse.osbp.tools.graphical.entity.lib.service; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.emf.common.command.Command; |
| import org.eclipse.emf.common.util.Diagnostic; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EReference; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.util.Diagnostician; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.edit.command.AddCommand; |
| import org.eclipse.emf.transaction.RecordingCommand; |
| import org.eclipse.emf.transaction.TransactionalEditingDomain; |
| import org.eclipse.osbp.dsl.semantic.common.helper.Bounds; |
| import org.eclipse.osbp.dsl.semantic.common.types.LAttribute; |
| import org.eclipse.osbp.dsl.semantic.common.types.LDataType; |
| import org.eclipse.osbp.dsl.semantic.common.types.LEnum; |
| import org.eclipse.osbp.dsl.semantic.common.types.LFeature; |
| import org.eclipse.osbp.dsl.semantic.common.types.LLowerBound; |
| import org.eclipse.osbp.dsl.semantic.common.types.LMultiplicity; |
| import org.eclipse.osbp.dsl.semantic.common.types.LOperation; |
| import org.eclipse.osbp.dsl.semantic.common.types.LPackage; |
| import org.eclipse.osbp.dsl.semantic.common.types.LReference; |
| import org.eclipse.osbp.dsl.semantic.common.types.LType; |
| import org.eclipse.osbp.dsl.semantic.common.types.LTypedPackage; |
| import org.eclipse.osbp.dsl.semantic.common.types.LUpperBound; |
| import org.eclipse.osbp.dsl.semantic.common.types.OSBPTypesFactory; |
| import org.eclipse.osbp.dsl.semantic.entity.LBean; |
| import org.eclipse.osbp.dsl.semantic.entity.LBeanAttribute; |
| import org.eclipse.osbp.dsl.semantic.entity.LBeanReference; |
| import org.eclipse.osbp.dsl.semantic.entity.LEntity; |
| import org.eclipse.osbp.dsl.semantic.entity.LEntityAttribute; |
| import org.eclipse.osbp.dsl.semantic.entity.LEntityFeature; |
| import org.eclipse.osbp.dsl.semantic.entity.LEntityModel; |
| import org.eclipse.osbp.dsl.semantic.entity.LEntityReference; |
| import org.eclipse.osbp.dsl.semantic.entity.OSBPEntityFactory; |
| import org.eclipse.osbp.dsl.semantic.entity.OSBPEntityPackage; |
| import org.eclipse.osbp.dsl.semantic.entity.util.OSBPEntitySwitch; |
| import org.eclipse.osbp.runtime.common.metric.TimeLogger; |
| import org.eclipse.osbp.xtext.oxtype.oxtype.OXImportDeclaration; |
| import org.eclipse.osbp.xtext.oxtype.oxtype.OXtypeFactory; |
| import org.eclipse.sirius.business.api.session.Session; |
| import org.eclipse.sirius.business.api.session.SessionManager; |
| import org.eclipse.sirius.diagram.DDiagram; |
| import org.eclipse.sirius.diagram.DDiagramElement; |
| import org.eclipse.sirius.diagram.DEdge; |
| import org.eclipse.sirius.diagram.DSemanticDiagram; |
| import org.eclipse.sirius.diagram.EdgeArrows; |
| import org.eclipse.sirius.diagram.business.internal.helper.task.operations.CreateViewTask; |
| import org.eclipse.sirius.diagram.business.internal.metamodel.spec.DNodeContainerSpec; |
| import org.eclipse.sirius.diagram.description.AbstractNodeMapping; |
| import org.eclipse.sirius.diagram.description.DiagramElementMapping; |
| import org.eclipse.sirius.diagram.description.tool.CreateView; |
| import org.eclipse.sirius.diagram.description.tool.ToolFactory; |
| import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor; |
| import org.eclipse.sirius.ecore.extender.business.api.accessor.exception.FeatureNotFoundException; |
| import org.eclipse.sirius.ecore.extender.business.api.accessor.exception.MetaClassNotFoundException; |
| import org.eclipse.sirius.tools.api.command.CommandContext; |
| import org.eclipse.sirius.viewpoint.DRepresentation; |
| import org.eclipse.sirius.viewpoint.DSemanticDecorator; |
| import org.eclipse.sirius.viewpoint.FontFormat; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IWorkbenchPage; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.ide.IDE; |
| import org.eclipse.ui.texteditor.AbstractTextEditor; |
| import org.eclipse.xtext.nodemodel.ICompositeNode; |
| import org.eclipse.xtext.nodemodel.util.NodeModelUtils; |
| import org.eclipse.xtext.resource.XtextResource; |
| import org.eclipse.xtext.xtype.XImportDeclaration; |
| import org.eclipse.xtext.xtype.XImportSection; |
| import org.eclipse.xtext.xtype.XtypeFactory; |
| |
| import com.google.common.base.Ascii; |
| import com.google.common.base.CharMatcher; |
| import com.google.common.base.Function; |
| import com.google.common.base.Optional; |
| import com.google.common.base.Predicate; |
| import com.google.common.base.Splitter; |
| import com.google.common.collect.Iterables; |
| import com.google.common.collect.Iterators; |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Ordering; |
| import com.google.common.collect.Sets; |
| |
| @SuppressWarnings("restriction") |
| public class EntityService { |
| |
| public Boolean hasError(EObject eObj) { |
| if (eObj instanceof LType || eObj instanceof LFeature) { |
| Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObj); |
| DiagnosticAttachment.getOrCreate(eObj, diagnostic); |
| return diagnostic.getSeverity() == Diagnostic.ERROR; |
| } |
| return false; |
| } |
| |
| public List<EObject> getValidsForDiagram(final EObject element, final DSemanticDecorator containerView) { |
| Predicate<EObject> validForClassDiagram = new Predicate<EObject>() { |
| public boolean apply(EObject input) { |
| return input instanceof LTypedPackage || input instanceof LType; |
| } |
| }; |
| return allValidSessionElements(element, validForClassDiagram); |
| } |
| |
| public LEntityModel getEntityModel(LTypedPackage pkg) { |
| return (LEntityModel) pkg.eContainer(); |
| } |
| |
| /** |
| * Returns all the root objects of all the resources in the same |
| * resource-set as the specified object. |
| * |
| * @param any |
| * an EObject. |
| * @return all the root objects in the same resource-set as <code>any</code> |
| * or an empty collection if <code>any</code> is not inside a |
| * resource-set. |
| */ |
| public Collection<EObject> allRoots(EObject any) { |
| Resource res = any.eResource(); |
| if (res != null && res.getResourceSet() != null) { |
| Collection<EObject> roots = new ArrayList<EObject>(); |
| for (Resource childRes : res.getResourceSet().getResources()) { |
| roots.addAll(childRes.getContents()); |
| } |
| return roots; |
| } else { |
| return Collections.emptySet(); |
| } |
| } |
| |
| public Collection<LType> rootElements(EObject any) { |
| return Sets.newLinkedHashSet(Iterables.filter(allRoots(any), LType.class)); |
| } |
| |
| public Collection<LFeature> children(LType lType) { |
| return Sets.newLinkedHashSet(Iterables.filter(allRoots(lType), LFeature.class)); |
| } |
| |
| private List<EObject> allValidSessionElements(EObject cur, Predicate<EObject> validForClassDiagram) { |
| Session found = SessionManager.INSTANCE.getSession(cur); |
| List<EObject> result = Lists.newArrayList(); |
| if (found != null) { |
| for (Resource res : found.getSemanticResources()) { |
| if (res.getURI().isPlatformResource() || res.getURI().isPlatformPlugin()) { |
| Iterators.addAll(result, Iterators.filter(res.getAllContents(), validForClassDiagram)); |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Gets the containing resource name, or null. |
| * |
| * @param current |
| * is the object |
| * @return the resource |
| */ |
| public String eResourceName(final EObject current) { |
| if (current != null && current.eResource() != null) { |
| return current.eResource().getURI().lastSegment(); |
| } else { |
| return null; |
| } |
| } |
| |
| /** |
| * Performs a "direct edit" operation on an LAttribute. |
| */ |
| // TODO siehe DesignServices |
| public LAttribute performEdit(LAttribute attr, String editString) { |
| String[] tokens = editString.split(":"); |
| attr.setName(tokens[0].trim()); |
| return attr; |
| } |
| |
| /** |
| * Performs a "direct edit" operation on an LReference. |
| */ |
| // TODO siehe DesignServices |
| public LReference performEdit(LReference attr, String editString) { |
| attr.setName(editString); |
| return attr; |
| } |
| |
| public LTypedPackage performEdit(LTypedPackage pkg, String editString) { |
| pkg.setName(editString); |
| return pkg; |
| } |
| |
| public String render(LAttribute attr) { |
| StringBuilder b = new StringBuilder(); |
| b.append(attr.getName()); |
| b.append(" : "); |
| b.append(render(attr.getType())); |
| |
| return b.toString(); |
| } |
| |
| public String render(LType type) { |
| return type != null ? type.getName() : ""; |
| } |
| |
| public String renderTooltip(EObject current) { |
| String result = ""; |
| Optional<Diagnostic> diag = DiagnosticAttachment.get(current); |
| if (diag.isPresent()) { |
| result += prettyMessage(diag.get()); |
| } |
| return result; |
| } |
| |
| public String prettyMessage(Diagnostic diag) { |
| String result = ""; |
| for (Diagnostic child : diag.getChildren()) { |
| result += "\n" + severityLabel(child.getSeverity()) + " : " + child.getMessage(); |
| result += prettyMessage(child); |
| } |
| return result; |
| } |
| |
| public String eKeysLabel(LAttribute att) { |
| LMultiplicity mult = att.getMultiplicity(); |
| if (mult == null) { |
| mult = OSBPTypesFactory.eINSTANCE.createLMultiplicity(); |
| Bounds zeroToOne = Bounds.createZeroToOne(); |
| mult.setLower(zeroToOne.getLower()); |
| mult.setUpper(zeroToOne.getUpper()); |
| } |
| return mult.getToMultiplicityString(); |
| } |
| |
| public String eKeysLabel(LReference ref) { |
| LMultiplicity mult = ref.getMultiplicity(); |
| if (mult == null) { |
| mult = OSBPTypesFactory.eINSTANCE.createLMultiplicity(); |
| Bounds zeroToOne = Bounds.createZeroToOne(); |
| mult.setLower(zeroToOne.getLower()); |
| mult.setUpper(zeroToOne.getUpper()); |
| } |
| return mult.getToMultiplicityString(); |
| } |
| |
| public EdgeArrows arrowsFillDiamond(EObject any) { |
| return EdgeArrows.FILL_DIAMOND_LITERAL; |
| } |
| |
| public FontFormat fontFormatBold(EObject any) { |
| return FontFormat.BOLD_LITERAL; |
| } |
| |
| public boolean isRequired(LFeature att) { |
| return Bounds.createFor(att).isRequired(); |
| } |
| |
| public boolean isCascading(LFeature att) { |
| if (att instanceof LReference) { |
| return ((LReference) att).isCascading(); |
| } |
| return false; |
| } |
| |
| public boolean isContainer(LFeature att) { |
| return false; |
| } |
| |
| public boolean isOperation(LFeature feature) { |
| return feature instanceof LOperation; |
| } |
| |
| public String severityLabel(int severity) { |
| switch (severity) { |
| case Diagnostic.ERROR: |
| return "ERROR"; |
| case Diagnostic.CANCEL: |
| return "CANCEL"; |
| case Diagnostic.INFO: |
| return "INFO"; |
| case Diagnostic.WARNING: |
| return "WARNING"; |
| case Diagnostic.OK: |
| return "OK"; |
| |
| } |
| return "UNKNOWN"; |
| } |
| |
| /** |
| * Replace spaces by camel case value. |
| * |
| * @param any |
| * @param from |
| * @return |
| */ |
| public String toCamelCase(EObject any, String from) { |
| if (from != null) { |
| StringBuffer buffer = new StringBuffer(from.length()); |
| for (String word : Splitter.on(CharMatcher.WHITESPACE).trimResults().split(from)) { |
| buffer.append(toU1Case(word)); |
| } |
| return buffer.toString(); |
| } |
| return from; |
| } |
| |
| private String toU1Case(String word) { |
| if (word != null && word.length() > 0) { |
| return new StringBuilder(word.length()).append(Ascii.toUpperCase(word.charAt(0))).append(word.substring(1)) |
| .toString(); |
| } |
| return word; |
| } |
| |
| public EObject markForAutosize(EObject any) { |
| if (any != null) { |
| any.eAdapters().add(AutosizeTrigger.AUTO_SIZE_MARKER); |
| } |
| return any; |
| } |
| |
| public boolean isEntityPackage(LTypedPackage pkg) { |
| EObject model = pkg.eContainer(); |
| return model instanceof LEntityModel; |
| } |
| |
| public boolean isEntity(EObject any) { |
| return any instanceof LEntity; |
| } |
| |
| public boolean isBean(EObject any) { |
| return any instanceof LBean; |
| } |
| |
| public boolean isEnum(EObject any) { |
| return any instanceof LEnum; |
| } |
| |
| public boolean isPackage(EObject any) { |
| return any instanceof LPackage; |
| } |
| |
| public List<EObject> children(final LTypedPackage pkg) { |
| final String pkgName = pkg.getName(); |
| Iterable<LTypedPackage> iterable = Iterables.filter(allPackages(pkg), new Predicate<LTypedPackage>() { |
| @Override |
| public boolean apply(LTypedPackage input) { |
| return !input.getName().equals(pkgName); |
| } |
| }); |
| |
| return Lists.<EObject>newLinkedList(iterable); |
| } |
| |
| public Boolean viewContainerNotSemanticContainer(EObject self, DSemanticDiagram diag, |
| DSemanticDecorator containerView) { |
| EObject target = containerView.getTarget(); |
| return target != self.eContainer(); |
| } |
| |
| public Collection<EObject> getRelated(EObject firstView, List<EObject> allSelectedViews, DDiagram diag) { |
| Set<EObject> relateds = Sets.newLinkedHashSet(); |
| for (DSemanticDecorator decorator : Iterables.filter(allSelectedViews, DSemanticDecorator.class)) { |
| relateds.addAll(new RelatedElementsSwitch().getRelatedElements(decorator.getTarget())); |
| } |
| return relateds; |
| } |
| |
| public void openClassDiagramContextHelp(EObject any) { |
| } |
| |
| public Collection<LTypedPackage> allPackages(EObject any) { |
| Resource res = any.eResource(); |
| if (res != null && res.getResourceSet() != null) { |
| Collection<LTypedPackage> roots = new ArrayList<LTypedPackage>(); |
| for (Resource childRes : res.getResourceSet().getResources()) { |
| if (childRes.getContents().isEmpty()) { |
| continue; |
| } |
| EObject element = childRes.getContents().get(0); |
| if (element instanceof LEntityModel) { |
| roots.addAll(((LEntityModel) element).getPackages()); |
| } |
| } |
| return roots; |
| } else { |
| return Collections.emptySet(); |
| } |
| } |
| |
| public boolean hasOpposite(EReference ref) { |
| return getOppositeReferences(ref) != null; |
| } |
| |
| public List<LFeature> getOppositeReferences(EObject ref) { |
| if (ref instanceof LReference) { |
| return getOppositeSemanticElements((LReference) ref); |
| } else { |
| return Collections.emptyList(); |
| } |
| } |
| |
| public List<LFeature> getOppositeSemanticElements(LReference ref) { |
| Set<LFeature> allRefs = Sets.newLinkedHashSet(); |
| |
| LFeature opposite = getOpposite(ref); |
| allRefs.add(ref); |
| if (opposite != null) { |
| allRefs.add(opposite); |
| } |
| return Ordering.natural().onResultOf(new Function<LFeature, String>() { |
| public String apply(LFeature input) { |
| return input.getName(); |
| } |
| }).sortedCopy(allRefs); |
| } |
| |
| public String renderOpposite(LReference ref) { |
| LFeature opposite = getOpposite(ref); |
| |
| if (opposite == null) { |
| return ""; |
| } |
| |
| StringBuilder b = new StringBuilder(); |
| b.append("["); |
| b.append(opposite.getMultiplicity().getToMultiplicityString()); |
| b.append("]"); |
| b.append(" "); |
| b.append(opposite.getName()); |
| |
| return b.toString(); |
| } |
| |
| public String render(LReference ref) { |
| if (ref == null) { |
| return ""; |
| } |
| |
| StringBuilder b = new StringBuilder(); |
| b.append("["); |
| b.append(ref.getMultiplicity().getToMultiplicityString()); |
| b.append("]"); |
| b.append(" "); |
| b.append(ref.getName()); |
| |
| return b.toString(); |
| } |
| |
| public boolean noOpposite(LReference ref) { |
| return getOpposite(ref) == null; |
| } |
| |
| private LFeature getOpposite(LReference ref) { |
| if (ref instanceof LEntityReference) { |
| return ((LEntityReference) ref).getOpposite(); |
| } else if (ref instanceof LBeanReference) { |
| ((LBeanReference) ref).getOpposite(); |
| } |
| return null; |
| } |
| |
| /** |
| * Paste a semantic element and create the corresponding view in the given |
| * container |
| * |
| * @param container |
| * Semantic container |
| * @param semanticElement |
| * Element to paste |
| * @param containerView |
| * Container view |
| */ |
| public void paste(final EObject container, final EObject semanticElement, final DSemanticDecorator elementView, |
| final DSemanticDecorator containerView) { |
| // Paste the semantic element from the clipboard to the selected |
| // container |
| final Session session = SessionManager.INSTANCE.getSession(container); |
| TransactionalEditingDomain domain = session.getTransactionalEditingDomain(); |
| |
| Command cmd = null; |
| if (container instanceof LEntity && semanticElement instanceof LEntityAttribute) { |
| cmd = AddCommand.create(domain, container, OSBPEntityPackage.Literals.LENTITY__FEATURES, semanticElement); |
| } else if (container instanceof LBean && semanticElement instanceof LBeanAttribute) { |
| cmd = AddCommand.create(domain, container, OSBPEntityPackage.Literals.LBEAN__FEATURES, semanticElement); |
| } else if (container instanceof LEntity && semanticElement instanceof LBeanAttribute) { |
| |
| LBeanAttribute beanAtt = EcoreUtil.copy((LBeanAttribute) semanticElement); |
| cmd = AddCommand.create(domain, container, OSBPEntityPackage.Literals.LENTITY__FEATURES, |
| createEntityAttribute(beanAtt)); |
| } else if (container instanceof LBean && semanticElement instanceof LEntityAttribute) { |
| LEntityAttribute entityAtt = EcoreUtil.copy((LEntityAttribute) semanticElement); |
| cmd = AddCommand.create(domain, container, OSBPEntityPackage.Literals.LBEAN__FEATURES, |
| createBeanAttribute(entityAtt)); |
| } else { |
| cmd = AddCommand.create(domain, container, null, semanticElement); |
| } |
| |
| // The feature is set to null because the domain will deduce it |
| |
| if (cmd.canExecute()) { |
| cmd.execute(); |
| } |
| // Create the view for the pasted element |
| createView(semanticElement, containerView, session, "containerView"); |
| } |
| |
| private LEntityAttribute createEntityAttribute(LBeanAttribute beanAtt) { |
| LEntityAttribute entityAtt = OSBPEntityFactory.eINSTANCE.createLEntityAttribute(); |
| |
| entityAtt.setAnnotationInfo(beanAtt.getAnnotationInfo()); |
| entityAtt.setCascading(beanAtt.isCascading()); |
| entityAtt.setDerived(beanAtt.isDerived()); |
| entityAtt.setDirty(beanAtt.isDirty()); |
| entityAtt.setDerivedGetterExpression(beanAtt.getDerivedGetterExpression()); |
| entityAtt.setDomainDescription(beanAtt.isDomainDescription()); |
| entityAtt.setDomainKey(beanAtt.isDomainKey()); |
| entityAtt.setId(beanAtt.isId()); |
| entityAtt.setLazy(beanAtt.isLazy()); |
| entityAtt.setMultiplicity(beanAtt.getMultiplicity()); |
| entityAtt.setName(beanAtt.getName()); |
| entityAtt.setTransient(beanAtt.isTransient()); |
| entityAtt.setType(beanAtt.getType()); |
| entityAtt.setUuid(beanAtt.isUuid()); |
| entityAtt.setVersion(beanAtt.isVersion()); |
| |
| entityAtt.getAnnotations().addAll(beanAtt.getAnnotations()); |
| entityAtt.getProperties().addAll(beanAtt.getProperties()); |
| entityAtt.getResolvedAnnotations().addAll(beanAtt.getResolvedAnnotations()); |
| return entityAtt; |
| } |
| |
| private LBeanAttribute createBeanAttribute(LEntityAttribute entityAtt) { |
| LBeanAttribute beanAtt = OSBPEntityFactory.eINSTANCE.createLBeanAttribute(); |
| |
| beanAtt.setAnnotationInfo(entityAtt.getAnnotationInfo()); |
| beanAtt.setCascading(entityAtt.isCascading()); |
| beanAtt.setDerived(entityAtt.isDerived()); |
| beanAtt.setDirty(entityAtt.isDirty()); |
| beanAtt.setDerivedGetterExpression(entityAtt.getDerivedGetterExpression()); |
| beanAtt.setDomainDescription(entityAtt.isDomainDescription()); |
| beanAtt.setDomainKey(entityAtt.isDomainKey()); |
| beanAtt.setId(entityAtt.isId()); |
| beanAtt.setLazy(entityAtt.isLazy()); |
| beanAtt.setMultiplicity(entityAtt.getMultiplicity()); |
| beanAtt.setName(entityAtt.getName()); |
| beanAtt.setTransient(entityAtt.isTransient()); |
| beanAtt.setType(entityAtt.getType()); |
| beanAtt.setUuid(entityAtt.isUuid()); |
| beanAtt.setVersion(entityAtt.isVersion()); |
| |
| beanAtt.getAnnotations().addAll(entityAtt.getAnnotations()); |
| beanAtt.getProperties().addAll(entityAtt.getProperties()); |
| beanAtt.getResolvedAnnotations().addAll(entityAtt.getResolvedAnnotations()); |
| return beanAtt; |
| } |
| |
| /** |
| * Create view. |
| * |
| * @param semanticElement |
| * Semantic element |
| * @param containerView |
| * Container view |
| * @param session |
| * Session |
| * @param containerViewVariable |
| * Name of the container view variable |
| */ |
| private void createView(final EObject semanticElement, final DSemanticDecorator containerView, |
| final Session session, final String containerViewVariable) { |
| // Get all available mappings applicable for the copiedElement in the |
| // current container |
| List<DiagramElementMapping> semanticElementMappings = getMappings(semanticElement, containerView, session); |
| |
| // Build a createView tool |
| final CreateView createViewOp = ToolFactory.eINSTANCE.createCreateView(); |
| for (DiagramElementMapping copiedElementMapping : semanticElementMappings) { |
| final DiagramElementMapping tmpCopiedElementMapping = copiedElementMapping; |
| createViewOp.setMapping(tmpCopiedElementMapping); |
| final String containerViewExpression = "var:" + containerViewVariable; |
| createViewOp.setContainerViewExpression(containerViewExpression); |
| |
| session.getTransactionalEditingDomain().getCommandStack() |
| .execute(new RecordingCommand(session.getTransactionalEditingDomain()) { |
| |
| @Override |
| protected void doExecute() { |
| try { |
| // Get the command context |
| DRepresentation representation = null; |
| if (containerView instanceof DRepresentation) { |
| representation = (DRepresentation) containerView; |
| } else if (containerView instanceof DDiagramElement) { |
| representation = ((DDiagramElement) containerView).getParentDiagram(); |
| } |
| |
| final CommandContext context = new CommandContext(semanticElement, representation); |
| |
| // Execute the create view task |
| new CreateViewTask(context, session.getModelAccessor(), createViewOp, |
| session.getInterpreter()).execute(); |
| } catch (MetaClassNotFoundException e) { |
| } catch (FeatureNotFoundException e) { |
| } |
| } |
| }); |
| } |
| } |
| |
| /** |
| * Get mappings available for a semantic element and a given container view. |
| * |
| * @param semanticElement |
| * Semantic element |
| * @param containerView |
| * Container view |
| * @param session |
| * Session |
| * @return List of mappings which could not be null |
| */ |
| private List<DiagramElementMapping> getMappings(final EObject semanticElement, |
| final DSemanticDecorator containerView, Session session) { |
| ModelAccessor modelAccessor = session.getModelAccessor(); |
| List<DiagramElementMapping> mappings = new ArrayList<DiagramElementMapping>(); |
| |
| if (containerView instanceof DSemanticDiagram) { |
| for (DiagramElementMapping mapping : (((DSemanticDiagram) containerView).getDescription() |
| .getAllContainerMappings())) { |
| String domainClass = ((AbstractNodeMapping) mapping).getDomainClass(); |
| if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) { |
| mappings.add(mapping); |
| } |
| } |
| for (DiagramElementMapping mapping : (((DSemanticDiagram) containerView).getDescription() |
| .getAllNodeMappings())) { |
| String domainClass = ((AbstractNodeMapping) mapping).getDomainClass(); |
| if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) { |
| mappings.add(mapping); |
| } |
| } |
| } else if (containerView instanceof DNodeContainerSpec) { |
| for (DiagramElementMapping mapping : (((DNodeContainerSpec) containerView).getActualMapping() |
| .getAllContainerMappings())) { |
| String domainClass = ((AbstractNodeMapping) mapping).getDomainClass(); |
| if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) { |
| mappings.add(mapping); |
| } |
| } |
| for (DiagramElementMapping mapping : (((DNodeContainerSpec) containerView).getActualMapping() |
| .getAllNodeMappings())) { |
| String domainClass = ((AbstractNodeMapping) mapping).getDomainClass(); |
| if (modelAccessor.eInstanceOf(semanticElement, domainClass) && !mapping.isCreateElements()) { |
| mappings.add(mapping); |
| } |
| } |
| } |
| return mappings; |
| } |
| |
| public LTypedPackage createNewPackage(LTypedPackage container) { |
| LEntityModel model = (LEntityModel) container.eContainer(); |
| LTypedPackage typedPackage = OSBPTypesFactory.eINSTANCE.createLTypedPackage(); |
| typedPackage.setName(container.getName() + "." + "n" + model.getPackages().size()); |
| model.getPackages().add(typedPackage); |
| |
| return typedPackage; |
| } |
| |
| public void reconnectReference(EObject element, DEdge oldEdge, DSemanticDecorator sourceNode, |
| DSemanticDecorator targetNode, EObject source, EObject target) { |
| |
| if (element instanceof LEntityReference) { |
| LEntityReference entityRef = (LEntityReference) element; |
| |
| // if not refTypeChanged, then entityChanged |
| boolean refTypeChanged = entityRef.getType() == source; |
| |
| if (refTypeChanged) { |
| entityRef.setType((LEntity) target); |
| |
| if (entityRef.getOpposite() != null) { |
| LEntityReference opposite = entityRef.getOpposite(); |
| LEntity newOpposisteContainerEntity = (LEntity) target; |
| newOpposisteContainerEntity.getFeatures().add(opposite); |
| } |
| |
| } else { |
| LEntity newContainerEntity = (LEntity) target; |
| newContainerEntity.getFeatures().add(entityRef); |
| |
| if (entityRef.getOpposite() != null) { |
| LEntityReference opposite = entityRef.getOpposite(); |
| opposite.setType(newContainerEntity); |
| } |
| } |
| } |
| } |
| |
| public void reconnectSuperType(EObject element, DEdge oldEdge, DSemanticDecorator sourceNode, |
| DSemanticDecorator targetNode, EObject source, EObject target) { |
| |
| if (element instanceof LEntity) { |
| LEntity entity = (LEntity) element; |
| |
| LEntity targetEntity = (LEntity) target; |
| LEntity sourceEntity = (LEntity) source; |
| |
| boolean superTypeChanged = entity.getSuperType() == sourceEntity; |
| if (superTypeChanged) { |
| entity.setSuperType(targetEntity); |
| sourceEntity.getSubTypes().remove(entity); |
| } else { |
| // subtype changed |
| LEntity affectedSuperType = sourceEntity.getSuperType(); |
| sourceEntity.setSuperType(null); |
| affectedSuperType.getSubTypes().remove(sourceEntity); |
| |
| targetEntity.setSuperType(affectedSuperType); |
| affectedSuperType.getSubTypes().add(targetEntity); |
| } |
| } else if (element instanceof LBean) { |
| LBean bean = (LBean) element; |
| |
| LBean targetEntity = (LBean) target; |
| LBean sourceEntity = (LBean) source; |
| |
| boolean superTypeChanged = bean.getSuperType() == sourceEntity; |
| if (superTypeChanged) { |
| bean.setSuperType(targetEntity); |
| sourceEntity.getSubTypes().remove(bean); |
| } else { |
| // subtype changed |
| LBean affectedSuperType = sourceEntity.getSuperType(); |
| sourceEntity.setSuperType(null); |
| affectedSuperType.getSubTypes().remove(sourceEntity); |
| |
| targetEntity.setSuperType(affectedSuperType); |
| affectedSuperType.getSubTypes().add(targetEntity); |
| } |
| |
| } |
| } |
| |
| public boolean dropType(EObject var, LType type, LTypedPackage newSemanticContainer, |
| LTypedPackage oldSemanticContainer) { |
| |
| Set<LTypedPackage> related = getRelatedPackages(type); |
| related.add(oldSemanticContainer); |
| related.add(newSemanticContainer); |
| |
| // do the move |
| oldSemanticContainer.getTypes().remove(type); |
| newSemanticContainer.getTypes().add(type); |
| |
| // fix imports |
| // |
| TimeLogger logger = TimeLogger.start(getClass()); |
| for (LTypedPackage pkg : related) { |
| fixImports(pkg); |
| } |
| logger.stop("Fixing imports for dropped " + type.getName()); |
| |
| return true; |
| } |
| |
| protected Set<LTypedPackage> getRelatedPackages(LType type) { |
| RelatedElementsSwitch rS = new RelatedElementsSwitch(); |
| List<EObject> related = rS.getRelatedElements(type); |
| |
| Set<LTypedPackage> result = new HashSet<LTypedPackage>(); |
| for (EObject r : related) { |
| if (r instanceof LType) { |
| LTypedPackage pkg = (LTypedPackage) r.eContainer(); |
| result.add(pkg); |
| } else if (r instanceof LReference) { |
| // r.type == given type && r is reference from somewhere to type |
| LType lType = (LType) r.eContainer(); |
| LTypedPackage pkg = (LTypedPackage) lType.eContainer(); |
| result.add(pkg); |
| } |
| } |
| |
| return result; |
| } |
| |
| public boolean removeReference(LEntityReference ref) { |
| |
| LEntity source = ref.getEntity(); |
| LEntity target = ref.getType(); |
| |
| source.getFeatures().remove(ref); |
| ref.setType(null); |
| |
| if (ref.getOpposite() != null) { |
| target.getFeatures().remove(ref.getOpposite()); |
| ref.getOpposite().setType(null); |
| ref.getOpposite().setOpposite(null); |
| } |
| |
| fixImports(source, source); |
| fixImports(target, target); |
| |
| return true; |
| } |
| |
| public boolean removeReference(LBeanReference ref) { |
| |
| LBean source = ref.getBean(); |
| LType target = ref.getType(); |
| |
| source.getFeatures().remove(ref); |
| ref.setType(null); |
| |
| fixImports(source, source); |
| fixImports(target, target); |
| |
| return true; |
| } |
| |
| public boolean addOppositeReference(EObject context, LEntityReference ref) { |
| |
| LEntity target = ref.getType(); |
| |
| // create opposite |
| LEntityReference opposite = OSBPEntityFactory.eINSTANCE.createLEntityReference(); |
| LEntityFeature annotationHolder = OSBPEntityFactory.eINSTANCE.createLEntityFeature(); |
| opposite.setAnnotationInfo(annotationHolder); |
| |
| LMultiplicity oppMult = OSBPTypesFactory.eINSTANCE.createLMultiplicity(); |
| oppMult.setLower(LLowerBound.ONE); |
| oppMult.setUpper(LUpperBound.ONE); |
| opposite.setMultiplicity(oppMult); |
| |
| // connect refs |
| ref.setOpposite(opposite); |
| opposite.setOpposite(ref); |
| opposite.setName("container" + target.getReferences().size() + 1); |
| |
| // connect entity and opposite |
| opposite.setType(ref.getEntity()); |
| target.getFeatures().add(opposite); |
| return true; |
| } |
| |
| public boolean fixImports(EObject var, LTypedPackage newSemanticContainer, LTypedPackage oldSemanticContainer) { |
| fixImports(oldSemanticContainer); |
| fixImports(newSemanticContainer); |
| |
| return true; |
| } |
| |
| public boolean fixImports(EObject context, LType type) { |
| if (type instanceof LEntity) { |
| fixImports(context, (LEntity) type); |
| } else if (type instanceof LBean) { |
| fixImports(context, (LBean) type); |
| } |
| |
| return true; |
| } |
| |
| public boolean fixImports(EObject context, LBean subtype) { |
| LBean supertype = subtype.getSuperType(); |
| fixImports((LTypedPackage) subtype.eContainer()); |
| if (supertype != null && supertype.eContainer() != subtype.eContainer()) { |
| fixImports((LTypedPackage) supertype.eContainer()); |
| } |
| |
| return true; |
| } |
| |
| public boolean fixImports(EObject context, LEntity subtype) { |
| LEntity supertype = subtype.getSuperType(); |
| fixImports((LTypedPackage) subtype.eContainer()); |
| if (supertype != null && supertype.eContainer() != subtype.eContainer()) { |
| fixImports((LTypedPackage) supertype.eContainer()); |
| } |
| |
| return true; |
| } |
| |
| public boolean fixImports(LTypedPackage lPkg) { |
| |
| LEntityModel model = (LEntityModel) lPkg.eContainer(); |
| XImportSection section = model.getImportSection(); |
| if (section == null) { |
| section = XtypeFactory.eINSTANCE.createXImportSection(); |
| model.setImportSection(section); |
| } |
| |
| // remove all fqn imports |
| for (Iterator<XImportDeclaration> iterator = section.getImportDeclarations().iterator(); iterator.hasNext();) { |
| XImportDeclaration decl = (XImportDeclaration) iterator.next(); |
| if (decl instanceof OXImportDeclaration) { |
| if (((OXImportDeclaration) decl).isFqnImport()) { |
| iterator.remove(); |
| } |
| } |
| } |
| |
| ImportCollectionSwitch s = new ImportCollectionSwitch(); |
| s.doSwitch(lPkg); |
| |
| appendImports(section, s.imports); |
| |
| return true; |
| } |
| |
| private void appendImports(XImportSection section, Set<String> imports) { |
| for (String imp : imports) { |
| OXImportDeclaration lImp = OXtypeFactory.eINSTANCE.createOXImportDeclaration(); |
| lImp.setFqnImport(true); |
| lImp.setImportedFullyQualifiedName(imp); |
| section.getImportDeclarations().add(lImp); |
| } |
| } |
| |
| public EObject openTextEditor(EObject any) { |
| if (any != null && any.eResource() instanceof XtextResource && any.eResource().getURI() != null) { |
| |
| String fileURI = any.eResource().getURI().toPlatformString(true); |
| IFile workspaceFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(fileURI)); |
| if (workspaceFile != null) { |
| IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); |
| try { |
| IEditorPart openEditor = IDE.openEditor(page, workspaceFile, |
| "org.eclipse.osbp.dsl.entity.xtext.EntityGrammar", true); |
| if (openEditor instanceof AbstractTextEditor) { |
| ICompositeNode node = NodeModelUtils.findActualNodeFor(any); |
| if (node != null) { |
| int offset = node.getOffset(); |
| int length = node.getTotalEndOffset() - offset; |
| ((AbstractTextEditor) openEditor).selectAndReveal(offset, length); |
| } |
| } |
| // editorInput. |
| } catch (PartInitException e) { |
| // Put your exception handler here if you wish to. |
| } |
| } |
| } |
| return any; |
| } |
| |
| private class ImportCollectionSwitch extends OSBPEntitySwitch<Boolean> { |
| |
| private Set<String> imports = new HashSet<String>(); |
| private boolean isInType; |
| |
| @Override |
| public Boolean caseLBean(LBean object) { |
| |
| addImport(object); |
| |
| if (isInType) { |
| return true; |
| } |
| |
| isInType = true; |
| |
| if (object.getSuperType() != null) { |
| doSwitch(object.getSuperType()); |
| } |
| |
| for (LBeanAttribute att : object.getAttributes()) { |
| doSwitch(att); |
| } |
| |
| for (LBeanReference ref : object.getReferences()) { |
| doSwitch(ref); |
| } |
| |
| isInType = false; |
| |
| return super.caseLBean(object); |
| } |
| |
| @Override |
| public Boolean caseLEntity(LEntity object) { |
| |
| addImport(object); |
| |
| if (isInType) { |
| return true; |
| } |
| |
| isInType = true; |
| |
| if (object.getSuperType() != null) { |
| doSwitch(object.getSuperType()); |
| } |
| |
| for (LEntityAttribute att : object.getAttributes()) { |
| doSwitch(att); |
| } |
| |
| for (LEntityReference ref : object.getReferences()) { |
| doSwitch(ref); |
| } |
| |
| isInType = false; |
| |
| return super.caseLEntity(object); |
| } |
| |
| @Override |
| public Boolean caseLEntityAttribute(LEntityAttribute object) { |
| if (object.getType() instanceof LBean) { |
| doSwitch(object.getType()); |
| } else if (object.getType() instanceof LDataType) { |
| doSwitch(object.getType()); |
| } else if (object.getType() instanceof LEnum) { |
| doSwitch(object.getType()); |
| } |
| |
| return super.caseLEntityAttribute(object); |
| } |
| |
| @Override |
| public Boolean caseLEntityReference(LEntityReference object) { |
| |
| if (object.getType() != null) { |
| doSwitch(object.getType()); |
| } |
| |
| return super.caseLEntityReference(object); |
| } |
| |
| @Override |
| public Boolean caseLBeanAttribute(LBeanAttribute object) { |
| if (object.getType() instanceof LBean) { |
| doSwitch(object.getType()); |
| } else if (object.getType() instanceof LDataType) { |
| doSwitch(object.getType()); |
| } else if (object.getType() instanceof LEnum) { |
| doSwitch(object.getType()); |
| } |
| |
| return super.caseLBeanAttribute(object); |
| } |
| |
| @Override |
| public Boolean caseLBeanReference(LBeanReference object) { |
| if (object.getType() != null) { |
| doSwitch(object.getType()); |
| } |
| return super.caseLBeanReference(object); |
| } |
| |
| @Override |
| public Boolean defaultCase(EObject object) { |
| if (object instanceof LTypedPackage) { |
| for (LType type : ((LTypedPackage) object).getTypes()) { |
| doSwitch(type); |
| } |
| } else if (object instanceof LDataType) { |
| addImport((LType) object); |
| } else if (object instanceof LEnum) { |
| addImport((LType) object); |
| } |
| return super.defaultCase(object); |
| } |
| |
| private void addImport(LType type) { |
| imports.add(calcImport(type)); |
| } |
| |
| private String calcImport(LType type) { |
| if (type == null) { |
| return ""; |
| } |
| |
| LTypedPackage pkg = (LTypedPackage) type.eContainer(); |
| return pkg.getName() + "." + type.getName(); |
| } |
| |
| } |
| |
| } |