From 77b73c7a54241412e40e1a79436ccf9728ce2650 Mon Sep 17 00:00:00 2001 From: Florian Hoelzl <hoelzl@fortiss.org> Date: Wed, 20 Jul 2011 13:45:59 +0000 Subject: [PATCH] some refactoring and cleanup added transformation service --- .../ui/action/ModelElementsActionBase.java | 4 +- .../ConnectorConnectionCompositorBase.java | 2 +- .../base/ui/editor/gef/EditorBase.java | 2 +- .../GEF2ToolingKernelCommandStack.java | 2 +- .../kernel/ui/internal/ActionService.java | 2 +- .../kernel/ui/internal/MarkerService.java | 6 +- .../kernel/ui/internal/NavigatorService.java | 4 +- .../properties/PropertiesAdapterFactory.java | 2 +- .../views/NavigatorTreeContentProvider.java | 2 +- .../trunk/schema/modelElement.exsd | 17 +- .../trunk/schema/transformationProvider.exsd | 124 +++++++++ .../extension/IConnectionCompositor.java | 12 +- .../kernel/extension/IConstraintChecker.java | 4 +- .../kernel/extension/IElementCompositor.java | 4 +- .../kernel/extension/IStorageProvider.java | 6 +- .../extension/ITransformationProvider.java | 66 +++++ .../ChainTransformationFailedException.java | 71 ++++++ .../data/ITransformationContext.java | 38 +++ .../data/TransformationProviderChain.java | 63 +++++ .../kernel/internal/CommandStackService.java | 16 +- .../kernel/internal/PersistencyService.java | 10 +- .../internal/TransformationService.java | 110 ++++++++ .../tooling/kernel/internal/package.html | 2 +- .../EclipseResourceStorageProvider.java | 32 +-- .../internal/storage/eclipse/package.html | 11 +- .../tooling/kernel/listener/package.html | 7 +- .../kernel/service/IExecutionService.java | 20 +- .../kernel/service/IPersistencyService.java | 9 +- .../service/ITransformationService.java | 66 +++++ .../base/EObjectAware2ServiceBase.java | 167 +----------- .../service/base/EObjectAwareServiceBase.java | 93 +------ .../kernel/service/base/IEObjectAware.java | 2 +- .../kernel/service/base/IEObjectAware2.java | 2 +- .../kernel/service/base/IObjectAware.java | 43 ++++ .../kernel/service/base/IObjectAware2.java | 44 ++++ .../service/base/ObjectAware2ServiceBase.java | 240 ++++++++++++++++++ .../service/base/ObjectAwareServiceBase.java | 163 ++++++++++++ .../kernel/util/ProjectRootElementUtils.java | 19 +- 38 files changed, 1150 insertions(+), 337 deletions(-) create mode 100644 org.fortiss.tooling.kernel/trunk/schema/transformationProvider.exsd create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/ITransformationProvider.java create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/ChainTransformationFailedException.java create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/ITransformationContext.java create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/TransformationProviderChain.java create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/TransformationService.java create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/ITransformationService.java create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IObjectAware.java create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IObjectAware2.java create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/ObjectAware2ServiceBase.java create mode 100644 org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/ObjectAwareServiceBase.java diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/action/ModelElementsActionBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/action/ModelElementsActionBase.java index e28ecfa51..15e00d051 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/action/ModelElementsActionBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/action/ModelElementsActionBase.java @@ -71,7 +71,7 @@ public abstract class ModelElementsActionBase extends Action { ITopLevelElement context = null; for (EObject o : getSelection()) { ITopLevelElement elementContext = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(o); + .getTopLevelElementFor(o); if (context == null) { context = elementContext; } @@ -94,7 +94,7 @@ public abstract class ModelElementsActionBase extends Action { if (cmd.canExecute()) { if (modifiesModel) { ITopLevelElement context = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(selection.iterator() + .getTopLevelElementFor(selection.iterator() .next()); context.runAsCommand(new Runnable() { diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/compose/ConnectorConnectionCompositorBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/compose/ConnectorConnectionCompositorBase.java index 005400cff..51b71216b 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/compose/ConnectorConnectionCompositorBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/compose/ConnectorConnectionCompositorBase.java @@ -167,7 +167,7 @@ public abstract class ConnectorConnectionCompositorBase<HE extends IHierarchicEl // If we are working in a connected model, deal with IDs ITopLevelElement modelContext = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(source); + .getTopLevelElementFor(source); if (modelContext != null) { // FIXME (FH): IDs // modelContext.prepareIDsForCompose(channel); diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/gef/EditorBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/gef/EditorBase.java index e6f8a2fc9..8bff6fc8c 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/gef/EditorBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/gef/EditorBase.java @@ -55,7 +55,7 @@ public abstract class EditorBase<T extends EObject> extends // top-level element if (getEditedObject().eContainer() == null && IPersistencyService.INSTANCE - .getTopLevelElementContextFor(getEditedObject()) != null) { + .getTopLevelElementFor(getEditedObject()) != null) { getSite().getPage().closeEditor(EditorBase.this, false); } } diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/internal/command/GEF2ToolingKernelCommandStack.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/internal/command/GEF2ToolingKernelCommandStack.java index b86e10953..415b92c6d 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/internal/command/GEF2ToolingKernelCommandStack.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/internal/command/GEF2ToolingKernelCommandStack.java @@ -45,7 +45,7 @@ public class GEF2ToolingKernelCommandStack extends CommandStack implements /** Constructor. */ public GEF2ToolingKernelCommandStack(EObject modelElement) { context = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(modelElement); + .getTopLevelElementFor(modelElement); context.addCommandStackListener(this); } diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/ActionService.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/ActionService.java index 07b652e40..d018f73af 100644 --- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/ActionService.java +++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/ActionService.java @@ -104,7 +104,7 @@ public class ActionService implements IActionService, globalDeleteAction.setId(ActionFactory.DELETE.getId()); for (ITopLevelElement context : IPersistencyService.INSTANCE - .getTopLevelElementContexts()) { + .getTopLevelElements()) { context.addCommandStackListener(this); } IPersistencyService.INSTANCE.addTopLevelElementListener(this); diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/MarkerService.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/MarkerService.java index 80ebdbc3a..6843123e0 100644 --- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/MarkerService.java +++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/MarkerService.java @@ -117,7 +117,7 @@ public class MarkerService implements IMarkerService, /** Constructor. */ public MarkerService() { for (ITopLevelElement element : IPersistencyService.INSTANCE - .getTopLevelElementContexts()) { + .getTopLevelElements()) { invalidElements.add(element); } constraintCheckerJob.schedule(); @@ -129,7 +129,7 @@ public class MarkerService implements IMarkerService, public Collection<IConstraintViolation<EObject>> getViolations( EObject element) { ITopLevelElement top = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(element); + .getTopLevelElementFor(element); if (top == null) { return Collections.emptyList(); } @@ -140,7 +140,7 @@ public class MarkerService implements IMarkerService, @Override public ESeverity getHighestViolationSeverity(EObject element) { ITopLevelElement top = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(element); + .getTopLevelElementFor(element); if (top == null) { return ESeverity.lowest(); } diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/NavigatorService.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/NavigatorService.java index 6bec6aaf5..132e4ab4c 100644 --- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/NavigatorService.java +++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/NavigatorService.java @@ -60,7 +60,7 @@ public class NavigatorService implements INavigatorService, /** Constructor. */ public NavigatorService() { for (ITopLevelElement element : IPersistencyService.INSTANCE - .getTopLevelElementContexts()) { + .getTopLevelElements()) { element.addCommandStackListener(this); saveables.put(element, new TopLevelElementSaveable(element)); } @@ -126,7 +126,7 @@ public class NavigatorService implements INavigatorService, for (EObject selection : EObjectSelectionUtils .getCurrentSelectionEObjects()) { ITopLevelElement context = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(selection); + .getTopLevelElementFor(selection); if (saveables.get(context) != null) { result.add(saveables.get(context)); } diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/properties/PropertiesAdapterFactory.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/properties/PropertiesAdapterFactory.java index 8ed03e1a5..9f6ba77b4 100644 --- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/properties/PropertiesAdapterFactory.java +++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/properties/PropertiesAdapterFactory.java @@ -41,7 +41,7 @@ public final class PropertiesAdapterFactory implements IAdapterFactory { && adaptableObject instanceof EObject) { EObject modelElement = (EObject) adaptableObject; if (IPersistencyService.INSTANCE - .getTopLevelElementContextFor(modelElement) != null) { + .getTopLevelElementFor(modelElement) != null) { return new ITabbedPropertySheetPageContributor() { @Override diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/views/NavigatorTreeContentProvider.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/views/NavigatorTreeContentProvider.java index 16492d5a7..ca37e6c9e 100644 --- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/views/NavigatorTreeContentProvider.java +++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/views/NavigatorTreeContentProvider.java @@ -46,7 +46,7 @@ public class NavigatorTreeContentProvider implements ITreeContentProvider { List<EObject> result = new LinkedList<EObject>(); for (ITopLevelElement context : IPersistencyService.INSTANCE - .getTopLevelElementContexts()) { + .getTopLevelElements()) { result.add(context.getTopLevelElement()); } return result.toArray(); diff --git a/org.fortiss.tooling.kernel/trunk/schema/modelElement.exsd b/org.fortiss.tooling.kernel/trunk/schema/modelElement.exsd index 3947cab91..c532dd043 100644 --- a/org.fortiss.tooling.kernel/trunk/schema/modelElement.exsd +++ b/org.fortiss.tooling.kernel/trunk/schema/modelElement.exsd @@ -12,7 +12,7 @@ <element name="modelElementClass"> <complexType> - <attribute name="modelElementClass" type="string"> + <attribute name="modelElementClass" type="string" use="required"> <annotation> <documentation> The class of the model element. @@ -25,6 +25,21 @@ </complexType> </element> + <element name="objectClass"> + <complexType> + <attribute name="objectClass" type="string" use="required"> + <annotation> + <documentation> + The class of the object. + </documentation> + <appinfo> + <meta.attribute kind="java" basedOn="java.lang.Object:"/> + </appinfo> + </annotation> + </attribute> + </complexType> + </element> + <annotation> <appinfo> <meta.section type="since"/> diff --git a/org.fortiss.tooling.kernel/trunk/schema/transformationProvider.exsd b/org.fortiss.tooling.kernel/trunk/schema/transformationProvider.exsd new file mode 100644 index 000000000..211aca079 --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/schema/transformationProvider.exsd @@ -0,0 +1,124 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="org.fortiss.tooling.kernel" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appinfo> + <meta.schema plugin="org.fortiss.tooling.kernel" id="transformationProvider" name="Transformation Provider"/> + </appinfo> + <documentation> + Register a transformation provider. + </documentation> + </annotation> + + <include schemaLocation="modelElement.exsd"/> + + <element name="extension"> + <annotation> + <appinfo> + <meta.element /> + </appinfo> + </annotation> + <complexType> + <sequence> + <element ref="transformationProvider" minOccurs="1" maxOccurs="unbounded"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + + </documentation> + <appinfo> + <meta.attribute translatable="true"/> + </appinfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="transformationProvider"> + <complexType> + <sequence> + <element ref="source"/> + <element ref="target"/> + </sequence> + </complexType> + </element> + + <element name="source"> + <annotation> + <documentation> + This is used for referencing valid source model elements. + </documentation> + </annotation> + <complexType> + <sequence> + <element ref="objectClass" minOccurs="1" maxOccurs="unbounded"/> + </sequence> + </complexType> + </element> + + <element name="target"> + <annotation> + <documentation> + This is used for referencing valid target model elements. + </documentation> + </annotation> + <complexType> + <sequence> + <element ref="objectClass" minOccurs="1" maxOccurs="unbounded"/> + </sequence> + </complexType> + </element> + + <annotation> + <appinfo> + <meta.section type="since"/> + </appinfo> + <documentation> + [Enter the first release in which this extension point appears.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="examples"/> + </appinfo> + <documentation> + [Enter extension point usage example here.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="apiinfo"/> + </appinfo> + <documentation> + [Enter API information here.] + </documentation> + </annotation> + + <annotation> + <appinfo> + <meta.section type="implementation"/> + </appinfo> + <documentation> + [Enter information about supplied implementation of this extension point.] + </documentation> + </annotation> + + +</schema> diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IConnectionCompositor.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IConnectionCompositor.java index daf5d8f0b..247e00bfd 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IConnectionCompositor.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IConnectionCompositor.java @@ -20,7 +20,7 @@ package org.fortiss.tooling.kernel.extension; import org.eclipse.emf.ecore.EObject; import org.fortiss.tooling.kernel.extension.data.IConnectionCompositionContext; import org.fortiss.tooling.kernel.service.IConnectionCompositorService; -import org.fortiss.tooling.kernel.service.base.IEObjectAware2; +import org.fortiss.tooling.kernel.service.base.IObjectAware2; /** * Interface for connection compositor extensions, i.e. classes which connect @@ -47,10 +47,10 @@ import org.fortiss.tooling.kernel.service.base.IEObjectAware2; * @author hoelzl * @author $Author$ * @version $Rev$ - * @ConQAT.Rating YELLOW Hash: A461E86AAFAF15638C7557BDD5FFB68B + * @ConQAT.Rating YELLOW Hash: 1AC611B81A3BA734C7F2282DB2AD91E9 */ public interface IConnectionCompositor<P extends EObject, S extends EObject, T extends EObject> - extends IEObjectAware2<S, T> { + extends IObjectAware2<S, T> { /** * Returns whether a connection between the source and the target is * possible. Additional information can be included in the context, which @@ -64,7 +64,8 @@ public interface IConnectionCompositor<P extends EObject, S extends EObject, T e * Actually connects the given source and target. This will only be called * if * {@link #canConnect(EObject, EObject, EObject, IConnectionCompositionContext)} - * returned true. + * returned true. This method returns a boolean, since user-interaction + * during the connect might cancel the connect. * * @param source * the source of the connection. @@ -77,9 +78,6 @@ public interface IConnectionCompositor<P extends EObject, S extends EObject, T e * reused for the connection (reconnect). * @param context * context information for the connection. May be null. - * - * TODO: what is the return? true is success and false otherwise? - * or what? */ boolean connect(S source, T target, EObject connection, IConnectionCompositionContext context); diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IConstraintChecker.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IConstraintChecker.java index f1c8a7cdd..dedabb7c2 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IConstraintChecker.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IConstraintChecker.java @@ -20,7 +20,7 @@ package org.fortiss.tooling.kernel.extension; import org.eclipse.emf.ecore.EObject; import org.fortiss.tooling.kernel.extension.data.IConstraintViolation; import org.fortiss.tooling.kernel.service.IConstraintCheckerService; -import org.fortiss.tooling.kernel.service.base.IEObjectAware; +import org.fortiss.tooling.kernel.service.base.IObjectAware; /** * Interface for constraint checker implementations. @@ -38,7 +38,7 @@ import org.fortiss.tooling.kernel.service.base.IEObjectAware; * @version $Rev$ * @ConQAT.Rating GREEN Hash: 9D1C13DDE03060268433FC560D3BB754 */ -public interface IConstraintChecker<C extends EObject> extends IEObjectAware<C> { +public interface IConstraintChecker<C extends EObject> extends IObjectAware<C> { /** * Determines whether the constraint checker is applicable to the given diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IElementCompositor.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IElementCompositor.java index 1d56a4881..7d0a2d54a 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IElementCompositor.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IElementCompositor.java @@ -21,7 +21,7 @@ import org.eclipse.emf.ecore.EObject; import org.fortiss.tooling.kernel.extension.data.IElementCompositionContext; import org.fortiss.tooling.kernel.extension.data.Prototype; import org.fortiss.tooling.kernel.service.IElementCompositorService; -import org.fortiss.tooling.kernel.service.base.IEObjectAware; +import org.fortiss.tooling.kernel.service.base.IObjectAware; /** * Interface for element compositor extensions, i.e. classes which know how to @@ -41,7 +41,7 @@ import org.fortiss.tooling.kernel.service.base.IEObjectAware; * @version $Rev$ * @ConQAT.Rating GREEN Hash: 4F8B26BA3A47A0A7E09A8E3528BBA598 */ -public interface IElementCompositor<C extends EObject> extends IEObjectAware<C> { +public interface IElementCompositor<C extends EObject> extends IObjectAware<C> { /** * Returns whether the given container may include the given contained * object. diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IStorageProvider.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IStorageProvider.java index 5b7ae7a1d..a36772b8a 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IStorageProvider.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/IStorageProvider.java @@ -37,7 +37,7 @@ import org.fortiss.tooling.kernel.extension.data.ITopLevelElement; * @author hoelzl * @author $Author$ * @version $Rev$ - * @ConQAT.Rating YELLOW Hash: 7DCBFE0BF5C4F3001EB6612D707B3E28 + * @ConQAT.Rating YELLOW Hash: A67842FEEDB243FFDE4F9A2608BF3BDD */ public interface IStorageProvider { @@ -45,8 +45,6 @@ public interface IStorageProvider { * Returns the top-level elements provided by this storage provider. This * method is called by persistency service during initialization. Only * successfully loaded models must be returned to the persitency service. - * - * TODO: Why "getTopLevelElementContexts" and not "getTopLevelElements"? */ - List<ITopLevelElement> getTopLevelElementContexts(); + List<ITopLevelElement> getTopLevelElements(); } diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/ITransformationProvider.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/ITransformationProvider.java new file mode 100644 index 000000000..b5ab3e496 --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/ITransformationProvider.java @@ -0,0 +1,66 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.extension; + +import org.eclipse.emf.ecore.EObject; +import org.fortiss.tooling.kernel.extension.data.ITransformationContext; +import org.fortiss.tooling.kernel.service.ITransformationService; +import org.fortiss.tooling.kernel.service.base.IObjectAware2; + +/** + * A transformation provider extends the {@link ITransformationService} with a + * concrete transformation from a source element into a target element. Since + * transformations may also produce intermediary data, which is not intended to + * be persisted, this class uses {@link Object} instead of {@link EObject}s + * only. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: A1D4FDB5F5177E279EFE10AAE5D407A1 + */ +public interface ITransformationProvider extends IObjectAware2<Object, Object> { + + /** Returns the target class this provider can provide. */ + Class<? extends Object> getTargetClass(); + + /** + * Returns whether this provider is able to become part of a chain, + * transforming objects of the given source class into the provider's target + * class. Note that a provider may return <code>true</code> here and return + * <code>false</code> later when its + * {@link #canTransform(Object, ITransformationContext)} is called and the + * concrete source object to be transformed cannot be handled. + */ + boolean canHandleChainTransformation(Class<? extends Object> sourceClass, + ITransformationContext context); + + /** + * Returns whether the transformation provider can transform the given + * source element using the provided transformation context element. + */ + boolean canTransform(Object source, ITransformationContext context); + + /** + * Returns the transformation result. This method is only called if + * {@link #canTransform(Object, ITransformationContext)} returns + * <code>true</code>. This method may return <code>null</code> if the + * transformation was aborted by, e.g., the user. + */ + Object transform(Object source, ITransformationContext context); +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/ChainTransformationFailedException.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/ChainTransformationFailedException.java new file mode 100644 index 000000000..a5bb13ccb --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/ChainTransformationFailedException.java @@ -0,0 +1,71 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.extension.data; + +import java.util.List; + +import org.fortiss.tooling.kernel.extension.ITransformationProvider; + +/** + * An exception thrown by + * {@link TransformationProviderChain#transform(Object, ITransformationContext)} + * if the transformation failed at some point of the chain. The failed + * transformation provider and the successful intermediate results can be + * obtained from this exception. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 392552053F397DDAE8C27683ED51547D + */ +public final class ChainTransformationFailedException extends Exception { + + /** Stores a reference to the transformation provider chain. */ + private final TransformationProviderChain chain; + + /** Stores the failed provider. */ + private final ITransformationProvider failedProvider; + + /** Stores the list of intermediate results. */ + private final List<Object> successfulResults; + + /** Constructor. */ + /* package */ChainTransformationFailedException( + TransformationProviderChain chain, + ITransformationProvider failedProvider, + List<Object> successfulResults) { + this.chain = chain; + this.failedProvider = failedProvider; + this.successfulResults = successfulResults; + } + + /** Returns the original transformation chain. */ + public TransformationProviderChain getTransformationProviderChain() { + return chain; + } + + /** Returns the failed provider. */ + public ITransformationProvider getFailedProvider() { + return failedProvider; + } + + /** Returns the list of successful intermediate results. */ + public List<Object> getSuccessfulResults() { + return successfulResults; + } +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/ITransformationContext.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/ITransformationContext.java new file mode 100644 index 000000000..d8cbdfb23 --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/ITransformationContext.java @@ -0,0 +1,38 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.extension.data; + +import org.fortiss.tooling.kernel.extension.ITransformationProvider; + +/** + * This class is a marker interface to provide additional information to an + * {@link ITransformationProvider}. + * + * A typical example of such information is a set of parameters provided to the + * transformation in addition to the object to be transformed + * + * @author hoelzlf + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 99FAB30533C1B634FFA4B109F3895563 + */ +public interface ITransformationContext { + // this is just a marker interface + // semantics of the context information is the concern of higher tool + // architecture layers +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/TransformationProviderChain.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/TransformationProviderChain.java new file mode 100644 index 000000000..88a7a3215 --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/extension/data/TransformationProviderChain.java @@ -0,0 +1,63 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.extension.data; + +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.fortiss.tooling.kernel.extension.ITransformationProvider; + +/** + * A transformation provider chain consists of a list of transformation + * providers, which are able to transform objects of the given source element + * class into an instance of the given target element class. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: BAD4BF78ACE465A9367F2CF955764E46 + */ +public final class TransformationProviderChain { + + /** Stores the provider list. */ + private final List<ITransformationProvider> providerList = new LinkedList<ITransformationProvider>(); + + /** Constructor. */ + public TransformationProviderChain(List<ITransformationProvider> providers) { + Assert.isNotNull(providers); + Assert.isTrue(!providers.isEmpty()); + + this.providerList.addAll(providers); + } + + /** Performs the transformation. */ + public Object transform(Object source, ITransformationContext context) + throws ChainTransformationFailedException { + List<Object> results = new LinkedList<Object>(); + for (ITransformationProvider provider : providerList) { + if (!provider.canTransform(source, context)) { + throw new ChainTransformationFailedException(this, provider, + results); + } + source = provider.transform(source, context); + results.add(source); + } + return source; + } +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java index e9b1abef9..3de71e568 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java @@ -32,14 +32,14 @@ import org.fortiss.tooling.kernel.util.LoggingUtils; * @author hoelzl * @author $Author$ * @version $Rev$ - * @ConQAT.Rating GREEN Hash: 05A073E630BD60C0AB017812C6AFFAE4 + * @ConQAT.Rating YELLOW Hash: 4A123251EA682F821C6401DF03804F5F */ public class CommandStackService implements ICommandStackService { /** {@inheritDoc} */ @Override public void runAsCommand(EObject target, Runnable runner) { ITopLevelElement context = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(target); + .getTopLevelElementFor(target); if (context != null) { context.runAsCommand(runner); } @@ -49,7 +49,7 @@ public class CommandStackService implements ICommandStackService { @Override public boolean canUndo(EObject target) { ITopLevelElement context = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(target); + .getTopLevelElementFor(target); return context != null && context.canUndo(); } @@ -57,14 +57,14 @@ public class CommandStackService implements ICommandStackService { @Override public boolean canRedo(EObject target) { ITopLevelElement context = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(target); + .getTopLevelElementFor(target); return context != null && context.canRedo(); } /** {@inheritDoc} */ @Override public void undo(EObject target) { - IPersistencyService.INSTANCE.getTopLevelElementContextFor(target) + IPersistencyService.INSTANCE.getTopLevelElementFor(target) .undo(); } @@ -72,7 +72,7 @@ public class CommandStackService implements ICommandStackService { /** {@inheritDoc} */ @Override public void redo(EObject target) { - IPersistencyService.INSTANCE.getTopLevelElementContextFor(target) + IPersistencyService.INSTANCE.getTopLevelElementFor(target) .redo(); } @@ -80,7 +80,7 @@ public class CommandStackService implements ICommandStackService { @Override public boolean isDirty(EObject target) { ITopLevelElement context = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(target); + .getTopLevelElementFor(target); return context != null && context.isDirty(); } @@ -88,7 +88,7 @@ public class CommandStackService implements ICommandStackService { @Override public void doSave(EObject target, IProgressMonitor monitor) { ITopLevelElement context = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(target); + .getTopLevelElementFor(target); if (context != null && context.isDirty()) { try { context.doSave(monitor); diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/PersistencyService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/PersistencyService.java index 1d30f5d65..589b2a204 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/PersistencyService.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/PersistencyService.java @@ -49,7 +49,7 @@ import org.osgi.framework.Bundle; * @author hoelzl * @author $Author$ * @version $Rev$ - * @ConQAT.Rating GREEN Hash: BA1EE25D06B3C06BF8A5BC6B3BC9CFAC + * @ConQAT.Rating YELLOW Hash: 0FAB59FD372CC7E5E5D6A06279A0A1FC */ public class PersistencyService implements IPersistencyService { @@ -79,7 +79,7 @@ public class PersistencyService implements IPersistencyService { /** {@inheritDoc} */ @Override - public synchronized UnmodifiableList<ITopLevelElement> getTopLevelElementContexts() { + public synchronized UnmodifiableList<ITopLevelElement> getTopLevelElements() { return CollectionUtils.asUnmodifiable(contextCache); } @@ -131,7 +131,7 @@ public class PersistencyService implements IPersistencyService { } List<ITopLevelElement> providedElements = provider - .getTopLevelElementContexts(); + .getTopLevelElements(); List<ITopLevelElement> removedCacheElements = new LinkedList<ITopLevelElement>(); for (ITopLevelElement top : contextCache) { if (provider == storageProviderCache.get(top) @@ -202,7 +202,7 @@ public class PersistencyService implements IPersistencyService { /** {@inheritDoc} */ @Override - public synchronized ITopLevelElement getTopLevelElementContextFor( + public synchronized ITopLevelElement getTopLevelElementFor( EObject modelElement) { while (modelElement != null) { for (ITopLevelElement context : contextCache) { @@ -238,7 +238,7 @@ public class PersistencyService implements IPersistencyService { private void initializeTopLevelElementContexts() { for (IStorageProvider provider : storageProviderList) { for (ITopLevelElement context : provider - .getTopLevelElementContexts()) { + .getTopLevelElements()) { contextCache.add(context); storageProviderCache.put(context, provider); } diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/TransformationService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/TransformationService.java new file mode 100644 index 000000000..5d67477d0 --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/TransformationService.java @@ -0,0 +1,110 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.internal; + +import java.util.List; + +import org.fortiss.tooling.kernel.extension.ITransformationProvider; +import org.fortiss.tooling.kernel.extension.data.ITransformationContext; +import org.fortiss.tooling.kernel.extension.data.TransformationProviderChain; +import org.fortiss.tooling.kernel.service.ITransformationService; +import org.fortiss.tooling.kernel.service.base.ObjectAware2ServiceBase; + +/** + * This class implements the {@link ITransformationService} interface. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating YELLOW Hash: 86474D41A5A332BF610AC57C51D583E7 + */ +public class TransformationService extends + ObjectAware2ServiceBase<ITransformationProvider> implements + ITransformationService { + + /** The connector extension point ID. */ + private static final String EXTENSION_POINT_NAME = "org.fortiss.tooling.kernel.transformationProvider"; + + /** The connector configuration element name. */ + private static final String CONFIGURATION_ELEMENT_NAME = "transformationProvider"; + + /** The connector attribute name. */ + private static final String ATTRIBUTE_NAME = "transformationProvider"; + + /** + * Returns the first {@link ITransformationProvider} which can connect the + * given elements (or <code>null</code>n if no such connector exists). + */ + private ITransformationProvider findWorkingTransformationProvider( + Object source, Class<? extends Object> targetClass, + ITransformationContext context) { + List<ITransformationProvider> list = getRegisteredHandlers( + source.getClass(), targetClass); + if (list == null) { + return null; + } + for (ITransformationProvider provider : list) { + if (provider.canTransform(source, context)) { + return provider; + } + } + return null; + } + + /** {@inheritDoc} */ + @Override + protected String getExtensionPointName() { + return EXTENSION_POINT_NAME; + } + + /** {@inheritDoc} */ + @Override + protected String getConfigurationElementName() { + return CONFIGURATION_ELEMENT_NAME; + } + + /** {@inheritDoc} */ + @Override + protected String getHandlerClassAttribute() { + return ATTRIBUTE_NAME; + } + + /** {@inheritDoc} */ + @Override + public boolean canTransform(Object source, + Class<? extends Object> targetClass, ITransformationContext context) { + return findWorkingTransformationProvider(source, targetClass, context) != null; + } + + /** {@inheritDoc} */ + @Override + public Object transform(Object source, Class<? extends Object> targetClass, + ITransformationContext context) { + return findWorkingTransformationProvider(source, targetClass, context) + .transform(source, context); + } + + /** {@inheritDoc} */ + @Override + public List<TransformationProviderChain> getTransformationProviderChain( + Class<? extends Object> sourceClass, + Class<? extends Object> targetClass) { + // TODO Auto-generated method stub + return null; + } +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/package.html b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/package.html index fec8615cd..8693b3666 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/package.html +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/package.html @@ -1,7 +1,7 @@ <!-- $Id$ @version $Rev$ - @ConQAT.Rating GREEN Hash: 9FBEA96965AF718EB00560E14DB6D4FB + @ConQAT.Rating YELLOW Hash: 13F39D97447479F3151634E5DAAB3AEC --> <body> Implementations of the kernel services defined in the <code>kernel.service</code> package. diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageProvider.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageProvider.java index fa69c4d19..3cdc30bd6 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageProvider.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/EclipseResourceStorageProvider.java @@ -56,7 +56,7 @@ import org.osgi.framework.Bundle; * @author hoelzlf * @author $Author$ * @version $Rev$ - * @ConQAT.Rating RED Hash: 9D11F8884C0E9AD666F0F39804D7321A + * @ConQAT.Rating YELLOW Hash: C6275F103FF5DC989ABA86CB9E7E3CE7 */ public class EclipseResourceStorageProvider implements IEclipseResourceStorageService, IResourceChangeListener, @@ -98,7 +98,16 @@ public class EclipseResourceStorageProvider implements for (IResource res : project.members()) { if (res instanceof IFile) { IFile file = (IFile) res; - checkLocationProviderAndLoadContext(file); + if (checkLocationProvider(file)) { + try { + loadContext(file); + } catch (IOException ioex) { + LoggingUtils.error( + ToolingKernelActivator.getDefault(), + "IO Exception while loading model file: " + + file.getName(), ioex); + } + } } } } catch (CoreException e) { @@ -112,20 +121,13 @@ public class EclipseResourceStorageProvider implements * Searches all location providers and loads the model context if some * location provider validates the given file as model storage file. */ - private void checkLocationProviderAndLoadContext(IFile file) { + private boolean checkLocationProvider(IFile file) { for (IEclipseResourceStorageLocationProvider provider : storageProviderList) { if (provider.isStorageLocation(file)) { - try { - loadContext(file); - } catch (IOException ioex) { - LoggingUtils.error( - ToolingKernelActivator.getDefault(), - "IO Exception while loading model file: " - + file.getName(), ioex); - } - break; + return true; } } + return false; } /** {@inheritDoc} */ @@ -151,9 +153,7 @@ public class EclipseResourceStorageProvider implements public boolean visit(IResourceDelta delta) { if (delta.getResource() instanceof IFile && delta.getResource().getParent() instanceof IProject - // TODO is it OK to hardcode the extension "af3_20" here? - use - // better a constant - && delta.getResource().getFileExtension().equals("af3_20")) { + && checkLocationProvider((IFile) delta.getResource())) { runWorkspaceChangeJob((IFile) delta.getResource(), delta.getKind()); } return true; @@ -229,7 +229,7 @@ public class EclipseResourceStorageProvider implements /** {@inheritDoc} */ @Override - public List<ITopLevelElement> getTopLevelElementContexts() { + public List<ITopLevelElement> getTopLevelElements() { List<ITopLevelElement> result = new ArrayList<ITopLevelElement>(); result.addAll(rootElementContexts.values()); return result; diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/package.html b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/package.html index f70b0805f..3dcd8de83 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/package.html +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/storage/eclipse/package.html @@ -1,10 +1,15 @@ <!-- $Id$ @version $Rev$ - @ConQAT.Rating YELLOW Hash: 7462237DA28E92C73BA17FAA05673D38 + @ConQAT.Rating YELLOW Hash: A6BD025E9E6FF9A37EC043180BD12299 --> <body> Implementation of the <code>IStorageProvider</code> interface using Eclipse file resources as storage mechanism for models. - -TODO: in this package is more that the implementation of IStorageProvider - or? +<P> +This storage provider searches all projects in the Eclipse workspace for model files. +Only files in the project's root folder are considered. +For each such files the set of registered <code>eclipseResourceStorageLocationProvider</code> extensions is +asked whether the respective file should be considered a model file. This extension mechanism is used +to allow different tools to use different file extensions for their models, e.g., tool A uses *.toolA, while +tool B uses *.toolB files. </body> diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/listener/package.html b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/listener/package.html index 31a1627de..08d3d3c12 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/listener/package.html +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/listener/package.html @@ -1,9 +1,12 @@ <!-- $Id: package.html 901 2011-07-10 13:44:11Z hoelzl $ @version $Rev: 901 $ - @ConQAT.Rating GREEN Hash: 9FBEA96965AF718EB00560E14DB6D4FB + @ConQAT.Rating YELLOW Hash: F00D0F258657E3EE1E28098A9F06A812 --> <body> -TODO +Classes in this packages are listener interfaces for kernel services. <p> +Sometimes higher layers of the tool architecture must be able to know what is happening in the kernel layer. +Therefore, they can implement the respective listener interface and register themselves with the respective +kernel service. </body> diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/IExecutionService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/IExecutionService.java index 06c90c515..dd8a1aff1 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/IExecutionService.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/IExecutionService.java @@ -18,10 +18,24 @@ $Id$ package org.fortiss.tooling.kernel.service; import org.fortiss.tooling.kernel.internal.ExecutionService; +import org.fortiss.tooling.kernel.model.IIdLabeled; /** - * This service provides run configurations and target execution for specific - * model elements and execution targets. + * This service provides execution configurations and target execution for + * specific model elements and execution targets. Usually the execution service + * makes use of the {@link ITransformationService} to transform an input model + * element into an executable object depending on which execution target was + * provided. + * <P> + * A typical example for an execution target is a simulator for a given modeling + * language or a specific target language like Java for a code generator. + * <P> + * An execution configuration in its simplest form references an + * {@link IIdLabeled} model element. However, an execution configuration can + * also contain additional information for the execution. Here, a typical + * example would be a set of parameters provided to some transformation, which + * takes part in the creation of the executable object (e.g a test case + * generator may be parameterized to use different methods of test generation). * * @author hoelzl * @author $Author$ @@ -30,7 +44,7 @@ import org.fortiss.tooling.kernel.internal.ExecutionService; */ public interface IExecutionService { - /** Returns the singleton instance of the service. */ + /** Returns the singleton instance of the execution service. */ public static final IExecutionService INSTANCE = new ExecutionService(); // TODO (FH): define diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/IPersistencyService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/IPersistencyService.java index add987fed..22beae95c 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/IPersistencyService.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/IPersistencyService.java @@ -41,7 +41,7 @@ import org.fortiss.tooling.kernel.listener.IPersistencyServiceListener; * @author hoelzl * @author $Author$ * @version $Rev$ - * @ConQAT.Rating YELLOW Hash: 6ED8D7ECA29E6F043E6AA41D784118CA + * @ConQAT.Rating YELLOW Hash: A92BFADC445DE98F5FD8C093A00E6587 */ public interface IPersistencyService { @@ -53,10 +53,8 @@ public interface IPersistencyService { * {@link IStorageProvider}s. All storage providers are requested to load * and provide their models during the persistency initialization. Therefore * this method does not have a progress monitor. - * - * TODO why getTopLevelElementContexts and not getTopLevelElements? */ - List<ITopLevelElement> getTopLevelElementContexts(); + List<ITopLevelElement> getTopLevelElements(); /** Returns whether the given element is a top-level element. */ boolean isTopLevelElement(EObject element); @@ -68,8 +66,7 @@ public interface IPersistencyService { void removeTopLevelElementListener(IPersistencyServiceListener listener); /** Returns the top-level element for the given model element. */ - // TODO: why getTopLevelElementContextFor and not getTopLevelElementFor ? - ITopLevelElement getTopLevelElementContextFor(EObject modelElement); + ITopLevelElement getTopLevelElementFor(EObject modelElement); /** Returns whether the some storage provider has unsaved changes. */ boolean isDirty(); diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/ITransformationService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/ITransformationService.java new file mode 100644 index 000000000..358c05770 --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/ITransformationService.java @@ -0,0 +1,66 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.service; + +import java.util.List; + +import org.fortiss.tooling.kernel.extension.ITransformationProvider; +import org.fortiss.tooling.kernel.extension.data.ITransformationContext; +import org.fortiss.tooling.kernel.extension.data.TransformationProviderChain; +import org.fortiss.tooling.kernel.internal.TransformationService; + +/** + * The transformation service provides registratoin and access to transformation + * providers. A transformation provider knows how to transform a given source + * object into an instance of a given target class using the provided context + * information. + * + * @see ITransformationProvider + * + * @author hoelzlf + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating RED Hash: + */ +public interface ITransformationService { + + /** Returns the singleton instance of the service. */ + public static final ITransformationService INSTANCE = new TransformationService(); + + /** + * Determines if there is a transformation provider, which can perform the + * transformation of the given source element into the given target element. + */ + boolean canTransform(Object source, Class<? extends Object> targetClass, + ITransformationContext context); + + /** + * Returns the transformation result using a suitable transformation + * provider (or a chain of providers). + */ + Object transform(Object source, Class<? extends Object> targetClass, + ITransformationContext context); + + /** + * Returns all chains of transformation providers for the given source class + * to target class transformation. + */ + List<TransformationProviderChain> getTransformationProviderChain( + Class<? extends Object> sourceClass, + Class<? extends Object> targetClass); +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/EObjectAware2ServiceBase.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/EObjectAware2ServiceBase.java index 1f2d733eb..4f1f5bf24 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/EObjectAware2ServiceBase.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/EObjectAware2ServiceBase.java @@ -17,20 +17,8 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.service.base; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.conqat.lib.commons.reflect.ReflectionUtils; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.ecore.EObject; -import org.fortiss.tooling.kernel.ToolingKernelActivator; import org.fortiss.tooling.kernel.internal.ElementCompositorService; -import org.fortiss.tooling.kernel.util.ExtensionPointUtils; -import org.fortiss.tooling.kernel.util.LoggingUtils; -import org.osgi.framework.Bundle; /** * Service base implementation, which supports handler registration with a set @@ -69,51 +57,15 @@ import org.osgi.framework.Bundle; * @version $Rev$ * @ConQAT.Rating GREEN Hash: 68234E8D2E623CB3492E3DEBD97D61FC */ -public abstract class EObjectAware2ServiceBase<T extends IEObjectAware2<? extends EObject, ? extends EObject>> { - - /** Stores the source class to target class to handler map. */ - protected final Map<Class<?>, Map<Class<?>, List<T>>> handlersBySource = new HashMap<Class<?>, Map<Class<?>, List<T>>>(); - - /** Stores the target class to source class to handler map. */ - protected final Map<Class<?>, Map<Class<?>, List<T>>> handlersByTarget = new HashMap<Class<?>, Map<Class<?>, List<T>>>(); - - /** Constructor. */ - public EObjectAware2ServiceBase() { - setupHandlerMap(); - } - - /** Returns the extension point name. */ - protected abstract String getExtensionPointName(); - - /** Returns the configuration element name. */ - protected abstract String getConfigurationElementName(); - - /** Returns the handler class attribute name. */ - protected abstract String getHandlerClassAttribute(); - - /** - * Returns the source attribute name. Sub-classes may override, but should - * first consider to use the default value <i>source</i> in the extension - * point definition. - */ - protected String getSourceAttribute() { - return "source"; - } - - /** - * Returns the target attribute name. Sub-classes may override, but should - * first consider to use the default value <i>target</i> in the extension - * point definition. - */ - protected String getTargetAttribute() { - return "target"; - } +public abstract class EObjectAware2ServiceBase<T extends IObjectAware2<? extends EObject, ? extends EObject>> + extends ObjectAware2ServiceBase<T> { /** * Returns the configuration element name for the model element class. * Sub-classes may override, but should first consider to use the default * value <i>modelElementClass</i> in the extension point definition. */ + @Override protected String getModelElementClassConfigurationElement() { return "modelElementClass"; } @@ -123,119 +75,8 @@ public abstract class EObjectAware2ServiceBase<T extends IEObjectAware2<? extend * override, but should first consider to use the default value * <i>modelElementClass</i> in the extension point definition. */ + @Override protected String getModelElementClassAttribute() { return "modelElementClass"; } - - /** - * Returns whether the service requires a unique handler per model element - * class. By default more than one handler can be registered per model - * element class. - */ - protected boolean requiresUniqueHandler() { - return false; - } - - /** Returns the list of registered handlers for the given class. */ - public List<T> getRegisteredHandlers(Class<?> sourceModelElementClass, - Class<?> targetModelElementClass) { - Map<Class<?>, List<T>> innerMap = ReflectionUtils - .performNearestClassLookup(sourceModelElementClass, - handlersBySource); - if (innerMap == null) { - return null; - } - return ReflectionUtils.performNearestClassLookup( - targetModelElementClass, innerMap); - } - - /** Initializes the handler map from plugin extensions. */ - private void setupHandlerMap() { - for (IConfigurationElement ce : ExtensionPointUtils - .getConfigurationElements(getExtensionPointName(), - getConfigurationElementName())) { - try { - createHandler(ce); - } catch (Exception e) { - LoggingUtils.error(ToolingKernelActivator.getDefault(), - "Error reading connector extension!", e); - } - } - } - - /** Creates the handler from the given configuration element. */ - @SuppressWarnings("unchecked") - private void createHandler(IConfigurationElement ce) throws Exception { - Bundle bundle = ExtensionPointUtils.getBundle(ce); - - Class<?> handlerClass = ExtensionPointUtils.loadClass( - ce.getAttribute(getHandlerClassAttribute()), bundle); - T handler = (T) handlerClass.getConstructor().newInstance(); - - List<Class<?>> sources = new ArrayList<Class<?>>(); - List<Class<?>> targets = new ArrayList<Class<?>>(); - - for (IConfigurationElement child : ce.getChildren()) { - if (child.getName().equals(getSourceAttribute())) { - addRegisteredClasses(child, sources, bundle); - } else if (child.getName().equals(getTargetAttribute())) { - addRegisteredClasses(child, targets, bundle); - } - } - - for (Class<?> source : sources) { - for (Class<?> target : targets) { - addHandler(source, target, handler); - } - } - } - - /** Adds all registered classes to the given list. */ - private void addRegisteredClasses(IConfigurationElement element, - List<Class<? extends Object>> list, Bundle bundle) - throws ClassNotFoundException { - for (IConfigurationElement ce : element - .getChildren(getModelElementClassConfigurationElement())) { - Class<?> modelElementClass = ExtensionPointUtils.loadClass( - ce.getAttribute(getModelElementClassAttribute()), bundle); - list.add(modelElementClass); - } - } - - /** Adds the given handler to the map. */ - private void addHandler(Class<?> sourceElementClass, - Class<?> targetElementClass, T handler) { - - insertStorage(handlersBySource, sourceElementClass, targetElementClass, - handler); - insertStorage(handlersByTarget, targetElementClass, sourceElementClass, - handler); - } - - /** Performs storage into the maps. */ - private void insertStorage(Map<Class<?>, Map<Class<?>, List<T>>> map, - Class<?> key1, Class<?> key2, T handler) { - - Map<Class<?>, List<T>> innerMap = map.get(key1); - if (innerMap == null) { - innerMap = new HashMap<Class<?>, List<T>>(); - map.put(key1, innerMap); - } - - List<T> list = innerMap.get(key2); - if (list == null) { - list = new ArrayList<T>(); - innerMap.put(key2, list); - } - - if (requiresUniqueHandler() && !list.isEmpty()) { - LoggingUtils.log( - ToolingKernelActivator.getDefault(), - "Encountered more than one handler registered with " - + getExtensionPointName() + "(" - + handler.getClass() + "," + list.get(0).getClass() - + ")", IStatus.WARNING); - } - list.add(handler); - } } diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/EObjectAwareServiceBase.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/EObjectAwareServiceBase.java index 1eb4ac90c..7316e235b 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/EObjectAwareServiceBase.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/EObjectAwareServiceBase.java @@ -17,20 +17,8 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.service.base; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.conqat.lib.commons.reflect.ReflectionUtils; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.ecore.EObject; -import org.fortiss.tooling.kernel.ToolingKernelActivator; import org.fortiss.tooling.kernel.internal.ConnectionCompositorService; -import org.fortiss.tooling.kernel.util.ExtensionPointUtils; -import org.fortiss.tooling.kernel.util.LoggingUtils; -import org.osgi.framework.Bundle; /** * Service base implementation, which supports handler registration with set of @@ -66,89 +54,15 @@ import org.osgi.framework.Bundle; * @version $Rev$ * @ConQAT.Rating GREEN Hash: DCEC975EF973BA6B3385D458381F7E3D */ -public abstract class EObjectAwareServiceBase<T extends IEObjectAware<? extends EObject>> { - - /** Stores the class to handler map. */ - protected final Map<Class<?>, List<T>> handlerMap = new HashMap<Class<?>, List<T>>(); - - /** Constructor. */ - public EObjectAwareServiceBase() { - setupHandlerMap(); - } - - /** Returns the list of registered handlers for the given class. */ - public List<T> getRegisteredHandlers(Class<?> modelElementClass) { - return ReflectionUtils.performNearestClassLookup(modelElementClass, - handlerMap); - } - - /** Initializes the handler map from plugin extensions. */ - @SuppressWarnings({ "unchecked" }) - private void setupHandlerMap() { - for (IConfigurationElement ce : ExtensionPointUtils - .getConfigurationElements(getExtensionPointName(), - getConfigurationElementName())) { - Bundle bundle = ExtensionPointUtils.getBundle(ce); - try { - Class<?> handlerClass = ExtensionPointUtils.loadClass( - ce.getAttribute(getHandlerClassAttribute()), bundle); - T handler = (T) handlerClass.getConstructor().newInstance(); - - for (IConfigurationElement ce2 : ce - .getChildren(getModelElementClassConfigurationElement())) { - Class<?> modelElementClass = ExtensionPointUtils.loadClass( - ce2.getAttribute(getModelElementClassAttribute()), - bundle); - addHandler(modelElementClass, handler); - } - } catch (Exception ex) { - LoggingUtils.error(ToolingKernelActivator.getDefault(), - ex.getMessage(), ex); - } - } - } - - /** Adds the given handler to the map. */ - private void addHandler(Class<?> modelElementClass, T handler) { - List<T> list = handlerMap.get(modelElementClass); - if (list == null) { - list = new LinkedList<T>(); - handlerMap.put(modelElementClass, list); - } - if (requiresUniqueHandler() && !list.isEmpty()) { - LoggingUtils.log( - ToolingKernelActivator.getDefault(), - "Encountered more than one handler registered with " - + getExtensionPointName() + "(" - + handler.getClass() + "," + list.get(0).getClass() - + ")", IStatus.WARNING); - } - list.add(handler); - } - - /** Returns the extension point name. */ - protected abstract String getExtensionPointName(); - - /** Returns the configuration element name. */ - protected abstract String getConfigurationElementName(); - - /** Returns the handler class attribute name. */ - protected abstract String getHandlerClassAttribute(); - - /** - * Returns whether the service requires a unique handler per model element - * class. By default more than one handler can be registered per model - * element class. - */ - protected boolean requiresUniqueHandler() { - return false; - } +public abstract class EObjectAwareServiceBase<T extends IObjectAware<? extends EObject>> + extends ObjectAwareServiceBase<T> { /** * Returns the configuration element name for the model element class. * Sub-classes may override, but should first consider to use the default * value <i>modelElementClass</i> in the extension point definition. */ + @Override protected String getModelElementClassConfigurationElement() { return "modelElementClass"; } @@ -158,6 +72,7 @@ public abstract class EObjectAwareServiceBase<T extends IEObjectAware<? extends * override, but should first consider to use the default value * <i>modelElementClass</i> in the extension point definition. */ + @Override protected String getModelElementClassAttribute() { return "modelElementClass"; } diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IEObjectAware.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IEObjectAware.java index 8654c8d0e..c34310311 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IEObjectAware.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IEObjectAware.java @@ -39,6 +39,6 @@ import org.fortiss.tooling.kernel.service.IElementCompositorService; * @version $Rev$ * @ConQAT.Rating GREEN Hash: 0A3C635BA583EF368DB2E394AF2B76A3 */ -public interface IEObjectAware<T extends EObject> { +public interface IEObjectAware<T extends EObject> extends IObjectAware<T> { // nothing specific is need here } diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IEObjectAware2.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IEObjectAware2.java index 318f05f18..601111497 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IEObjectAware2.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IEObjectAware2.java @@ -40,6 +40,6 @@ import org.fortiss.tooling.kernel.service.IConnectionCompositorService; * @ConQAT.Rating GREEN Hash: 97D29062614C5E30453F4B16A04A2A10 */ public interface IEObjectAware2<S extends EObject, T extends EObject> extends - IEObjectAware<T> { + IEObjectAware<T>, IObjectAware2<S, T> { // nothing specific is need here } diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IObjectAware.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IObjectAware.java new file mode 100644 index 000000000..9adab06ed --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IObjectAware.java @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.service.base; + +import org.fortiss.tooling.kernel.extension.IElementCompositor; +import org.fortiss.tooling.kernel.internal.ElementCompositorService; +import org.fortiss.tooling.kernel.service.IElementCompositorService; + +/** + * Abstract interface used in the generic parameter of the + * {@link ObjectAwareServiceBase} base implementation. A plugable extension to + * the kernel may be parameterized by one meta-model class, e.g., a constraint + * checker extension handles a specific type of model elements. If the extending + * handler's interface extends this interface, {@link ObjectAwareServiceBase} + * can be used to ease the extension mechanism. + * + * <P> + * Refer to {@link IElementCompositor}, {@link IElementCompositorService} and + * {@link ElementCompositorService} for an example implementation. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating GREEN Hash: 0A3C635BA583EF368DB2E394AF2B76A3 + */ +public interface IObjectAware<T extends Object> { + // nothing specific is need here +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IObjectAware2.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IObjectAware2.java new file mode 100644 index 000000000..26e8099da --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/IObjectAware2.java @@ -0,0 +1,44 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.service.base; + +import org.fortiss.tooling.kernel.extension.IConnectionCompositor; +import org.fortiss.tooling.kernel.internal.ConnectionCompositorService; +import org.fortiss.tooling.kernel.service.IConnectionCompositorService; + +/** + * Abstract interface used in the generic parameter of the + * {@link ObjectAware2ServiceBase} base implementation. A plugable extension to + * the kernel may be parameterized by two meta-model class, e.g., a reference + * creation extension handles a specific source and target type of model + * elements. If the extending handler's interface extends the current interface, + * {@link ObjectAware2ServiceBase} can be used to ease the extension mechanism. + * + * <P> + * Refer to {@link IConnectionCompositor}, {@link IConnectionCompositorService} + * and {@link ConnectionCompositorService} for an example implementation. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating GREEN Hash: 97D29062614C5E30453F4B16A04A2A10 + */ +public interface IObjectAware2<S extends Object, T extends Object> extends + IObjectAware<T> { + // nothing specific is need here +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/ObjectAware2ServiceBase.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/ObjectAware2ServiceBase.java new file mode 100644 index 000000000..5605f0066 --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/ObjectAware2ServiceBase.java @@ -0,0 +1,240 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.service.base; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.conqat.lib.commons.reflect.ReflectionUtils; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.fortiss.tooling.kernel.ToolingKernelActivator; +import org.fortiss.tooling.kernel.internal.ElementCompositorService; +import org.fortiss.tooling.kernel.util.ExtensionPointUtils; +import org.fortiss.tooling.kernel.util.LoggingUtils; +import org.osgi.framework.Bundle; + +/** + * Service base implementation, which supports handler registration with a set + * of source and a set of target classes. + * + * <p> + * Sub-classes must implement: + * <UL> + * <LI>{@link #getExtensionPointName()} to provide the extension point ID, + * <LI>{@link #getConfigurationElementName()} to provide the configuration + * element ID, + * <LI>{@link #getHandlerClassAttribute()} to provide the attribute of the + * handler class. + * </UL> + * + * <p> + * Sub-classes may override: + * <UL> + * <LI>{@link #getSourceAttribute()} to provide a source attribute ID, + * <LI>{@link #getTargetAttribute()} to provide a target attribute ID, + * <LI>{@link #getModelElementClassConfigurationElement()} to provide a element + * class configuration element, + * <LI>{@link #getModelElementClassAttribute()} to provide a element class + * attribute. + * <LI> {@link #requiresUniqueHandler()} should return true if each combination + * of source and target class must not have more than one handler. The default + * is <code>false</code>. + * </UL> + * + * An example implementation of a service based on this class is given by + * {@link ElementCompositorService}. The corresponding extension point schema is + * defined in <code>schema/modelElementConnectionCompositor.exsd</code>. + * + * @author hoelzlf + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating GREEN Hash: 68234E8D2E623CB3492E3DEBD97D61FC + */ +public abstract class ObjectAware2ServiceBase<T extends IObjectAware2<? extends Object, ? extends Object>> { + + /** Stores the source class to target class to handler map. */ + protected final Map<Class<?>, Map<Class<?>, List<T>>> handlersBySource = new HashMap<Class<?>, Map<Class<?>, List<T>>>(); + + /** Stores the target class to source class to handler map. */ + protected final Map<Class<?>, Map<Class<?>, List<T>>> handlersByTarget = new HashMap<Class<?>, Map<Class<?>, List<T>>>(); + + /** Constructor. */ + public ObjectAware2ServiceBase() { + setupHandlerMap(); + } + + /** Returns the extension point name. */ + protected abstract String getExtensionPointName(); + + /** Returns the configuration element name. */ + protected abstract String getConfigurationElementName(); + + /** Returns the handler class attribute name. */ + protected abstract String getHandlerClassAttribute(); + + /** + * Returns the source attribute name. Sub-classes may override, but should + * first consider to use the default value <i>source</i> in the extension + * point definition. + */ + protected String getSourceAttribute() { + return "source"; + } + + /** + * Returns the target attribute name. Sub-classes may override, but should + * first consider to use the default value <i>target</i> in the extension + * point definition. + */ + protected String getTargetAttribute() { + return "target"; + } + + /** + * Returns the configuration element name for the model element class. + * Sub-classes may override, but should first consider to use the default + * value <i>modelElementClass</i> in the extension point definition. + */ + protected String getModelElementClassConfigurationElement() { + return "modelElementClass"; + } + + /** + * Returns the attribute name for the model element class. Sub-classes may + * override, but should first consider to use the default value + * <i>modelElementClass</i> in the extension point definition. + */ + protected String getModelElementClassAttribute() { + return "modelElementClass"; + } + + /** + * Returns whether the service requires a unique handler per model element + * class. By default more than one handler can be registered per model + * element class. + */ + protected boolean requiresUniqueHandler() { + return false; + } + + /** Returns the list of registered handlers for the given class. */ + public List<T> getRegisteredHandlers(Class<?> sourceModelElementClass, + Class<?> targetModelElementClass) { + Map<Class<?>, List<T>> innerMap = ReflectionUtils + .performNearestClassLookup(sourceModelElementClass, + handlersBySource); + if (innerMap == null) { + return null; + } + return ReflectionUtils.performNearestClassLookup( + targetModelElementClass, innerMap); + } + + /** Initializes the handler map from plugin extensions. */ + private void setupHandlerMap() { + for (IConfigurationElement ce : ExtensionPointUtils + .getConfigurationElements(getExtensionPointName(), + getConfigurationElementName())) { + try { + createHandler(ce); + } catch (Exception e) { + LoggingUtils.error(ToolingKernelActivator.getDefault(), + "Error reading connector extension!", e); + } + } + } + + /** Creates the handler from the given configuration element. */ + @SuppressWarnings("unchecked") + private void createHandler(IConfigurationElement ce) throws Exception { + Bundle bundle = ExtensionPointUtils.getBundle(ce); + + Class<?> handlerClass = ExtensionPointUtils.loadClass( + ce.getAttribute(getHandlerClassAttribute()), bundle); + T handler = (T) handlerClass.getConstructor().newInstance(); + + List<Class<?>> sources = new ArrayList<Class<?>>(); + List<Class<?>> targets = new ArrayList<Class<?>>(); + + for (IConfigurationElement child : ce.getChildren()) { + if (child.getName().equals(getSourceAttribute())) { + addRegisteredClasses(child, sources, bundle); + } else if (child.getName().equals(getTargetAttribute())) { + addRegisteredClasses(child, targets, bundle); + } + } + + for (Class<?> source : sources) { + for (Class<?> target : targets) { + addHandler(source, target, handler); + } + } + } + + /** Adds all registered classes to the given list. */ + private void addRegisteredClasses(IConfigurationElement element, + List<Class<? extends Object>> list, Bundle bundle) + throws ClassNotFoundException { + for (IConfigurationElement ce : element + .getChildren(getModelElementClassConfigurationElement())) { + Class<?> modelElementClass = ExtensionPointUtils.loadClass( + ce.getAttribute(getModelElementClassAttribute()), bundle); + list.add(modelElementClass); + } + } + + /** Adds the given handler to the map. */ + private void addHandler(Class<?> sourceElementClass, + Class<?> targetElementClass, T handler) { + + insertStorage(handlersBySource, sourceElementClass, targetElementClass, + handler); + insertStorage(handlersByTarget, targetElementClass, sourceElementClass, + handler); + } + + /** Performs storage into the maps. */ + private void insertStorage(Map<Class<?>, Map<Class<?>, List<T>>> map, + Class<?> key1, Class<?> key2, T handler) { + + Map<Class<?>, List<T>> innerMap = map.get(key1); + if (innerMap == null) { + innerMap = new HashMap<Class<?>, List<T>>(); + map.put(key1, innerMap); + } + + List<T> list = innerMap.get(key2); + if (list == null) { + list = new ArrayList<T>(); + innerMap.put(key2, list); + } + + if (requiresUniqueHandler() && !list.isEmpty()) { + LoggingUtils.log( + ToolingKernelActivator.getDefault(), + "Encountered more than one handler registered with " + + getExtensionPointName() + "(" + + handler.getClass() + "," + list.get(0).getClass() + + ")", IStatus.WARNING); + } + list.add(handler); + } +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/ObjectAwareServiceBase.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/ObjectAwareServiceBase.java new file mode 100644 index 000000000..8fd01fe3e --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/service/base/ObjectAwareServiceBase.java @@ -0,0 +1,163 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.service.base; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.conqat.lib.commons.reflect.ReflectionUtils; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IStatus; +import org.fortiss.tooling.kernel.ToolingKernelActivator; +import org.fortiss.tooling.kernel.internal.ConnectionCompositorService; +import org.fortiss.tooling.kernel.util.ExtensionPointUtils; +import org.fortiss.tooling.kernel.util.LoggingUtils; +import org.osgi.framework.Bundle; + +/** + * Service base implementation, which supports handler registration with set of + * {@link Object} classes. + * + * <p> + * Sub-classes must implement: + * <UL> + * <LI>{@link #getExtensionPointName()} to provide the extension point ID, + * <LI>{@link #getConfigurationElementName()} to provide the configuration + * element ID, + * <LI>{@link #getHandlerClassAttribute()} to provide the attribute of the + * handler class. + * </UL> + * + * <p> + * Sub-classes may override: + * <UL> + * <LI>{@link #getModelElementClassConfigurationElement()} to provide a element + * class configuration element, + * <LI>{@link #getModelElementClassAttribute()} to provide a element class + * attribute. + * <LI> {@link #requiresUniqueHandler()} should return true if each EObject class + * must not have more than one handler. The default is <code>false</code>. + * </UL> + * + * An example implementation of a service based on this class is given by + * {@link ConnectionCompositorService}. The corresponding extension point schema + * is defined in <code>schema/modelElementConnectionCompositor.exsd</code>. + * + * @author hoelzlf + * @author $Author$ + * @version $Rev$ + * @ConQAT.Rating GREEN Hash: DCEC975EF973BA6B3385D458381F7E3D + */ +public abstract class ObjectAwareServiceBase<T extends IObjectAware<? extends Object>> { + + /** Stores the class to handler map. */ + protected final Map<Class<?>, List<T>> handlerMap = new HashMap<Class<?>, List<T>>(); + + /** Constructor. */ + public ObjectAwareServiceBase() { + setupHandlerMap(); + } + + /** Returns the list of registered handlers for the given class. */ + public List<T> getRegisteredHandlers(Class<?> modelElementClass) { + return ReflectionUtils.performNearestClassLookup(modelElementClass, + handlerMap); + } + + /** Initializes the handler map from plugin extensions. */ + @SuppressWarnings({ "unchecked" }) + private void setupHandlerMap() { + for (IConfigurationElement ce : ExtensionPointUtils + .getConfigurationElements(getExtensionPointName(), + getConfigurationElementName())) { + Bundle bundle = ExtensionPointUtils.getBundle(ce); + try { + Class<?> handlerClass = ExtensionPointUtils.loadClass( + ce.getAttribute(getHandlerClassAttribute()), bundle); + T handler = (T) handlerClass.getConstructor().newInstance(); + + for (IConfigurationElement ce2 : ce + .getChildren(getModelElementClassConfigurationElement())) { + Class<?> modelElementClass = ExtensionPointUtils.loadClass( + ce2.getAttribute(getModelElementClassAttribute()), + bundle); + addHandler(modelElementClass, handler); + } + } catch (Exception ex) { + LoggingUtils.error(ToolingKernelActivator.getDefault(), + ex.getMessage(), ex); + } + } + } + + /** Adds the given handler to the map. */ + private void addHandler(Class<?> modelElementClass, T handler) { + List<T> list = handlerMap.get(modelElementClass); + if (list == null) { + list = new LinkedList<T>(); + handlerMap.put(modelElementClass, list); + } + if (requiresUniqueHandler() && !list.isEmpty()) { + LoggingUtils.log( + ToolingKernelActivator.getDefault(), + "Encountered more than one handler registered with " + + getExtensionPointName() + "(" + + handler.getClass() + "," + list.get(0).getClass() + + ")", IStatus.WARNING); + } + list.add(handler); + } + + /** Returns the extension point name. */ + protected abstract String getExtensionPointName(); + + /** Returns the configuration element name. */ + protected abstract String getConfigurationElementName(); + + /** Returns the handler class attribute name. */ + protected abstract String getHandlerClassAttribute(); + + /** + * Returns whether the service requires a unique handler per model element + * class. By default more than one handler can be registered per model + * element class. + */ + protected boolean requiresUniqueHandler() { + return false; + } + + /** + * Returns the configuration element name for the model element class. + * Sub-classes may override, but should first consider to use the default + * value <i>modelElementClass</i> in the extension point definition. + */ + protected String getModelElementClassConfigurationElement() { + return "modelElementClass"; + } + + /** + * Returns the attribute name for the model element class. Sub-classes may + * override, but should first consider to use the default value + * <i>modelElementClass</i> in the extension point definition. + */ + protected String getModelElementClassAttribute() { + return "modelElementClass"; + } +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/ProjectRootElementUtils.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/ProjectRootElementUtils.java index f66ea0096..fcdb39433 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/ProjectRootElementUtils.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/ProjectRootElementUtils.java @@ -31,7 +31,7 @@ import org.fortiss.tooling.kernel.service.IPersistencyService; * @author hoelzl * @author $Author$ * @version $Rev$ - * @ConQAT.Rating YELLOW Hash: 4F0D1BA91E831DBE36E16AC7553F730B + * @ConQAT.Rating YELLOW Hash: 94996ADDA194596C514B274DF8FAB803 */ public final class ProjectRootElementUtils { @@ -41,22 +41,21 @@ public final class ProjectRootElementUtils { */ public static <T extends IProjectRootElement> T getRootElement( EObject element, Class<T> clazz) { - return ReflectionUtils.pickInstanceOf( - clazz, - IPersistencyService.INSTANCE - .getTopLevelElementContextFor(element) + return ReflectionUtils.pickInstanceOf(clazz, + IPersistencyService.INSTANCE.getTopLevelElementFor(element) .getTopLevelElement().eContents()); } /** * Returns the model element with the given qualified name or - * <code>null</code> if no such element exists. + * <code>null</code> if no such element exists. The search is started from + * the given elements top-level parent. */ - // TODO (FH): write some tests for this - public static EObject findElementByName(String qualifiedName, EObject root) { + public static EObject findElementByName(String qualifiedName, + EObject element) { StringTokenizer tizer = new StringTokenizer(qualifiedName, "/"); - EObject current = IPersistencyService.INSTANCE - .getTopLevelElementContextFor(root).getTopLevelElement(); + EObject current = IPersistencyService.INSTANCE.getTopLevelElementFor( + element).getTopLevelElement(); boolean found = true; while (found && tizer.hasMoreElements()) { String name = tizer.nextToken(); -- GitLab