Skip to content
Snippets Groups Projects
Commit aaa45875 authored by Simon Barner's avatar Simon Barner
Browse files

Merge branch 'master' of https://git.fortiss.org/af3/kernel.git into 3865

parents 754fe33f 8c9c966c
No related branches found
No related tags found
1 merge request!843865: tolerant model loader
Showing
with 273 additions and 15 deletions
/*-------------------------------------------------------------------------+
| Copyright 2019 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.ui.extension.base.factory;
import static java.util.stream.Collectors.toList;
import static org.apache.commons.lang3.reflect.ConstructorUtils.getMatchingAccessibleConstructor;
import static org.conqat.lib.commons.collections.CollectionUtils.isNullOrEmpty;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getInterfaceType;
import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelFactory;
import org.fortiss.tooling.kernel.ui.ToolingKernelUIActivator;
/**
* Delegates the creational and getter calls to concrete {@link IModelFactory}s. The first non-null
* element returned by the factories of the initially given list is returned. If no element is
* created (all delegates returned null), this factory also returns null.
* <p>
* Only the root model must be identical for all delegate factories. Hence, the root element of the
* first delegate is returned.
*
* @author hoelzl
*/
public class DelegatingModelFactory extends DelegatingFactoryBase<IModelFactory>
implements IModelFactory {
/** Constructor. */
public DelegatingModelFactory(List<Class<? extends IModelFactory>> factories,
Object editedObject) {
super(factories, editedObject);
}
/** {@inheritDoc} */
@Override
protected Optional<? extends IModelFactory>
constructFactory(Class<? extends IModelFactory> delegateFactory) {
Constructor<? extends IModelFactory> ctor = null;
try {
Class<?> ctorParamType = (editedObject instanceof EObject)
? getInterfaceType((EObject)editedObject) : editedObject.getClass();
ctor = getMatchingAccessibleConstructor(delegateFactory, ctorParamType);
try {
return Optional.of(ctor.newInstance(editedObject));
} catch(InstantiationException | IllegalAccessException | IllegalArgumentException |
InvocationTargetException e) {
error(ToolingKernelUIActivator.getDefault(), "Failed to instantiate the factory " +
delegateFactory.getSimpleName() + ".");
return Optional.empty();
}
} catch(NullPointerException | SecurityException e1) {
error(ToolingKernelUIActivator.getDefault(), "The factory " +
delegateFactory.getSimpleName() +
" is missing a single argument Constructor accepting the edited model." +
" Only such constructors are allowed for " +
IModelFactory.class.getSimpleName() + "s.");
return Optional.empty();
}
}
/** {@inheritDoc} */
@Override
public List<?> getContentAnchorageModels(Object parent) {
return getDelegateFactories().stream().map(f -> f.getContentAnchorageModels(parent))
.filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct()
.collect(toList());
}
/** {@inheritDoc} */
@Override
public Object getLinkStart(Object link) {
return getDelegateFactories().stream().map(f -> f.getLinkStart(link))
.filter(cc -> cc != null).findFirst().orElse(null);
}
/** {@inheritDoc} */
@Override
public Object getLinkEnd(Object link) {
return getDelegateFactories().stream().map(f -> f.getLinkEnd(link)).filter(cc -> cc != null)
.findFirst().orElse(null);
}
/** {@inheritDoc} */
@Override
public Object getParent(Object element) {
return getDelegateFactories().stream().map(f -> f.getParent(element))
.filter(cc -> cc != null).findFirst().orElse(null);
}
/** {@inheritDoc} */
@Override
public Object getRootModel() {
return editedObject;
}
/** {@inheritDoc} */
@Override
public List<?> getContentModels() {
return getDelegateFactories().stream().map(f -> f.getContentModels())
.filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct()
.collect(toList());
}
/** {@inheritDoc} */
@Override
public List<?> getDiagramAnchorageModels() {
return getDelegateFactories().stream().map(f -> f.getDiagramAnchorageModels())
.filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct()
.collect(toList());
}
/** {@inheritDoc} */
@Override
public List<?> getLinkModels() {
return getDelegateFactories().stream().map(f -> f.getLinkModels())
.filter(lm -> !isNullOrEmpty(lm)).flatMap(Collection::stream).distinct()
.collect(toList());
}
/** {@inheritDoc} */
@Override
public void update() {
// Not yet needed.
}
}
/*-------------------------------------------------------------------------+
| Copyright 2019 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.ui.extension.base.factory;
import java.util.List;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentAnchorageMVCBundle;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IDiagramAnchorageMVCBundle;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.ILinkMVCBundle;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IContentAnchorageVisual;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IContentVisual;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IDiagramAnchorageVisual;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.ILinkVisual;
import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.visual.IVisualFactory;
import org.eclipse.ui.IEditorPart;
import org.fortiss.tooling.kernel.service.ITransformationService;
import org.fortiss.tooling.kernel.ui.extension.base.LWFXEFEditorBase;
/**
* Base class for {@link IVisualFactory}s of extendable {@link LWFXEFEditorBase}
* {@link IEditorPart}s.The first non-null element returned by the factories of the initially given
* list is returned. If no element is
* created (all delegates returned null), this factory also returns null.
* <P>
* This class uses the {@link ITransformationService} to find a delegate visual factory for the
* model elements in question.
*
* @author hoelzl
*/
public class DelegatingVisualFactory extends DelegatingFactoryBase<IVisualFactory>
implements IVisualFactory {
/** Constructor. */
public DelegatingVisualFactory(List<Class<? extends IVisualFactory>> factories) {
super(factories, null);
}
/** {@inheritDoc} */
@Override
public IContentVisual createContentVisual(IContentMVCBundle modelBundle) {
return getDelegateFactories().stream().map(f -> f.createContentVisual(modelBundle))
.filter(cc -> cc != null).findFirst().orElse(null);
}
/** {@inheritDoc} */
@Override
public IDiagramAnchorageVisual
createDiagramAnchorageVisual(IDiagramAnchorageMVCBundle modelBundle) {
return getDelegateFactories().stream().map(f -> f.createDiagramAnchorageVisual(modelBundle))
.filter(cc -> cc != null).findFirst().orElse(null);
}
/** {@inheritDoc} */
@Override
public IContentAnchorageVisual
createContentAnchorageVisual(IContentAnchorageMVCBundle modelBundle) {
return getDelegateFactories().stream().map(f -> f.createContentAnchorageVisual(modelBundle))
.filter(cc -> cc != null).findFirst().orElse(null);
}
/** {@inheritDoc} */
@Override
public ILinkVisual createLinkVisual(ILinkMVCBundle modelBundle) {
return getDelegateFactories().stream().map(f -> f.createLinkVisual(modelBundle))
.filter(cc -> cc != null).findFirst().orElse(null);
}
}
......@@ -5,7 +5,7 @@ ConstraintUIService.java 433e35bb1c9bbc628c6ee070ff45632400becf4a GREEN
ContextMenuService.java ca3c899293f25b70ce8e5f0d86ca2f9683329d81 GREEN
EditPartFactoryService.java e9180c0020f1769d9e24ef3c08f9ca5599dbc5c3 GREEN
MarkerService.java b01b7706034691683df7bbc2e7828c42574b3147 GREEN
ModelEditorBindingService.java 948fcdc298a74e366351ad8835a145af6cd238be GREEN
ModelEditorBindingService.java 577f5db41abf240291434dbad6bc6b0fde1eeb2b GREEN
ModelElementHandlerService.java 07a30545ad687ff0fe13bf7a9348c41fb03e0b2c GREEN
NavigatorService.java 2b1361eac805996e22e5409dafff9707fbac3376 GREEN
ToolingKernelUIInternal.java 38903445a9084b7908716a00f41621dfb3126fca GREEN
......
......@@ -16,10 +16,13 @@
package org.fortiss.tooling.kernel.ui.internal;
import static java.util.Collections.emptyList;
import static java.util.Collections.sort;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.getParentElement;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.isChildElementOf;
import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.EventObject;
import java.util.HashMap;
import java.util.List;
......@@ -96,6 +99,16 @@ public class ModelEditorBindingService extends EObjectAwareServiceBase<IModelEdi
@Override
public void startService() {
IKernelIntrospectionSystemService.getInstance().registerService(this);
for(List<IModelEditorBinding<EObject>> bindings : handlerMap.values()) {
sort(bindings, new Comparator<IModelEditorBinding<EObject>>() {
@Override
public int compare(IModelEditorBinding<EObject> o1,
IModelEditorBinding<EObject> o2) {
return o2.getPriority() - o1.getPriority();
}
});
}
}
/** Registers the given editor binding with the service. */
......@@ -169,12 +182,18 @@ public class ModelEditorBindingService extends EObjectAwareServiceBase<IModelEdi
/** {@inheritDoc} */
@Override
public List<IModelEditorBinding<EObject>> getBindings(EObject element) {
List<IModelEditorBinding<EObject>> bindings = getRegisteredHandlers(element.getClass());
public List<IModelEditorBinding<EObject>> getBindings(Class<? extends EObject> elementType) {
List<IModelEditorBinding<EObject>> bindings = getRegisteredHandlers(elementType);
if(bindings == null) {
bindings = emptyList();
}
return bindings;
return new ArrayList<>(bindings);
}
/** {@inheritDoc} */
@Override
public List<IModelEditorBinding<EObject>> getBindings(EObject element) {
return getBindings(element.getClass());
}
/** {@inheritDoc} */
......
ActionBarContributor.java 18d9db3744c5381cca8b6823b5f7bc18183a1cfa GREEN
ExtendableMultiPageEditor.java f8eb6fdc347098fb03e776f23fab61109aa55d6e GREEN
ExtendableMultiPageEditor.java b18b5eed364eaa1c83cbcb64a89288d1ad263f7d GREEN
IActionContributingEditor.java 4aa7496d67822de919a8cf0af0ddaafc61bf2919 GREEN
ModelElementEditorInput.java e269eff5d992d375a646e54d048f1f0efc6144dd GREEN
TutorialStepUIEditor.java 9eadc96c302b5131ff4cc3715777718fa06ec7e8 GREEN
......
......@@ -15,11 +15,10 @@
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.kernel.ui.internal.editor;
import static java.util.Collections.sort;
import static org.conqat.ide.commons.ui.logging.LoggingUtils.error;
import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.Comparator;
import java.util.EventObject;
import java.util.List;
......@@ -185,18 +184,13 @@ public class ExtendableMultiPageEditor extends MultiPageEditorPart
int pageIndex = 0;
List<IModelEditorBinding<EObject>> bindings =
IModelEditorBindingService.getInstance().getBindings(editedObject);
sort(bindings, new Comparator<IModelEditorBinding<EObject>>() {
@Override
public int compare(IModelEditorBinding<EObject> o1, IModelEditorBinding<EObject> o2) {
return o2.getPriority() - o1.getPriority();
}
});
for(IModelEditorBinding<EObject> editorBinding : bindings) {
try {
Class<? extends IEditorPart> editorClass =
editorBinding.getEditorClass(editedObject);
if(editorClass != null) {
IEditorPart editorPart = editorClass.newInstance();
Class<? extends EObject> inputType = editedObject.getClass();
IEditorPart editorPart = constructEditorPart(editorClass, inputType);
addPage(editorPart, getEditorInput());
setPageText(pageIndex++, editorBinding.getLabel(editedObject));
}
......@@ -206,6 +200,23 @@ public class ExtendableMultiPageEditor extends MultiPageEditorPart
}
}
/**
* Constructs an {@link IEditorPart} instance of the given {@code editorClass}.
* {@link IEditorPart}s that take the input model element type as a parameter are preferred over
* no-arg constructors.
*/
protected IEditorPart constructEditorPart(Class<? extends IEditorPart> editorClass,
Class<? extends EObject> inputType) throws Exception {
try {
Constructor<? extends IEditorPart> ctor = editorClass.getConstructor(Class.class);
return ctor.newInstance(inputType);
} catch(NoSuchMethodException | SecurityException e) {
// Fallback for no-arg constructors.
Constructor<? extends IEditorPart> ctor = editorClass.getConstructor();
return ctor.newInstance();
}
}
/** {@inheritDoc} */
@Override
public void doSave(IProgressMonitor monitor) {
......
......@@ -4,7 +4,7 @@ IConstraintUIService.java 07df6b9553bf04f8c414c976dc630e6a1dd5ec96 GREEN
IContextMenuService.java cfb6b8237b6cd2b0e461991a9ceb95969f330265 GREEN
IEditPartFactoryService.java c448bff63fb81f57037c9f1dc5319859c12d0c4d GREEN
IMarkerService.java d433e838e387dd2fe61b8dea7395ebb7203ae39b GREEN
IModelEditorBindingService.java e000fb7faf558d1201c5c26e449e0019b4ec24b0 GREEN
IModelEditorBindingService.java ce2ae1957e2232bb0fac1d1d262103f9adfc5266 GREEN
IModelElementHandlerService.java c04c2876ccb8b3f8597c8e443f9c7c3db0945430 GREEN
INavigatorService.java 8d2ffeb6f075d3abea904b84d8a40090d97837fd GREEN
ITutorialUIService.java 72707c60c3d23d8ffc5c579cb9b022bb614eb094 GREEN
......@@ -54,6 +54,9 @@ public interface IModelEditorBindingService {
/** Returns the currently active editor. */
IModelEditor<EObject> getActiveEditor();
/** Returns registered editor bindings for the given class. */
List<IModelEditorBinding<EObject>> getBindings(Class<? extends EObject> elementType);
/** Returns registered editor bindings for the given {@link EObject}. */
List<IModelEditorBinding<EObject>> getBindings(EObject element);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment