From abd250ec49ff4a3e439eb5f1fb513e9b5170901e Mon Sep 17 00:00:00 2001
From: Florian Hoelzl <hoelzl@fortiss.org>
Date: Mon, 4 Jul 2011 12:52:48 +0000
Subject: [PATCH] fixed constraint extension point added recursive and
 non-recursive check methods to constraint service

---
 .../schema/modelElementConstraintChecker.exsd | 20 +++++++-
 .../kernel/interfaces/IConstraintChecker.java |  4 +-
 .../kernel/internal/ConstraintService.java    | 46 +++++++++++++++----
 .../kernel/services/IConstraintService.java   | 12 ++++-
 4 files changed, 67 insertions(+), 15 deletions(-)

diff --git a/org.fortiss.tooling.kernel/trunk/schema/modelElementConstraintChecker.exsd b/org.fortiss.tooling.kernel/trunk/schema/modelElementConstraintChecker.exsd
index 85dc11ee2..c9fb800f9 100644
--- a/org.fortiss.tooling.kernel/trunk/schema/modelElementConstraintChecker.exsd
+++ b/org.fortiss.tooling.kernel/trunk/schema/modelElementConstraintChecker.exsd
@@ -10,6 +10,8 @@
       </documentation>
    </annotation>
 
+   <include schemaLocation="modelElement.exsd"/>
+
    <element name="extension">
       <annotation>
          <appinfo>
@@ -18,6 +20,7 @@
       </annotation>
       <complexType>
          <sequence>
+            <element ref="modelElementConstraintChecker" minOccurs="1" maxOccurs="unbounded"/>
          </sequence>
          <attribute name="point" type="string" use="required">
             <annotation>
@@ -46,7 +49,22 @@
       </complexType>
    </element>
 
-   <element name="modelElementConstraintChecker" type="string">
+   <element name="modelElementConstraintChecker">
+      <complexType>
+         <sequence>
+            <element ref="modelElementClass" minOccurs="1" maxOccurs="unbounded"/>
+         </sequence>
+         <attribute name="checker" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+               <appinfo>
+                  <meta.attribute kind="java" basedOn=":org.fortiss.tooling.kernel.interfaces.IConstraintChecker"/>
+               </appinfo>
+            </annotation>
+         </attribute>
+      </complexType>
    </element>
 
    <annotation>
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/interfaces/IConstraintChecker.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/interfaces/IConstraintChecker.java
index b4e190d58..f3ad06024 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/interfaces/IConstraintChecker.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/interfaces/IConstraintChecker.java
@@ -38,8 +38,8 @@ public interface IConstraintChecker<C extends EObject> extends IEObjectAware<C>
 	 * Determines whether the constraint checker is applicable to the given
 	 * model element.
 	 */
-	boolean isApplicable(EObject modelElement);
+	boolean isApplicable(C modelElement);
 
 	/** Applies the constraint checker to the given model element. */
-	IConstraintViolation<EObject> apply(EObject modelElement);
+	IConstraintViolation<EObject> apply(C modelElement);
 }
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ConstraintService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ConstraintService.java
index 1936883cb..0ff0b0020 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ConstraintService.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/ConstraintService.java
@@ -17,6 +17,7 @@ $Id$
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.kernel.internal;
 
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -35,8 +36,8 @@ import org.fortiss.tooling.kernel.services.IConstraintService;
  * @ConQAT.Rating RED Hash: 9E0D8411A1525AA3989DED2C0DC7A033
  */
 public class ConstraintService extends
-		EObjectAwareServiceBase<IConstraintChecker<? extends EObject>>
-		implements IConstraintService {
+		EObjectAwareServiceBase<IConstraintChecker<EObject>> implements
+		IConstraintService {
 
 	/** The compositor extension point ID. */
 	private static final String EXTENSION_POINT_NAME = "org.fortiss.tooling.kernel.modelElementConstraintChecker";
@@ -48,24 +49,49 @@ public class ConstraintService extends
 	private static final String HANDLER_CLASS_ATTRIBUTE_NAME = "checker";
 
 	/** {@inheritDoc} */
-	@SuppressWarnings("unchecked")
 	@Override
-	public List<IConstraintViolation<? extends EObject>> performAllConstraintChecks(
+	public List<IConstraintViolation<EObject>> performAllConstraintChecksRecursively(
 			EObject modelElement) {
-		List<IConstraintViolation<? extends EObject>> result = new LinkedList<IConstraintViolation<? extends EObject>>();
-		for (IConstraintChecker<? extends EObject> checker : getRegisteredHandlers(modelElement
+		List<IConstraintViolation<EObject>> result = new LinkedList<IConstraintViolation<EObject>>();
+		performConstraintCheck(modelElement, result);
+		for (Iterator<EObject> iter = modelElement.eAllContents(); iter
+				.hasNext();) {
+			performConstraintCheck(iter.next(), result);
+		}
+		return result;
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public List<IConstraintViolation<EObject>> performAllConstraintChecks(
+			EObject modelElement) {
+		List<IConstraintViolation<EObject>> result = new LinkedList<IConstraintViolation<EObject>>();
+		performConstraintCheck(modelElement, result);
+		return result;
+	}
+
+	/**
+	 * Performs all constraint checks on the given model element. Violations are
+	 * added to the given list. Constraint checks on content elements are not
+	 * considered.
+	 */
+	private void performConstraintCheck(EObject modelElement,
+			List<IConstraintViolation<EObject>> violationList) {
+		for (IConstraintChecker<EObject> checker : getRegisteredHandlers(modelElement
 				.getClass())) {
 			if (checker.isApplicable(modelElement)) {
-				result.add(checker.apply(modelElement));
+				IConstraintViolation<EObject> violation = checker
+						.apply(modelElement);
+				if (violation != null) {
+					violationList.add(violation);
+				}
 			}
 		}
-		return result;
 	}
 
 	/** {@inheritDoc} */
-	@SuppressWarnings("unchecked")
 	@Override
-	public List<IConstraintChecker<? extends EObject>> getAllConstraintCheckers(
+	public List<IConstraintChecker<EObject>> getAllConstraintCheckers(
 			EObject modelElement) {
 		return getRegisteredHandlers(modelElement.getClass());
 	}
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IConstraintService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IConstraintService.java
index 9063b0594..386962513 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IConstraintService.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/services/IConstraintService.java
@@ -39,8 +39,16 @@ public interface IConstraintService {
 	public static final IConstraintService INSTANCE = new ConstraintService();
 
 	/**
-	 * Performs all constraint checks on the given model element and returns the
-	 * check results.
+	 * Performs all constraint checks on the given model element and recursively
+	 * its content and returns the check results. Note, that this method can be
+	 * time-consuming for large model element trees.
+	 */
+	<T extends EObject> List<IConstraintViolation<T>> performAllConstraintChecksRecursively(
+			T modelElement);
+
+	/**
+	 * Performs all constraint checks only on the given model element and
+	 * returns the check results.
 	 */
 	<T extends EObject> List<IConstraintViolation<T>> performAllConstraintChecks(
 			T modelElement);
-- 
GitLab