Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • af3/kernel
  • diewald/kernel
2 results
Show changes
Showing
with 2 additions and 1619 deletions
......@@ -29,7 +29,6 @@ public final class ToolingKernelUIInternal {
printPhase("Tooling Kernel UI initializing ...");
ActionService.getInstance().initializeService();
AllocationEditPartFactoryService.getInstance().initializeService();
ConstraintUIService.getInstance().initializeService();
ContextMenuService.getInstance().initializeService();
EditPartFactoryService.getInstance().initializeService();
MarkerService.getInstance().initializeService();
......@@ -45,7 +44,6 @@ public final class ToolingKernelUIInternal {
printPhase("Tooling Kernel UI starting ...");
ActionService.getInstance().startService();
AllocationEditPartFactoryService.getInstance().startService();
ConstraintUIService.getInstance().startService();
ContextMenuService.getInstance().startService();
EditPartFactoryService.getInstance().startService();
MarkerService.getInstance().startService();
......
DetailsUIHandlerBase.java d3d2038cee67f61ca0be7e0c832ffc95771cee0f GREEN
KISSDetailsUIRegistry.java 89716fced381fa2b8e64cd8bcd81fa22495973d9 GREEN
KISSDetailsUIRegistry.java 4ae512082e0a7751f9da1d631b1bba44c2e5e8c4 GREEN
......@@ -21,7 +21,6 @@ import org.fortiss.tooling.kernel.introspection.IIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.introspection.IIntrospectionItem;
import org.fortiss.tooling.kernel.introspection.items.ConnectionCompositorServiceIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.introspection.items.ConstraintCheckerServiceIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.introspection.items.ConstraintVerificationServiceIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.introspection.items.EclipseResourceStorageServiceIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.introspection.items.ElementCompositorServiceIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.introspection.items.LibraryServiceIntrospectionDetailsItem;
......@@ -32,8 +31,6 @@ import org.fortiss.tooling.kernel.introspection.items.TransformationServiceIntro
import org.fortiss.tooling.kernel.ui.internal.introspection.details.handler.AllocationEditPartFactoryServiceIntrospectionDetailsUIHandler;
import org.fortiss.tooling.kernel.ui.internal.introspection.details.handler.ConnectionCompositorServiceIntrospectionDetailsUIHandler;
import org.fortiss.tooling.kernel.ui.internal.introspection.details.handler.ConstraintCheckerServiceIntrospectionDetailsUIHandler;
import org.fortiss.tooling.kernel.ui.internal.introspection.details.handler.ConstraintServiceIntrospectionDetailsUIHandler;
import org.fortiss.tooling.kernel.ui.internal.introspection.details.handler.ConstraintUIServiceIntrospectionDetailsUIHandler;
import org.fortiss.tooling.kernel.ui.internal.introspection.details.handler.ContextMenuServiceIntrospectionDetailsUIHandler;
import org.fortiss.tooling.kernel.ui.internal.introspection.details.handler.EclipseResourceStorageProviderIntrospectionDetailsUIHandler;
import org.fortiss.tooling.kernel.ui.internal.introspection.details.handler.EditPartFactoryServiceIntrospectionDetailsUIHandler;
......@@ -46,7 +43,6 @@ import org.fortiss.tooling.kernel.ui.internal.introspection.details.handler.Pers
import org.fortiss.tooling.kernel.ui.internal.introspection.details.handler.PrototypeServiceIntrospectionDetailsUIHandler;
import org.fortiss.tooling.kernel.ui.internal.introspection.details.handler.TransformationServiceIntrospectionDetailsUIHandler;
import org.fortiss.tooling.kernel.ui.internal.introspection.items.AllocationEditPartFactoryServiceIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.ui.internal.introspection.items.ConstraintUIServiceIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.ui.internal.introspection.items.ContextMenuServiceIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.ui.internal.introspection.items.EditPartFactoryServiceIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.ui.internal.introspection.items.ModelEditorBindingServiceIntrospectionDetailsItem;
......@@ -100,10 +96,6 @@ public final class KISSDetailsUIRegistry {
new PersistencyServiceIntrospectionDetailsUIHandler());
registerHandler(TransformationServiceIntrospectionDetailsItem.class,
new TransformationServiceIntrospectionDetailsUIHandler());
registerHandler(ConstraintVerificationServiceIntrospectionDetailsItem.class,
new ConstraintServiceIntrospectionDetailsUIHandler());
registerHandler(ConstraintUIServiceIntrospectionDetailsItem.class,
new ConstraintUIServiceIntrospectionDetailsUIHandler());
}
/** Registers the given composite */
......
AllocationEditPartFactoryServiceIntrospectionDetailsUIHandler.java 944cc4d5db305ceba7ca1f1f1957a5160511a228 GREEN
ConnectionCompositorServiceIntrospectionDetailsUIHandler.java bf4744afe94f1b97c2f8442466c10d4969b81854 GREEN
ConstraintCheckerServiceIntrospectionDetailsUIHandler.java 33758640bc77148162b88143dd1ed758a12bcf30 GREEN
ConstraintServiceIntrospectionDetailsUIHandler.java 8695a09d5a6047d1a478c1d48a49f1e3072caadd GREEN
ConstraintUIServiceIntrospectionDetailsUIHandler.java bc5fff880e84fac2fa8e1bc43b67cfb2ce907f97 GREEN
ContextMenuServiceIntrospectionDetailsUIHandler.java 33f39e000e14a9c2661ca280e82139593852be7c GREEN
CopyClassNameToClipBoardRunnable.java 884555c7026c466d3401b272fc64b9f693074950 GREEN
EObjectAware2IntrospectionDetailsUIHandlerBase.java 18aefde758dc370f564a535d71bab9afc8bdf91f GREEN
......
/*-------------------------------------------------------------------------+
| Copyright 2016 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.internal.introspection.details.handler;
import org.conqat.ide.commons.ui.jface.TreeContentProviderBase;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TableLabelProviderBase;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.fortiss.tooling.kernel.extension.IConstraint;
import org.fortiss.tooling.kernel.introspection.items.ConstraintVerificationServiceIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.service.IConstraintService;
/**
* Introspection UI handler for the {@link IConstraintService}.
*
* @author hoelzl
*/
public final class ConstraintServiceIntrospectionDetailsUIHandler
extends EObjectAwareIntrospectionDetailsUIHandlerBase {
/** {@inheritDoc} */
@Override
public Control createComposite(ScrolledComposite parent) {
String heading = "Type to search registered constraint:";
return createFilteredTreeInTabFolder(parent, heading, "", "Registered constraints");
}
/** {@inheritDoc} */
@Override
protected void createTreeColumns(Tree tree) {
TreeColumn col0 = new TreeColumn(tree, SWT.LEFT);
col0.setText("Constraint");
col0.setWidth(900);
}
/** {@inheritDoc} */
@Override
protected ITreeContentProvider createContentProvider() {
return new TreeContentProviderBase() {
/** {@inheritDoc} */
@Override
public Object[] getChildren(Object parentElement) {
if(parentElement == getInputObject()) {
return getInputObject().getHandlerKeyClasses().toArray();
}
return new Object[0];
}
};
}
/** {@inheritDoc} */
@Override
protected ITableLabelProvider createLabelProvider() {
return new TableLabelProvider();
}
/** Table label provider for handler registrations with two classes. */
protected static class TableLabelProvider extends TableLabelProviderBase {
/** {@inheritDoc} */
@Override
public String getColumnText(Object element, int columnIndex) {
return element instanceof IConstraint ? element.getClass().getName() : "";
}
}
/** {@inheritDoc} */
@Override
protected ConstraintVerificationServiceIntrospectionDetailsItem getInputObject() {
return (ConstraintVerificationServiceIntrospectionDetailsItem)dataItem;
}
}
/*-------------------------------------------------------------------------+
| Copyright 2016 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.internal.introspection.details.handler;
import java.util.Map.Entry;
import org.conqat.ide.commons.ui.jface.TreeContentProviderBase;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TableLabelProviderBase;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.fortiss.tooling.kernel.service.IConnectionCompositorService;
import org.fortiss.tooling.kernel.ui.internal.introspection.items.ConstraintUIServiceIntrospectionDetailsItem;
/**
* Introspection UI handler for the {@link IConnectionCompositorService}.
*
* @author hoelzl
*/
public final class ConstraintUIServiceIntrospectionDetailsUIHandler
extends EObjectAwareIntrospectionDetailsUIHandlerBase {
/** {@inheritDoc} */
@Override
public Control createComposite(ScrolledComposite parent) {
String heading = "Type to search registered constraint UI's:";
return createFilteredTreeInTabFolder(parent, heading, "", "Registered constraint UI's");
}
/** {@inheritDoc} */
@Override
protected void createTreeColumns(Tree tree) {
TreeColumn col0 = new TreeColumn(tree, SWT.LEFT);
col0.setText("Constraint UI");
col0.setWidth(600);
TreeColumn col1 = new TreeColumn(tree, SWT.LEFT);
col1.setText("Matching constraint");
col1.setWidth(300);
}
/** {@inheritDoc} */
@Override
protected ITreeContentProvider createContentProvider() {
return new TreeContentProviderBase() {
/** {@inheritDoc} */
@Override
public Object[] getChildren(Object parentElement) {
if(parentElement == getInputObject()) {
return getInputObject().getHandlerKeyClasses().toArray();
}
return new Object[0];
}
};
}
/** {@inheritDoc} */
@Override
protected ITableLabelProvider createLabelProvider() {
return new TableLabelProvider();
}
/** Table label provider for handler registrations with two classes. */
protected static class TableLabelProvider extends TableLabelProviderBase {
/** {@inheritDoc} */
@Override
public String getColumnText(Object element, int columnIndex) {
if(element instanceof Entry<?, ?>) {
switch(columnIndex) {
case 0:
return (String)((Entry<?, ?>)element).getKey();
case 1:
return ((Class<?>)((Entry<?, ?>)element).getValue()).getName();
}
}
return "";
}
}
/** {@inheritDoc} */
@Override
protected ConstraintUIServiceIntrospectionDetailsItem getInputObject() {
return (ConstraintUIServiceIntrospectionDetailsItem)dataItem;
}
}
AllocationEditPartFactoryServiceIntrospectionDetailsItem.java e2067b2d95c270a9aed82a2368177d76b0144d79 GREEN
ConstraintUIServiceIntrospectionDetailsItem.java c143c6113a5bc3c69c6652055e6f703a170d9794 GREEN
ContextMenuServiceIntrospectionDetailsItem.java ce7c725510e986b99fcddb40676cf6a5e7c2351d GREEN
EditPartFactoryServiceIntrospectionDetailsItem.java f11316c73b6de0e254c4e319e063065e598d5c96 GREEN
ModelEditorBindingServiceIntrospectionDetailsItem.java b241c242f5d8597542d9b63276b64ac2ca81ec7d GREEN
......
/*-------------------------------------------------------------------------+
| Copyright 2016 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.internal.introspection.items;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.fortiss.tooling.kernel.introspection.IIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.ui.extension.IConstraintUI;
import org.fortiss.tooling.kernel.ui.service.IConstraintUIService;
/**
* {@link IIntrospectionDetailsItem} for {@link IConstraintUIService}.
*
* @author hoelzl
*/
public final class ConstraintUIServiceIntrospectionDetailsItem
implements IIntrospectionDetailsItem {
/** Read-only copy of the services handler maps. */
protected final Map<String, Class<? extends IConstraintUI>> handlerMap;
/** Constructor. */
public ConstraintUIServiceIntrospectionDetailsItem(
Map<String, Class<? extends IConstraintUI>> handlerMap) {
this.handlerMap = handlerMap;
}
/** Returns the registered constraint UI's along with their non-UI counterparts. */
public Set<Entry<String, Class<? extends IConstraintUI>>> getHandlerKeyClasses() {
return handlerMap.entrySet();
}
/** Returns the handler list for the given registration class. */
public Class<? extends IConstraintUI> getHandler(String regClass) {
return handlerMap.get(regClass);
}
}
ConstraintMenu.java 55bb88600b21e832109460f14fe8f09a18056fcc GREEN
DoubleClick.java fd00e7737c0bad903433c0adb67dad92220ff451 GREEN
GenericNewMenu.java 7e0dd435cb5ca6d4b486235ec17eef3e5c7aa5f6 GREEN
LibraryView.java 44107622da7bcf431e1177e462d711646488957f GREEN
......
/*-------------------------------------------------------------------------+
| Copyright 2016 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.internal.views;
import static java.util.Collections.emptyList;
import static org.eclipse.jface.resource.ImageDescriptor.createFromImage;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.DecorationOverlayIcon;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.swt.graphics.Image;
import org.fortiss.tooling.kernel.model.constraints.ConstraintInstance;
import org.fortiss.tooling.kernel.model.constraints.ErrorConstraintInstanceStatus;
import org.fortiss.tooling.kernel.model.constraints.FailedConstraintInstanceStatus;
import org.fortiss.tooling.kernel.model.constraints.IConstrained;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceStatus;
import org.fortiss.tooling.kernel.model.constraints.OutdatedConstraintInstanceStatus;
import org.fortiss.tooling.kernel.model.constraints.SuccessConstraintInstanceStatus;
import org.fortiss.tooling.kernel.service.ICommandStackService;
import org.fortiss.tooling.kernel.ui.ESharedImages;
import org.fortiss.tooling.kernel.ui.ToolingKernelUIActivator;
import org.fortiss.tooling.kernel.ui.extension.IContextMenuContributor;
import org.fortiss.tooling.kernel.ui.extension.IModelElementHandler;
import org.fortiss.tooling.kernel.ui.extension.data.ContextMenuContextProvider;
import org.fortiss.tooling.kernel.ui.service.IConstraintUIService;
import org.fortiss.tooling.kernel.ui.service.IConstraintUIService.IFix;
import org.fortiss.tooling.kernel.ui.service.IContextMenuService;
import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService;
import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService;
/**
* Context menu for constraints.
*
* @author hoelzl
*/
public class ConstraintMenu implements IContextMenuContributor {
/** {@inheritDoc} */
@Override
public List<IContributionItem> getContributedItems(EObject selectedObject,
ContextMenuContextProvider contextProvider) {
if(!(selectedObject instanceof IConstrained)) {
return emptyList();
}
return ((IConstrained)selectedObject).getConstraintInstances().stream()
.filter(ci -> shouldGetMenuEntry(ci))
.map(ci -> constraintToAction(ci, (IConstrained)selectedObject))
.collect(Collectors.toList());
}
/**
* <code>true</code> iff <code>ci</code> should get a menu entry, i.e., if not successful and
* activated.
*/
private boolean shouldGetMenuEntry(ConstraintInstance ci) {
IConstraintInstanceStatus status = IConstraintUIService.getInstance().getStatus(ci);
return !(status == null || status instanceof SuccessConstraintInstanceStatus);
}
/**
* Returns the submenu or menu entry corresponding to the status of <code>ci</code>.
* <code>elt</code> is needed to prevent displaying an entry to go to <code>elt</code> (not
* hurtful, but useless, since the user is already seeing it).
*/
private IContributionItem constraintToAction(ConstraintInstance ci, IConstrained elt) {
IConstraintInstanceStatus status = IConstraintUIService.getInstance().getStatus(ci);
ConstraintSubMenuBase m;
if(status instanceof FailedConstraintInstanceStatus) {
m = new KnowMoreAboutFailingConstraintAction(ci, elt);
} else if(status instanceof ErrorConstraintInstanceStatus) {
m = new CheckErrorConstraintAction(ci, elt);
} else if(status instanceof OutdatedConstraintInstanceStatus) {
m = new CheckOutdatedConstraintAction(ci, elt);
} else {
// should not happen
return null;
}
if(m.getItems().length == 0) {
Action a = new Action(m.getMenuText(), m.getImageDescriptor()) {
// nothing to do
};
return new ActionContributionItem(a);
}
if(m.getItems().length == 1 && m.getTopActionContribution() != null) {
IAction uniqueAction = m.getTopActionContribution().getAction();
String txt = m.getMenuText();
String newText = txt + " -> " + uniqueAction.getText();
uniqueAction.setText(newText);
uniqueAction.setImageDescriptor(m.getImageDescriptor());
return m.getTopActionContribution();
}
return m;
}
/** {@inheritDoc} */
@Override
public String getMenuSectionID() {
return IContextMenuService.BEFORE_GLOBAL_MENU_SECTION_ID;
}
/** Action to "go to" a given constrained element. */
private static class GoToConstrained extends Action {
/** The constrained element to open. */
private IConstrained cstrd;
/** Constructor. */
public GoToConstrained(IConstrained cstrd) {
super("Go to " + IModelElementHandlerService.getInstance().getName(cstrd),
createFromImage(IModelElementHandlerService.getInstance().getIcon(cstrd)));
this.cstrd = cstrd;
}
/** {@inheritDoc} */
@Override
public void run() {
IModelElementHandler<EObject> handler =
IModelElementHandlerService.getInstance().getModelElementHandler(cstrd);
EObject eltToOpen =
handler == null ? cstrd : handler.handleOpenModelElementRequest(cstrd);
IModelEditorBindingService.getInstance().openInEditor(eltToOpen);
}
}
/** Get the icon of the prototype. */
public static String getText(ConstraintInstance ci, String suffix) {
return "\"" + IConstraintUIService.getInstance().getDescription(ci) + "\": " + suffix;
}
/** Get the icon of the prototype. */
public static ImageDescriptor getIcon(ConstraintInstance ci, ImageDescriptor overlay) {
ImageDescriptor imgd = IConstraintUIService.getInstance().getIconImageDescriptor(ci);
Image img = imgd == null ? null : imgd.createImage();
if(img == null) {
if(IConstraintUIService.getInstance().shallDisplayAsWarning(ci)) {
return ESharedImages.WARNING.getImageDescriptor();
}
return ESharedImages.ERROR.getImageDescriptor();
}
ImageDescriptor[] descriptors = new ImageDescriptor[5];
descriptors[IDecoration.BOTTOM_LEFT] = overlay;
return new DecorationOverlayIcon(img, descriptors);
}
/** Get the correct overlay for the given constraint. */
private static ImageDescriptor getOverlay(ConstraintInstance ci) {
if(IConstraintUIService.getInstance().shallDisplayAsWarning(ci)) {
return ESharedImages.WARNING_OVERLAY.getImageDescriptor();
}
return ESharedImages.ERROR_OVERLAY.getImageDescriptor();
}
/** Base for action involved in a constraint submenu. */
private static class ConstraintSubMenuBase extends MenuManager {
/** The constraint. */
protected ConstraintInstance ci;
/**
* The action to get more information about the constraint status.
* The same action allows to update an outdated constraint status (there is no
* "more information" to get out of an outdated constraint); it is stored in a field to
* allow the "update" action to change the icon and the text going with it.
*/
protected ActionContributionItem moreInfoAction;
/** Constructor. */
public ConstraintSubMenuBase(ConstraintInstance ci, IConstrained selectedElt, String suffix,
ImageDescriptor overlay) {
super(getText(ci, suffix), getIcon(ci, overlay), null);
this.ci = ci;
if(IConstraintUIService.getInstance().canOpen(ci)) {
moreInfoAction = new ActionContributionItem(new OpenStatusAction());
this.add(moreInfoAction);
}
for(IConstrained cstrd : ci.getConstraineds()) {
if(!selectedElt.equals(cstrd)) {
this.add(new ActionContributionItem(new GoToConstrained(cstrd)));
}
}
}
/**
* @return The top action contribution. Useful in case we get aware that there is only one
* contribution and we therefore want to present it without going through a submenu.
*/
public ActionContributionItem getTopActionContribution() {
if(this.getItems()[0] instanceof ActionContributionItem) {
return (ActionContributionItem)this.getItems()[0];
}
return null;
}
/** Action to update a constraint. Assumes the status *can be open*. */
protected class OpenStatusAction extends Action {
/** Constructor. */
public OpenStatusAction() {
super("More information...",
ToolingKernelUIActivator.getImageDescriptor("icons/info.gif"));
}
/** {@inheritDoc} */
@Override
public void run() {
IConstraintInstanceStatus status = IConstraintUIService.getInstance().getStatus(ci);
if(status instanceof OutdatedConstraintInstanceStatus) {
ICommandStackService.getInstance().runAsCommand(ci, new Runnable() {
@Override
public void run() {
IConstraintUIService.getInstance().openStatus(ci);
}
});
} else {
IConstraintUIService.getInstance().openStatus(ci);
}
}
}
}
/** Action for creating a new prototype. */
private static class CheckOutdatedConstraintAction extends ConstraintSubMenuBase {
/** Constructor. */
public CheckOutdatedConstraintAction(ConstraintInstance ci, IConstrained selectedElt) {
super(ci, selectedElt, "Outdated", ESharedImages.WARNING_OVERLAY.getImageDescriptor());
IAction action = moreInfoAction.getAction();
action.setImageDescriptor(ToolingKernelUIActivator.getImageDescriptor("icons/ok.png"));
action.setText("Check");
}
}
/** Action for knowing more about some unsuccessful constraint. */
private static class KnowMoreAboutUnsuccessfulConstraintAction extends ConstraintSubMenuBase {
/** Constructor. */
public KnowMoreAboutUnsuccessfulConstraintAction(ConstraintInstance ci,
IConstrained selectedElt, String suffix) {
super(ci, selectedElt, suffix, getOverlay(ci));
List<IFix> fixes = IConstraintUIService.getInstance().fixes(ci);
if(fixes != null) {
for(IFix fix : fixes) {
this.add(new ActionContributionItem(new FixAction(fix)));
}
}
}
/** Action to update a constraint. */
private class FixAction extends Action {
/** The fix to achieve. */
IFix fix;
/** Constructor. */
public FixAction(IFix fix) {
super(fix.getDescription(),
ToolingKernelUIActivator.getImageDescriptor("icons/fix.png"));
this.fix = fix;
}
/** {@inheritDoc} */
@Override
public void run() {
ICommandStackService.getInstance().runAsCommand(ci, new Runnable() {
@Override
public void run() {
fix.runFix(IConstraintUIService.getInstance().getStatus(ci));
}
});
}
}
}
/** Action for knowing more about a failing constraint. */
private static class KnowMoreAboutFailingConstraintAction
extends KnowMoreAboutUnsuccessfulConstraintAction {
/** Constructor. */
public KnowMoreAboutFailingConstraintAction(ConstraintInstance ci,
IConstrained selectedElt) {
super(ci, selectedElt, "Unsatisfied");
}
}
/** Action for knowing more about a constraint yielding an error. */
private static class CheckErrorConstraintAction
extends KnowMoreAboutUnsuccessfulConstraintAction {
/** Constructor. */
public CheckErrorConstraintAction(ConstraintInstance ci, IConstrained selectedElt) {
super(ci, selectedElt, "Error encountered");
}
}
}
IActionService.java 22eafafc8708cbff7f855f7b1b9bef042c127f25 GREEN
IAllocationEditPartFactoryService.java ac7243a8ff8a6c3f71937ecf3e63a04e271ca1d5 GREEN
IConstraintUIService.java 07df6b9553bf04f8c414c976dc630e6a1dd5ec96 GREEN
IContextMenuService.java cfb6b8237b6cd2b0e461991a9ceb95969f330265 GREEN
IEditPartFactoryService.java c448bff63fb81f57037c9f1dc5319859c12d0c4d GREEN
IMarkerService.java d433e838e387dd2fe61b8dea7395ebb7203ae39b GREEN
......
package org.fortiss.tooling.kernel.ui.service;
import java.util.List;
import java.util.Set;
import org.eclipse.jface.resource.ImageDescriptor;
import org.fortiss.tooling.kernel.extension.IConstraint;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.model.constraints.ConstraintInstance;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceContainer;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceStatus;
import org.fortiss.tooling.kernel.service.IConstraintService;
import org.fortiss.tooling.kernel.ui.extension.IConstraintUI;
import org.fortiss.tooling.kernel.ui.internal.ConstraintUIService;
/**
* GUI aspects of {@link IConstraintService}.
*
* @author aravantinos
*/
public interface IConstraintUIService {
/** Returns the service instance. */
public static IConstraintUIService getInstance() {
return ConstraintUIService.getInstance();
}
/** Action to take when trying to open the (status of the given) constraint instance. */
void openStatus(ConstraintInstance ci);
/** True if the (status of the) given constraint instance can be open. */
boolean canOpen(ConstraintInstance ci);
/**
* Install the given constraint instance: install notifiers and triggers an "onOutdate" event.
*/
void install(ConstraintInstance ci);
/**
* True if a failure of the given constraint instance shall be displayed as a warning instead of
* as an error.
*/
boolean shallDisplayAsWarning(ConstraintInstance ci);
/** Returns a description for the given constraint. */
String getDescription(Class<? extends IConstraint> c);
/** Returns a description for the given constraint instance. */
String getDescription(ConstraintInstance ci);
/** Returns the image descriptor to be used as icon image for the given constraint instance. */
ImageDescriptor getIconImageDescriptor(ConstraintInstance c);
/**
* Browse the elements in the context of the given container, adds constraints instances if
* relevant and install them.
*/
void addMissingConstraintInstances(IConstraintInstanceContainer cstrContainer);
/**
* Returns the status of the given constraint instance, possibly returns <code>null</code> if
* the constraint instance is not activated.
*/
IConstraintInstanceStatus getStatus(ConstraintInstance ci);
/**
* Returns a list of possible automatic fixes for <code>ci</code>. A constraint instance should
* be candidate to fixing if it is anything but successful or outdated.
*/
List<IFix> fixes(ConstraintInstance ci);
/** Interface for a "fix". */
public interface IFix {
/**
* Description of the fix. Useful to allow the user distinguish the fix in case there are
* several.
*/
String getDescription();
/** Fixes (the constraint instance of) <code>status</code>. */
void runFix(IConstraintInstanceStatus status);
}
/** Returns a list of all available constraints. */
Set<Class<? extends IConstraint>> getAllConstraints();
/** Returns a list of constraints which should always be activated. */
Set<Class<? extends IConstraint>> getAlwaysActivatedConstraints();
/** Returns a list of all constraints which are activated for the given top element. */
Set<Class<? extends IConstraint>> getActivatedConstraints(ITopLevelElement top);
/**
* Activates the constraint <code>cstr</code> in the context of the given constraints container.
*/
void activate(Class<? extends IConstraint> cstr, IConstraintInstanceContainer cstrContainer);
/**
* Deactivates the constraint <code>cstr</code> in the context of the given constraints
* container.
* The constraint container is necessary to retrieve the constraints whose markers need to be
* deactivated.
*/
void deactivate(Class<? extends IConstraint> cstr, IConstraintInstanceContainer cstrContainer);
/**
* Registers the constraint UI part with the kernel and associates it with its non-UI
* counterpart. The non-UI counterpart should however be registered separately.
*/
void registerConstraintUI(Class<? extends IConstraintUI> cstrUI,
Class<? extends IConstraint> cstr);
}
ActionUtils.java 4553e487264e3d1f86f4767da4a7400cce4b9a5d GREEN
ConstraintsUIUtils.java 69d5e08bbf768baf2790380e36f1020ef826a33e GREEN
CopyPasteUtils.java bbc5cf9c9dc03ebf8dc75d42c919fe6eb60b388e GREEN
DataBindingUtils.java 631c47881caa13fc567679a7e4416eb777af0713 GREEN
DragAndDropUtils.java 7aab91518aa12d76533a345bf6ed0be9ac7ff0e5 GREEN
......
/*-------------------------------------------------------------------------+
| Copyright 2015 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.util;
import static org.fortiss.tooling.kernel.extension.data.IConstraintViolation.SEVERITY_DIRECT_COMPARATOR;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.fortiss.tooling.kernel.extension.IConstraint;
import org.fortiss.tooling.kernel.extension.data.IConstraintViolation;
import org.fortiss.tooling.kernel.extension.data.IConstraintViolation.ESeverity;
import org.fortiss.tooling.kernel.model.constraints.ConstraintInstance;
import org.fortiss.tooling.kernel.model.constraints.ErrorConstraintInstanceStatus;
import org.fortiss.tooling.kernel.model.constraints.FailedConstraintInstanceStatus;
import org.fortiss.tooling.kernel.model.constraints.IConstrained;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceContainer;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceStatus;
import org.fortiss.tooling.kernel.model.constraints.OutdatedConstraintInstanceStatus;
import org.fortiss.tooling.kernel.model.constraints.SuccessConstraintInstanceStatus;
import org.fortiss.tooling.kernel.ui.service.IConstraintUIService;
import org.fortiss.tooling.kernel.ui.service.IConstraintUIService.IFix;
import org.fortiss.tooling.kernel.utils.EcoreUtils;
/**
* Utility functions for constraints.
*
* @author aravantinos
*/
public class ConstraintsUIUtils {
/** Gathers some statuses by verification status. */
public static class ClassifiedStatuses {
/** Failed constraints. */
public List<FailedConstraintInstanceStatus> failedStatuses;
/** Error statuses (constraint could not be checked). */
public List<ErrorConstraintInstanceStatus> errorStatuses;
/** Outdated statuses. */
public List<OutdatedConstraintInstanceStatus> outdatedStatuses;
/** Successful constraints. */
public List<SuccessConstraintInstanceStatus> successStatuses;
/** Constructor. */
public ClassifiedStatuses() {
failedStatuses = new ArrayList<FailedConstraintInstanceStatus>();
errorStatuses = new ArrayList<ErrorConstraintInstanceStatus>();
outdatedStatuses = new ArrayList<OutdatedConstraintInstanceStatus>();
successStatuses = new ArrayList<SuccessConstraintInstanceStatus>();
}
}
/** Returns {@link ClassifiedStatuses} corresponding to <code>constrained</code>. */
public static ClassifiedStatuses getClassifiedStatuses(IConstrained constrained) {
ClassifiedStatuses res = new ClassifiedStatuses();
for(ConstraintInstance constraint : constrained.getConstraintInstances()) {
IConstraintInstanceStatus status =
IConstraintUIService.getInstance().getStatus(constraint);
if(status instanceof FailedConstraintInstanceStatus) {
res.failedStatuses.add((FailedConstraintInstanceStatus)status);
}
if(status instanceof ErrorConstraintInstanceStatus) {
res.errorStatuses.add((ErrorConstraintInstanceStatus)status);
}
if(status instanceof OutdatedConstraintInstanceStatus) {
res.outdatedStatuses.add((OutdatedConstraintInstanceStatus)status);
}
if(status instanceof SuccessConstraintInstanceStatus) {
res.successStatuses.add((SuccessConstraintInstanceStatus)status);
}
}
return res;
}
/** Returns {@link ESeverity} corresponding to the status of the constraint <code>c</code> */
public static ESeverity getConstraintSeverity(ConstraintInstance c) {
IConstraintInstanceStatus status = IConstraintUIService.getInstance().getStatus(c);
if(IConstraintUIService.getInstance().shallDisplayAsWarning(c)) {
if(status instanceof FailedConstraintInstanceStatus ||
status instanceof OutdatedConstraintInstanceStatus) {
return ESeverity.WARNING;
}
return ESeverity.lowest();
}
if(status instanceof FailedConstraintInstanceStatus) {
return ESeverity.ERROR;
} else if(status instanceof ErrorConstraintInstanceStatus) {
return ESeverity.ERROR;
} else if(status instanceof OutdatedConstraintInstanceStatus) {
return ESeverity.WARNING;
} else {
return ESeverity.lowest();
}
}
/** Returns severity corresponding to the status of the constraints of <code>c</code>. */
public static ESeverity getSeverity(IConstrained c) {
try {
return c.getConstraintInstances().stream().map(cstr -> getConstraintSeverity(cstr))
.sorted(IConstraintViolation.SEVERITY_DIRECT_COMPARATOR).findFirst().get();
} catch(Exception e) {
return null;
}
}
/**
* Returns the maximum severity between <code>sev</code> and the severity resulting of possibly
* unsatisfied constraints on <code>modelElement</code>.
*/
public static ESeverity augmentSeverityWithConstraintSeverity(ESeverity sev,
EObject modelElement) {
if(modelElement instanceof IConstrained) {
ESeverity sev2 = ConstraintsUIUtils.getSeverity((IConstrained)modelElement);
if(sev == null || (sev2 != null && SEVERITY_DIRECT_COMPARATOR.compare(sev2, sev) < 0)) {
sev = sev2;
}
}
return sev == null ? ESeverity.lowest() : sev;
}
/**
* Sends (kernel-specific) refresh notifications to the constrained elements to trigger a
* refresh of the marker decorations.
*/
public static void triggerMarkersRefresh(ConstraintInstance ci) {
List<IConstrained> constraineds = new ArrayList<IConstrained>();
// We first collect separately the constrained objects because - unfortunately for some
// unknown reason - the following notification seems to trigger a change of the list of
// constrained objects.
constraineds.addAll(ci.getConstraineds());
constraineds.stream().forEach(constrained -> {
if(constrained != null) {
EcoreUtils.postRefreshNotification(constrained);
}
});
}
/**
* Sends (kernel-specific) refresh notifications to every element constrained by a constraint
* instance of the given list.
*/
public static void triggerMarkersRefresh(List<ConstraintInstance> cis) {
Set<IConstrained> constraineds = new HashSet<IConstrained>();
for(ConstraintInstance ci : cis) {
for(IConstrained cstrd : ci.getConstraineds()) {
if(cstrd != null) {
constraineds.add(cstrd);
}
}
}
constraineds.stream().forEach(cstrd -> EcoreUtils.postRefreshNotification(cstrd));
}
/**
* Calls <code>triggerMarkersRefresh</code> on every constraint of <code>cstrContainer</code>
* matching <code>id</code>.
*/
public static void triggerMarkerRefresh(Class<? extends IConstraint> cstrClass,
IConstraintInstanceContainer cstrContainer) {
for(ConstraintInstance c : cstrContainer.getConstraintInstances()) {
if(c.getConstraintName().equals(cstrClass.getName())) {
triggerMarkersRefresh(c);
}
}
}
/** Returns a standard text describing the status of <code>c</code>. */
public static String getText(ConstraintInstance c) {
if(c == null) {
return "";
}
String mainMsg = "ERROR";
IConstraintInstanceStatus status = IConstraintUIService.getInstance().getStatus(c);
if(status == null) {
mainMsg = "NOT APPLICABLE";
} else if(status instanceof SuccessConstraintInstanceStatus) {
mainMsg = "SUCCESS";
} else if(status instanceof FailedConstraintInstanceStatus) {
mainMsg = "FAIL";
} else if(status instanceof OutdatedConstraintInstanceStatus) {
mainMsg = "OUTDATED";
}
return mainMsg;
}
/** Returns a standard "hint" indicating possible action on the status of <code>c</code>. */
public static String getHint(ConstraintInstance c) {
if(c == null) {
return "";
}
IConstraintInstanceStatus status = IConstraintUIService.getInstance().getStatus(c);
if(status instanceof OutdatedConstraintInstanceStatus) {
return "(double-click to update)";
} else if(IConstraintUIService.getInstance().canOpen(c)) {
return "(double-click for more details)";
}
return "";
}
/** Returns a standard color corresponding to the status of <code>c</code>. */
public static Color getColor(ConstraintInstance c) {
Display display = Display.getCurrent();
if(c == null) {
return null;
}
IConstraintInstanceStatus status = IConstraintUIService.getInstance().getStatus(c);
if(status == null) {
return null;
} else if(status instanceof FailedConstraintInstanceStatus ||
status instanceof ErrorConstraintInstanceStatus) {
return display.getSystemColor(SWT.COLOR_RED);
} else if(status instanceof SuccessConstraintInstanceStatus) {
return display.getSystemColor(SWT.COLOR_GREEN);
}
return display.getSystemColor(SWT.COLOR_GRAY);
}
/** A label provider for the status of an {@link ConstraintInstance}. */
public static class StatusLabelProvider extends ColumnLabelProvider {
/** See constructor. */
private boolean withHint;
/** Function to retrieve a constraint from the embedded objects. */
private Function<Object, ConstraintInstance> getConstraint;
/**
* Constructor.
*
* @param withHint
* <code>true</code> if you want to display hints like "double-click for more
* details" in the status. If you set it to <code>true</code>, you are
* responsible for providing the corresponding behaviour (e.g., that
* double-clicking will open the status).
* @param getConstraint
* Function returning a constraint from the object to be provided.
*/
public StatusLabelProvider(boolean withHint,
Function<Object, ConstraintInstance> getConstraint) {
super();
this.getConstraint = getConstraint;
this.withHint = withHint;
}
/** {@inheritDoc} */
@Override
public String getText(Object element) {
ConstraintInstance cstr = getConstraint.apply(element);
// the following call CANNOT BE INLINED
String mainMsg = ConstraintsUIUtils.getText(cstr);
return mainMsg + (withHint ? " " + ConstraintsUIUtils.getHint(cstr) : "");
}
/** {@inheritDoc} */
@Override
public Color getBackground(Object element) {
ConstraintInstance cstr = getConstraint.apply(element);
return ConstraintsUIUtils.getColor(cstr);
}
}
/** Returns <code>true</code> iff <code>constraint</code> is active. */
public static boolean isConstraintActive(ConstraintInstance constraint) {
return IConstraintUIService.getInstance().getStatus(constraint) != null;
}
/**
* Standard warning message to display when a resource-consuming check is activated for the
* first time.
*/
public static void displayTimeConsumptionWarning(Class<? extends IConstraint> cstrClass) {
Display d = Display.getCurrent();
d = d == null ? Display.getDefault() : d;
Shell shell = d.getActiveShell();
String title = "Background operation about to start";
String msg = "AutoFOCUS will now go through your project to check that ";
msg += IConstraintUIService.getInstance().getDescription(cstrClass) + ". ";
msg += "This might slow down your system.\n\n";
msg += "Note that this is a one-time thing: once the check is activated, ";
msg += "subsequent runs should be unnoticed.";
MessageDialog.openWarning(shell, title, msg);
}
/** Base for fixes. */
public static class FixBase implements IFix {
/** The description. */
private String description;
/** The fix itself. */
private Consumer<IConstraintInstanceStatus> fix;
/** Constructor. */
public FixBase(String description, Consumer<IConstraintInstanceStatus> fix) {
this.description = description;
this.fix = fix;
}
/** {@inheritDoc} */
@Override
public String getDescription() {
return description;
}
/** {@inheritDoc} */
@Override
public void runFix(IConstraintInstanceStatus status) {
fix.accept(status);
}
}
}
/*-------------------------------------------------------------------------+
| Copyright 2015 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.fortiss.tooling.kernel.model.constraints.ConstraintInstance;
import org.fortiss.tooling.kernel.model.constraints.IConstrained;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceStatus;
import org.fortiss.tooling.kernel.service.IConstraintService;
/**
* Interface for constraints as required by {@link IConstraintService}.
*/
public interface IConstraint {
/** Verify the given constraint instance. */
IConstraintInstanceStatus verify(ConstraintInstance ci);
/**
* Hook to preprocess <code>cstrd</code> before computing its checksum. Typically useful to
* remove items which should not be considered when computing the checksum, e.g., layout
* information.
*/
void preprocessBeforeChecksum(IConstrained cstrd);
/** Cancels the last verification of <code>ci</code>. */
void cancel(ConstraintInstance ci);
/**
* Adds a constraint instance to the provided element.
*
* Subclasses shall return <code>null</code> if the provided element should not be constrained
* (whatever is the reason: the constraint is only judge here).
*/
ConstraintInstance addConstraintInstanceIfNeeded(IConstrained cstrd);
/**
* @return The name of the Group. This method will be implemented in all of the classes that
* implements this interface
*/
String getGroup();
}
/*-------------------------------------------------------------------------+
| Copyright 2016 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.base;
import static org.fortiss.tooling.kernel.utils.ConstraintsUtils.createConstraintInstance;
import static org.fortiss.tooling.kernel.utils.ConstraintsUtils.createOutdatedStatus;
import static org.fortiss.tooling.kernel.utils.ConstraintsUtils.getConstrained;
import static org.fortiss.tooling.kernel.utils.ConstraintsUtils.getConstraintInstanceOfType;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.fortiss.tooling.kernel.extension.IConstraint;
import org.fortiss.tooling.kernel.model.constraints.ConstraintInstance;
import org.fortiss.tooling.kernel.model.constraints.IConstrained;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceContainer;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceStatus;
/**
* Base for {@link IConstraint}.
*
* @author aravantinos
*/
public class ConstraintBases {
/** Most generic base. */
public abstract static class ConstraintBase implements IConstraint {
/** Returns the constraint instance container in the context of the given object. */
abstract public IConstraintInstanceContainer getConstraintInstanceContainer(EObject obj);
/** {@inheritDoc} */
@Override
public void preprocessBeforeChecksum(IConstrained cstrd) {
cstrd.getConstraintInstances().clear();
cstrd.getChecksumsPerConstraintName().clear();
// By default, we remove all the constraint-related information.
TreeIterator<EObject> it = cstrd.eAllContents();
List<EMap<String, BigInteger>> toClears = new ArrayList<>();
while(it.hasNext()) {
EObject obj = it.next();
if(obj instanceof IConstrained) {
((IConstrained)obj).getConstraintInstances().clear();
toClears.add(((IConstrained)obj).getChecksumsPerConstraintName());
}
}
toClears.stream().forEach(toClear -> toClear.clear());
}
/** {@inheritDoc} */
@Override
public void cancel(ConstraintInstance ci) {
// By default - and generally - nothing to do. Not all constraints are so heavy that
// they deserve to have a cancellation procedure.
}
/** {@inheritDoc} */
@Override
public ConstraintInstance addConstraintInstanceIfNeeded(IConstrained constrained) {
if(getConstraintInstanceOfType(constrained, this) != null) {
return null;
}
ConstraintInstance ci = createConstraintInstanceIfNeeded(constrained);
if(ci != null) {
createOutdatedStatus(ci);
}
if(ci != null) {
IConstraintInstanceContainer ciContainer =
getConstraintInstanceContainer(constrained);
ciContainer.getConstraintInstances().add(ci);
}
return ci;
}
/**
* Creates and return a constraint instance on the provided element.
*
* Subclasses shall return <code>null</code> if the provided element should not be
* constrained (whatever is the reason: the constraint is only judge here).
*/
public abstract ConstraintInstance
createConstraintInstanceIfNeeded(IConstrained constrained);
}
/**
* Base for a constraint which is as close as possible to the old constraint system:
* - the constrained element contains all the information necessary for the constraint
* (nothing stored in the constraint instance)
* - only one element is constrained
*/
public static abstract class ConstraintCheckerBase extends ConstraintBase {
/** {@inheritDoc} */
@Override
public IConstraintInstanceStatus verify(ConstraintInstance ci) {
IConstrained constrained = getConstrained(ci);
return isApplicable(constrained) ? verify(constrained) : null;
}
/** Verify the given constrained element. */
public abstract IConstraintInstanceStatus verify(IConstrained constrained);
/** Determines whether this constraint is applicable to the given model element. */
public abstract boolean isApplicable(IConstrained constrained);
/** {@inheritDoc} */
@Override
public ConstraintInstance addConstraintInstanceIfNeeded(IConstrained constrained) {
return isApplicable(constrained) ? super.addConstraintInstanceIfNeeded(constrained)
: null;
}
/** {@inheritDoc} */
@Override
public ConstraintInstance createConstraintInstanceIfNeeded(IConstrained constrained) {
return createConstraintInstance(this.getClass(), constrained);
}
}
}
CommandStackService.java 957bda69b5feb91f002aed4d25ed334e92801e7e GREEN
ConnectionCompositorService.java d69a60cd7a3d06e91d24fd32b9c00125ea71e0dd GREEN
ConstraintCheckerService.java 459b5eb717598e7e8bb71a0c87e57ea85cb00e4b GREEN
ConstraintService.java 139187909523300c80a22be920329f1c9d0fb654 GREEN
DummyTopLevelElement.java 8394597464707992cd053e68129bb87ce9f696db GREEN
ElementCompositorService.java 98c5d27e09881e60aa4f87c1ac0c7787cdec9f7c GREEN
LibraryPrototypeProvider.java b77eddbdca78f561ffb1233e98817be361c690ae GREEN
......@@ -10,6 +9,6 @@ LoggingService.java da784259f7b456b54bf75c41ec268f64919ce78d GREEN
MigrationService.java 2f800eac9793aa736089a802bbfc2c4c1c09770d GREEN
PersistencyService.java 103eef642c038ef63fa49b743d803aaa3fea2724 GREEN
PrototypeService.java 18c3db05ab11f189a9711bf241c3c7f35c954a9e GREEN
ToolingKernelInternal.java d624a5f6b237ce993e150e2b8d1b4390e3fc8f7a GREEN
ToolingKernelInternal.java f6e7114825748683c7f1d040b41ab854a6c4d79b GREEN
TransformationService.java 3cdb86fe920158f93cd9466c6ef9697b2dd8ca7f GREEN
TutorialService.java 675d3f365ce062869f86baa3779d50687674bda0 GREEN
package org.fortiss.tooling.kernel.internal;
import static java.util.Collections.emptyList;
import static org.eclipse.emf.ecore.xmi.XMLResource.OPTION_PROCESS_DANGLING_HREF;
import static org.eclipse.emf.ecore.xmi.XMLResource.OPTION_PROCESS_DANGLING_HREF_DISCARD;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.copy;
import static org.fortiss.tooling.kernel.utils.LoggingUtils.warning;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.fortiss.tooling.kernel.ToolingKernelActivator;
import org.fortiss.tooling.kernel.extension.IConstraint;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.introspection.IIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.introspection.IIntrospectionItem;
import org.fortiss.tooling.kernel.introspection.IIntrospectiveKernelService;
import org.fortiss.tooling.kernel.introspection.items.ConstraintVerificationServiceIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.model.INamedElement;
import org.fortiss.tooling.kernel.model.constraints.ConstraintInstance;
import org.fortiss.tooling.kernel.model.constraints.IConstrained;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceStatus;
import org.fortiss.tooling.kernel.service.IConstraintService;
import org.fortiss.tooling.kernel.service.IKernelIntrospectionSystemService;
import org.fortiss.tooling.kernel.service.IPersistencyService;
/**
* Implementation of {@link IConstraintService}.
*
* @author aravantinos
*/
public final class ConstraintService implements IIntrospectiveKernelService, IConstraintService {
/** The singleton instance. */
private static final ConstraintService INSTANCE = new ConstraintService();
/** Stores the set of registered constraint classes by name. */
protected final Map<String, Class<? extends IConstraint>> handlerMap =
new HashMap<String, Class<? extends IConstraint>>();
/** Stores the set of registered constraints classes instantiations. */
protected final Map<Class<? extends IConstraint>, IConstraint> instanceMap =
new HashMap<Class<? extends IConstraint>, IConstraint>();
/** Returns singleton instance of the service. */
public static ConstraintService getInstance() {
return INSTANCE;
}
/** Starts the service. */
public void startService() {
IKernelIntrospectionSystemService.getInstance().registerService(this);
}
/** Initializes the service by setting up the handler map. */
public void initializeService() {
// nothing to do here
}
/** {@inheritDoc} */
@Override
public void registerConstraint(Class<? extends IConstraint> cstrClass) {
String name = cstrClass.getName();
Class<? extends IConstraint> existingCstr = handlerMap.get(name);
if(existingCstr != null) {
warning(ToolingKernelActivator.getDefault(),
"Encountered more than one registered constraint with name " + name);
}
handlerMap.put(name, cstrClass);
try {
instanceMap.put(cstrClass, cstrClass.getConstructor().newInstance());
} catch(InstantiationException | IllegalAccessException | IllegalArgumentException |
InvocationTargetException | NoSuchMethodException | SecurityException e) {
warning(ToolingKernelActivator.getDefault(),
"Instanciation of " + cstrClass.getName() + " threw an exception.");
}
}
/** {@inheritDoc} */
@Override
public String getIntrospectionDescription() {
return getIntrospectionLabel() + "\n\nThe service deals with constraints over AF3 models." +
"\nA constraint is a function over a model element (the \"constrained\" element) which returns true or false." +
"\nThe application of a constraint to a given model element is called a \"constraint instance\"." +
"\nContrarily to usual constraint systems, constraint instances are a first-class citizen for this service" +
"\nbecause it allows us to store the status of the constraint on the given element as well as the checksum of the constrained element." +
"\n\nThe service provides the following:" +
"\n- verification of a constraint instance," +
"\n- cancellation of a constraint instance verification (if provided by the relevant verifier)," +
"\n- check whether a constraint instance is up to date," +
"\n- provide a list of possible \"quick fixes\" for a given constraint instance in case it failed," +
"\n- complete a given project with instances of a given constraint if necessary" +
"\n (it is however advised to use instead, if possible, the equivalent function of the UI service which also installs" +
"\n the added constraint instances)." +
"\n\nThis service is fed with classes of type IConstraint." +
"\nSuch classes are responsible of the verification of constraints which return a status of the following form:" +
"\n- SUCCESS means the verification succeeded" +
"\n- FAIL means the verification failed" +
"\n- ERROR means the verification could not be run (typically because an error happened)" +
"\n- OUTDATED means the constrained items have changed and the constraint instance should be verified. " +
"\n- null if it is irrelevant to check the constraint - whatever is the reason. " +
"\nDo not hesitate to extend these statuses to define your own," +
"\nfor instance to provide more information about failure (thus possibly allowing automatic fixes)." +
"\n\nThe class org.fortiss.af3.project.utils.ConstraintsProjectUtils.AF3ProjectConstraintCheckerBase should" +
"\ngenerally provide a sufficient initial implementation." +
"\n\nSee the developer wiki page \"Add a new constraint on a metamodel\"" +
" for detailed documentation on developing a new sort of constraint.";
}
/** {@inheritDoc} */
@Override
public void verify(ConstraintInstance ci) {
IConstraint verifier = getConstraint(ci);
if(verifier != null) {
ITopLevelElement modelContext =
IPersistencyService.getInstance().getTopLevelElementFor(ci);
// It can happen that <code>modelContext</code> is null, e.g., if the verification is
// triggered while the constraint is actually being removed.
if(modelContext == null) {
return;
}
modelContext.runAsCommand(() -> {
// We update the checksums before verification to avoid detecting some fake changes
// during the verification.
updateChecksums(ci);
IConstraintInstanceStatus status = verifier.verify(ci);
ci.setStatus(status);
// And we also update the checksums after in case the verification had some side
// effects...
updateChecksums(ci);
currentlyUpdating.remove(ci);
});
}
}
/** Returns the short name of the constraint of the given instance. */
private String cstrShortName(ConstraintInstance ci) {
int dolIndex = ci.getConstraintName().lastIndexOf('$');
int dotIndex = ci.getConstraintName().lastIndexOf('.');
return ci.getConstraintName().substring(Math.max(dotIndex, dolIndex) + 1);
}
/** {@inheritDoc} */
@Override
public boolean isUpToDate(ConstraintInstance ci) {
if(ci == null) {
// silently return in case of a null constraint instance
return true;
}
for(IConstrained c : ci.getConstraineds()) {
BigInteger computeCheckSum = computeCheckSum(c, ci);
EMap<String, BigInteger> checksumMap = c.getChecksumsPerConstraintName();
BigInteger storedChecksum = checksumMap.get(ci.getConstraintName());
if(computeCheckSum == null || !computeCheckSum.equals(storedChecksum)) {
return false;
}
}
return true;
}
/** Updates all the checksums of <code>ci</code>. */
private void updateChecksums(ConstraintInstance ci) {
for(IConstrained c : ci.getConstraineds()) {
c.getChecksumsPerConstraintName().put(ci.getConstraintName(), computeCheckSum(c, ci));
}
}
/**
* Path to a directory where to store the constrained elements which are actually checksummed.
* This is useful since it is essential to control very precisely how checksums are computed.
* If equal to the empty string, debug is deactivated.
* This string should however only be set to a non-empty string on a local machine, never
* committed!
*/
private static final String DEBUG_FOLDER = null;
/** Number used to annotate the traces when debugging is active. */
private int debug_trace_number = 0;
/**
* Returns the checksum of <code>constrained</code>. Note that <code>ci</code> is necessary
* because it has a potential impact on what is relevant for the checksum or not.
*/
protected BigInteger computeCheckSum(IConstrained constrained, ConstraintInstance ci) {
if(constrained == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
final EObject hashRelevant = getChecksumRelevantEObject(constrained, ci);
try(ObjectOutputStream oos = new ObjectOutputStream(baos)) {
final ResourceSet rset = new ResourceSetImpl();
Resource resource = rset.createResource(URI.createURI("temp"));
resource.getContents().add(hashRelevant);
Map<String, String> options = new HashMap<>();
// The option below is to allow computing the hashsum of an incomplete ecore sub-model,
// which is wanted in case parts of the model which are not checksum relevant are still
// referred to.
options.put(OPTION_PROCESS_DANGLING_HREF, OPTION_PROCESS_DANGLING_HREF_DISCARD);
resource.save(oos, options);
MessageDigest m = MessageDigest.getInstance("SHA1");
m.update(baos.toByteArray());
BigInteger res = new BigInteger(1, m.digest());
if(DEBUG_FOLDER != null) {
String filePrefix = DEBUG_FOLDER + "/trace" + debug_trace_number++;
String nameCstr = cstrShortName(ci);
String nameCstrd = constrained instanceof INamedElement
? ((INamedElement)constrained).getName() : constrained.toString();
String fileName = filePrefix + "_" + nameCstr + "_" + nameCstrd + ".xml";
try(FileOutputStream file = new FileOutputStream(fileName);
ObjectOutputStream oos2 = new ObjectOutputStream(file)) {
resource.save(oos2, options);
oos2.writeUTF("\nCHECKSUM: " + res.toString());
}
}
resource.getContents().remove(hashRelevant);
resource.delete(options);
return res;
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
/**
* Returns the object to be used to compute the checksum.
* Generally, all statuses and checksums are removed. Each constraint can also provide
* specific adaptations.
*/
protected EObject getChecksumRelevantEObject(IConstrained constrained, ConstraintInstance ci) {
IConstrained res = copy(constrained);
res.getChecksumsPerConstraintName().clear();
IConstraint verifier = getConstraint(ci);
if(verifier != null) {
verifier.preprocessBeforeChecksum(res);
}
return res;
}
/** @return The registered constraint whose <code>ci</code> is a constraint instance of. */
protected IConstraint getConstraint(ConstraintInstance ci) {
return instanceMap.get(handlerMap.get(ci.getConstraintName()));
}
/** {@inheritDoc} */
@Override
public void cancel(ConstraintInstance ci) {
getConstraint(ci).cancel(ci);
}
/** {@inheritDoc} */
@Override
public String getIntrospectionLabel() {
return "Constraint Service";
}
/** {@inheritDoc} */
@Override
public IIntrospectionDetailsItem getDetailsItem() {
return new ConstraintVerificationServiceIntrospectionDetailsItem(instanceMap.values());
}
/** {@inheritDoc} */
@Override
public boolean showInIntrospectionNavigation() {
return true;
}
/** {@inheritDoc} */
@Override
public Collection<IIntrospectionItem> getIntrospectionItems() {
return emptyList();
}
/** {@inheritDoc} */
@Override
public List<ConstraintInstance> addMissingConstraintsInstances(ITopLevelElement top,
Class<? extends IConstraint> cstrClass) {
List<ConstraintInstance> addedConstraints = new ArrayList<ConstraintInstance>();
IConstraint cstr = instanceMap.get(cstrClass);
TreeIterator<EObject> it = top.getRootModelElement().eAllContents();
while(it.hasNext()) {
EObject elt = it.next();
if(elt instanceof IConstrained) {
ConstraintInstance ci = cstr.addConstraintInstanceIfNeeded((IConstrained)elt);
if(ci != null) {
addedConstraints.add(ci);
}
}
}
return addedConstraints;
}
/** {@inheritDoc} */
@Override
public String getName(Class<? extends IConstraint> cstrClass) {
return cstrClass.getName();
}
/** {@inheritDoc} */
@Override
public Class<? extends IConstraint> getConstraintByName(String name) {
return handlerMap.get(name);
}
/**
* List of constraint instances being currently updated, to prevent triggering twice an update
* which is already on its way.
*/
List<ConstraintInstance> currentlyUpdating = new ArrayList<>();
/** {@inheritDoc} */
@Override
public boolean isUpdating(ConstraintInstance ci) {
return currentlyUpdating.contains(ci);
}
/** {@inheritDoc} */
@Override
public void markAsUpdating(ConstraintInstance ci) {
currentlyUpdating.add(ci);
}
/** {@inheritDoc} */
@Override
public String getGroupName(Class<? extends IConstraint> cstrClass) {
if(instanceMap.get(cstrClass).getGroup() != null) {
return instanceMap.get(cstrClass).getGroup().trim().toString();
}
return "";
}
}
......@@ -35,7 +35,6 @@ public final class ToolingKernelInternal {
CommandStackService.getInstance().initializeService();
ConnectionCompositorService.getInstance().initializeService();
ConstraintCheckerService.getInstance().initializeService();
ConstraintService.getInstance().initializeService();
ElementCompositorService.getInstance().initializeService();
MigrationService.getInstance().initializeService();
LibraryService.getInstance().initializeService();
......@@ -56,7 +55,6 @@ public final class ToolingKernelInternal {
CommandStackService.getInstance().startService();
ConnectionCompositorService.getInstance().startService();
ConstraintCheckerService.getInstance().startService();
ConstraintService.getInstance().startService();
ElementCompositorService.getInstance().startService();
MigrationService.getInstance().startService();
LibraryService.getInstance().startService();
......
/*-------------------------------------------------------------------------+
| Copyright 2016 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.introspection.items;
import java.util.Collection;
import org.fortiss.tooling.kernel.extension.IConstraint;
import org.fortiss.tooling.kernel.introspection.IIntrospectionDetailsItem;
import org.fortiss.tooling.kernel.service.IConstraintService;
/**
* {@link IIntrospectionDetailsItem} for the {@link IConstraintService}.
*
* @author aravantinos
*/
public class ConstraintVerificationServiceIntrospectionDetailsItem
implements IIntrospectionDetailsItem {
/** Read-only copy of the services handler list. */
protected final Collection<IConstraint> handlerSet;
/** Constructor. */
public ConstraintVerificationServiceIntrospectionDetailsItem(
Collection<IConstraint> handlerSet) {
this.handlerSet = handlerSet;
}
/** Returns the first registration classes. */
public Collection<IConstraint> getHandlerKeyClasses() {
return handlerSet;
}
/** Returns the registered constraint of the given name. */
public IConstraint getHandler(String name) {
return handlerSet.stream().filter(c -> name.equals(c.getClass().getName())).findFirst()
.get();
}
}