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

- Instead of iteration over the entire model for each IIdLabeled element whose...

- Instead of iteration over the entire model for each IIdLabeled element whose ID is to be checked for consistency and uniqueness, register the constraint checker for the FileProject and do each of the checks in one pass.
- Should fixes drastic performance problems introduced with last change to resolve this issue
refs 2309
parent 2a6d4bb2
No related branches found
No related tags found
No related merge requests found
......@@ -30,15 +30,6 @@
provider="org.fortiss.tooling.kernel.internal.LibraryPrototypeProvider">
</modelPrototypeProvider>
</extension>
<extension point="org.fortiss.tooling.kernel.modelElementConstraintChecker">
<modelElementConstraintChecker checker="org.fortiss.tooling.kernel.constraint.IdUniquenessChecker">
<modelElementClass modelElementClass="org.fortiss.tooling.kernel.model.IIdLabeled"/>
</modelElementConstraintChecker>
<modelElementConstraintChecker checker="org.fortiss.tooling.kernel.constraint.IdConsistencyChecker">
<modelElementClass modelElementClass="org.fortiss.tooling.kernel.model.IIdLabeled"/>
</modelElementConstraintChecker>
</extension>
<!-- Resource factories. Keep registration in sync with AF3 model file extension. -->
<extension point = "org.eclipse.emf.ecore.extension_parser">
......
/*--------------------------------------------------------------------------+
$Id$
| |
| 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.constraint;
import org.eclipse.emf.ecore.EObject;
import org.fortiss.tooling.kernel.model.IIdLabeled;
import org.fortiss.tooling.kernel.model.INamedElement;
/**
* Class for implementation of constraint violation message.
*
* @author barner
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: FA47E0B446DFB0E62523A73A2DB8A1E6
*/
public class ConstraintMessage {
/** Formats the name of {@code element} for the {@link IdUniquenessConstraintViolation} message. */
private static String formatElementName(EObject element) {
return formatElementName(element, true);
}
/** Helper method to implement {@link #formatElementName(EObject)}. */
private static String formatElementName(EObject element, boolean offspring) {
if(element instanceof INamedElement) {
String elementName = ((INamedElement)element).getName();
if(elementName != null && !elementName.isEmpty()) {
return "\"" + elementName + "\"";
}
}
if(element != null && element.eContainer() != null) {
String elementName = formatElementName(element.eContainer(), false);
return offspring ? "<unnamed offspring of> " + elementName : elementName;
}
return "<unnamed>";
}
/** Creates the violation for an {@link IIdLabeled} element that contains a duplicated ID. */
public static IdUniquenessConstraintViolation<IIdLabeled> createDuplicateIdViolation(
IIdLabeled element, IIdLabeled duplicate) {
return new IdUniquenessConstraintViolation<IIdLabeled>(element, "The ID " +
element.getId() + " of model element " + formatElementName(element) +
" has already been assigned to model element " + formatElementName(duplicate) + ".");
}
/**
* Creates the violation for an {@link IIdLabeled} whose ID attribute is inconsistent with the
* elements persisted id (e.g., {@code xmi:id}).
*/
public static IdConsistencyConstraintViolation<IIdLabeled> createConsistencyIdViolation(
IIdLabeled element, String persistedId) {
return new IdConsistencyConstraintViolation<IIdLabeled>(element, "The ID " +
element.getId() + " of model element " + formatElementName(element) +
" does not match the element's persisted ID " + persistedId + ".");
}
}
/*--------------------------------------------------------------------------+
$Id$
| |
| 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.constraint;
import static org.fortiss.tooling.kernel.constraint.ConstraintMessage.createConsistencyIdViolation;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getChildrenWithType;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.fortiss.tooling.kernel.extension.IConstraintChecker;
import org.fortiss.tooling.kernel.extension.base.ConstraintCheckerBase;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.model.IIdLabeled;
import org.fortiss.tooling.kernel.service.IPersistencyService;
/**
* {@link IConstraintChecker} to check whether the IDs provided by {@link IIdLabeled} is identical
* to the XMI ID stored in the corresponding {@link XMLResource}.
*
* While this consistency of the IDs should be ensured by of the kernel (see {@code ModelContext}),
* this constraint checker is an additional safety layer.
*
* @author barner
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: B88B5832B0BFA99359A3DA7F20BBBCBE
*/
public class IdConsistencyChecker extends ConstraintCheckerBase<IIdLabeled> {
/** {@inheritDoc} */
@Override
public List<IdConsistencyConstraintViolation<IIdLabeled>> apply(IIdLabeled element) {
ArrayList<IdConsistencyConstraintViolation<IIdLabeled>> result =
new ArrayList<IdConsistencyConstraintViolation<IIdLabeled>>();
// Get project root element
EObject root = element;
while(root.eContainer() != null) {
root = root.eContainer();
}
ITopLevelElement topLevelElement = IPersistencyService.INSTANCE.getTopLevelElementFor(root);
if(topLevelElement != null) {
for(IIdLabeled current : getChildrenWithType(root, IIdLabeled.class)) {
String persistedId = topLevelElement.getId(current);
if(!(new Integer(current.getId()).toString()).equals(persistedId)) {
result.add(createConsistencyIdViolation(current, persistedId));
}
}
}
return result;
}
}
/*--------------------------------------------------------------------------+
$Id$
| |
| 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.constraint;
import static org.fortiss.tooling.kernel.extension.data.IConstraintViolation.ESeverity.FATAL;
import org.fortiss.tooling.kernel.extension.base.ConstraintViolationBase;
import org.fortiss.tooling.kernel.extension.data.IConstraintViolation;
import org.fortiss.tooling.kernel.model.IIdLabeled;
/**
* {@link IConstraintViolation} for {@link IIdLabeled} elements.
*
* @author barner
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: 399E20804354E3EA3EC65237BE6DE821
*/
public class IdConsistencyConstraintViolation<T extends IIdLabeled> extends
ConstraintViolationBase<T> {
/** Constructor. */
public IdConsistencyConstraintViolation(T modelElement, String explanation) {
super(modelElement, FATAL, explanation);
}
}
/*--------------------------------------------------------------------------+
$Id$
| |
| 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.constraint;
import static org.fortiss.tooling.kernel.constraint.ConstraintMessage.createDuplicateIdViolation;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getChildrenWithType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.fortiss.tooling.kernel.extension.IConstraintChecker;
import org.fortiss.tooling.kernel.extension.base.ConstraintCheckerBase;
import org.fortiss.tooling.kernel.model.IIdLabeled;
/**
* {@link IConstraintChecker} to check whether all {@link IIdLabeled} elements actually have unique
* IDs.
*
* While the uniqueness of IDs should be ensured by the assignment strategy of the kernel, and
* {@code ModelContext} eliminates duplicated IDs when loading and saving models, this constraint
* checker is an additional safety layer.
*
* This is because in persisted model resources, the encoding of {@link EReference} is based on IDs.
* Hence, model resources with duplicated IDs in referenced model elements are invalid and cannot be
* loaded.
*
* @author barner
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: A57025B59A7DB40046D9DD46EDDD5315
*/
public class IdUniquenessChecker extends ConstraintCheckerBase<IIdLabeled> {
/** Map to track ID -> element relationship (within a single project). */
private class IdToElementMap extends HashMap<Integer, IIdLabeled> {
// Nothing to do
}
/** Map: project root element -> {@link IdToElementMap}. */
private Map<EObject, IdToElementMap> idToElementMaps = new HashMap<EObject, IdToElementMap>();
/** {@inheritDoc} */
@Override
public List<IdUniquenessConstraintViolation<IIdLabeled>> apply(IIdLabeled element) {
ArrayList<IdUniquenessConstraintViolation<IIdLabeled>> result =
new ArrayList<IdUniquenessConstraintViolation<IIdLabeled>>();
// Get project root element
EObject root = element;
while(root.eContainer() != null) {
root = root.eContainer();
}
IdToElementMap idToElementMap = idToElementMaps.get(root);
// If required, populate map to track ID -> Element relationship
if(idToElementMap == null) {
idToElementMap = new IdToElementMap();
idToElementMaps.put(root, idToElementMap);
for(IIdLabeled current : getChildrenWithType(root, IIdLabeled.class)) {
// In case there are duplicates, the first occurrence is considered to be legitimate
// and is hence kept in the map
if(!idToElementMap.containsKey(current.getId())) {
idToElementMap.put(current.getId(), current);
}
}
}
if(idToElementMap.containsKey(element.getId())) {
IIdLabeled knownElement = idToElementMap.get(element.getId());
if(knownElement != element) {
result.add(createDuplicateIdViolation(element, knownElement));
}
} else {
idToElementMap.put(element.getId(), element);
}
return result;
}
}
/*--------------------------------------------------------------------------+
$Id$
| |
| 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.constraint;
import static org.fortiss.tooling.kernel.extension.data.IConstraintViolation.ESeverity.FATAL;
import org.fortiss.tooling.kernel.extension.base.ConstraintViolationBase;
import org.fortiss.tooling.kernel.extension.data.IConstraintViolation;
import org.fortiss.tooling.kernel.model.IIdLabeled;
/**
* {@link IConstraintViolation} for {@link IIdLabeled} elements.
*
* @author barner
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: 94BDDCCA8D8AC743AE40F428DF0DEF3C
*/
public class IdUniquenessConstraintViolation<T extends IIdLabeled> extends
ConstraintViolationBase<T> {
/** Constructor. */
public IdUniquenessConstraintViolation(T modelElement, String explanation) {
super(modelElement, FATAL, explanation);
}
}
<!--
$Id$
@version $Rev$
@ConQAT.Rating YELLOW Hash: 1469932365423F2E8747E876625E2D73
-->
<body>
Package for constraint checkers of the kernel.
</body>
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