| /** |
| * Copyright (c) 2006-2012 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| * Christian Damus (Zeligsoft) - 255469 |
| */ |
| package org.eclipse.emf.ecore.util; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.emf.common.util.BasicDiagnostic; |
| import org.eclipse.emf.common.util.Diagnostic; |
| import org.eclipse.emf.common.util.DiagnosticChain; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.Enumerator; |
| import org.eclipse.emf.common.util.ResourceLocator; |
| import org.eclipse.emf.common.util.TreeIterator; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.common.util.UniqueEList; |
| |
| import org.eclipse.emf.ecore.*; |
| |
| import org.eclipse.emf.ecore.EPackage; |
| import org.eclipse.emf.ecore.plugin.EcorePlugin; |
| |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| |
| import org.eclipse.emf.ecore.xml.namespace.XMLNamespacePackage; |
| import org.eclipse.emf.ecore.xml.type.XMLTypePackage; |
| import org.eclipse.emf.ecore.xml.type.util.XMLTypeValidator; |
| |
| /** |
| * <!-- begin-user-doc --> |
| * The <b>Validator</b> for the model. |
| * <!-- end-user-doc --> |
| * @see org.eclipse.emf.ecore.EcorePackage |
| * @generated |
| */ |
| public class EcoreValidator extends EObjectValidator |
| { |
| /** |
| * The cached model package |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public static final EcoreValidator INSTANCE = new EcoreValidator(); |
| |
| /** |
| * A key to be used in <code>context</code> maps to indicate that stricter validation should be performed |
| * to ensure that the name of each named element is a well formed Java identifier. |
| * The value of the entry must be a {@link Boolean}. |
| * The default value is <code>Boolean.TRUE</code>. |
| * @see EValidator#validate(EObject, DiagnosticChain, Map) |
| * @see #validateENamedElement_WellFormedName(ENamedElement, DiagnosticChain, Map) |
| * @since 2.4 |
| */ |
| public static final String STRICT_NAMED_ELEMENT_NAMES = "org.eclipse.emf.ecore.model.ENamedElement_WellFormedName"; |
| |
| /** |
| * A constant for the {@link org.eclipse.emf.common.util.Diagnostic#getSource() source} of diagnostic {@link org.eclipse.emf.common.util.Diagnostic#getCode() codes} from this package. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see org.eclipse.emf.common.util.Diagnostic#getSource() |
| * @see org.eclipse.emf.common.util.Diagnostic#getCode() |
| * @generated NOT |
| */ |
| public static final String DIAGNOSTIC_SOURCE = "org.eclipse.emf.ecore.model"; |
| |
| /** |
| * A constant with a fixed name that can be used as the base value for additional hand written constants. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| private static final int GENERATED_DIAGNOSTIC_CODE_COUNT = 0; |
| |
| /** |
| * @see #validateEClass_AtMostOneID(EClass, DiagnosticChain, Map) |
| */ |
| public static final int AT_MOST_ONE_ID = GENERATED_DIAGNOSTIC_CODE_COUNT + 1; |
| |
| /** |
| * @see #validateEGenericType_ConsistentArguments(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_ARGUMENTS_INCORRECT_NUMBER = 2; |
| |
| /** |
| * @see #validateEGenericType_ConsistentArguments(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_ARGUMENTS_INVALID_SUBSTITUTION = 3; |
| |
| /** |
| * @see #validateEGenericType_ConsistentArguments(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_ARGUMENTS_NONE = 4; |
| |
| /** |
| * @see #validateEGenericType_ConsistentArguments(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_ARGUMENTS_NONE_ALLOWED = 5; |
| |
| /** |
| * @see #validateETypedElement_ConsistentBounds(ETypedElement, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_BOUNDS = 6; |
| |
| /** |
| * @see #validateEGenericType_ConsistentBounds(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_BOUNDS_NOT_ALLOWED = 7; |
| |
| /** |
| * @see #validateEGenericType_ConsistentBounds(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_BOUNDS_NO_BOUNDS_WITH_TYPE_PARAMETER_OR_CLASSIFIER = 8; |
| |
| /** |
| * @see #validateEGenericType_ConsistentBounds(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_BOUNDS_NO_LOWER_AND_UPPER = 9; |
| |
| /** |
| * @see #validateEReference_ConsistentKeys(EReference, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_KEYS = 10; |
| |
| /** |
| * @see #validateEReference_ConsistentOpposite(EReference, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_OPPOSITE_BAD_TRANSIENT = 11; |
| |
| /** |
| * @see #validateEReference_ConsistentOpposite(EReference, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_OPPOSITE_BOTH_CONTAINMENT = 12; |
| |
| /** |
| * @see #validateEReference_ConsistentOpposite(EReference, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_OPPOSITE_NOT_FROM_TYPE = 13; |
| |
| /** |
| * @see #validateEReference_ConsistentOpposite(EReference, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_OPPOSITE_NOT_MATCHING = 14; |
| |
| /** |
| * @see #validateEClass_ConsistentSuperTypes(EClass, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_SUPER_TYPES_CONFLICT = 15; |
| |
| /** |
| * @see #validateEClass_ConsistentSuperTypes(EClass, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_SUPER_TYPES_DUPLICATE = 16; |
| |
| /** |
| * @see #validateEAttribute_ConsistentTransient(EAttribute, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_TRANSIENT = 17; |
| |
| /** |
| * @see #validateEGenericType_ConsistentType(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_TYPE_CLASS_REQUIRED = 18; |
| |
| /** |
| * @see #validateEGenericType_ConsistentType(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_TYPE_CLASS_NOT_PERMITTED = 19; |
| |
| /** |
| * @see #validateEGenericType_ConsistentType(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_TYPE_DATA_TYPE_NOT_PERMITTED = 20; |
| |
| /** |
| * @see #validateEGenericType_ConsistentType(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_TYPE_NO_TYPE_PARAMETER_AND_CLASSIFIER = 21; |
| |
| /** |
| * @see #validateEGenericType_ConsistentType(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_TYPE_PRIMITIVE_TYPE_NOT_PERMITTED = 22; |
| |
| /** |
| * @see #validateEGenericType_ConsistentType(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_TYPE_TYPE_PARAMETER_NOT_IN_SCOPE = 23; |
| |
| /** |
| * @see #validateEGenericType_ConsistentType(EGenericType, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_TYPE_WILDCARD_NOT_PERMITTED = 24; |
| |
| /** |
| * @see #validateEClass_InterfaceIsAbstract(EClass, DiagnosticChain, Map) |
| */ |
| public static final int INTERFACE_IS_ABSTRACT = 25; |
| |
| /** |
| * @see #validateEClass_NoCircularSuperTypes(EClass, DiagnosticChain, Map) |
| */ |
| public static final int NO_CIRCULAR_SUPER_TYPES = 26; |
| |
| /** |
| * @see #validateEOperation_NoRepeatingVoid(EOperation, DiagnosticChain, Map) |
| */ |
| public static final int NO_REPEATING_VOID = 27; |
| |
| /** |
| * @see #validateEReference_SingleContainer(EReference, DiagnosticChain, Map) |
| */ |
| public static final int SINGLE_CONTAINER = 28; |
| |
| /** |
| * @see #validateEPackage_UniqueClassifierNames(EPackage, DiagnosticChain, Map) |
| */ |
| public static final int UNIQUE_CLASSIFIER_NAMES = 29; |
| |
| /** |
| * @see #validateEEnum_UniqueEnumeratorNames(EEnum, DiagnosticChain, Map) |
| */ |
| public static final int UNIQUE_ENUMERATOR_LITERALS = 30; |
| |
| /** |
| * @see #validateEEnum_UniqueEnumeratorNames(EEnum, DiagnosticChain, Map) |
| */ |
| public static final int UNIQUE_ENUMERATOR_NAMES = 31; |
| |
| /** |
| * @see #validateEClass_UniqueFeatureNames(EClass, DiagnosticChain, Map) |
| */ |
| public static final int UNIQUE_FEATURE_NAMES = 32; |
| |
| /** |
| * @see #validateEPackage_UniqueNsURIs(EPackage, DiagnosticChain, Map) |
| */ |
| public static final int UNIQUE_NS_URIS = 33; |
| |
| /** |
| * @see #validateEClass_UniqueOperationSignatures(EClass, DiagnosticChain, Map) |
| */ |
| public static final int UNIQUE_OPERATION_SIGNATURES = 34; |
| |
| /** |
| *@see #validateEOperation_UniqueParameterNames(EOperation, DiagnosticChain, Map) |
| */ |
| public static final int UNIQUE_PARAMETER_NAMES = 35; |
| |
| /** |
| * @see #validateEPackage_UniqueSubpackageNames(EPackage, DiagnosticChain, Map) |
| */ |
| public static final int UNIQUE_SUBPACKAGE_NAMES = 36; |
| |
| /** |
| *@see #validateEOperation_UniqueParameterNames(EOperation, DiagnosticChain, Map) |
| *@see #validateEClassifier_UniqueTypeParameterNames(EClassifier, DiagnosticChain, Map) |
| */ |
| public static final int UNIQUE_TYPE_PARAMETER_NAMES = 37; |
| |
| /** |
| * @see #validateEStructuralFeature_ValidDefaultValueLiteral(EStructuralFeature, DiagnosticChain, Map) |
| */ |
| public static final int VALID_DEFAULT_VALUE_LITERAL = 38; |
| |
| /** |
| * @see #validateETypedElement_ValidLowerBound(ETypedElement, DiagnosticChain, Map) |
| */ |
| public static final int VALID_LOWER_BOUND = 39; |
| |
| /** |
| * @see #validateETypedElement_ValidType(ETypedElement, DiagnosticChain, Map) |
| */ |
| public static final int VALID_TYPE = 40; |
| |
| /** |
| * @see #validateETypedElement_ValidUpperBound(ETypedElement, DiagnosticChain, Map) |
| */ |
| public static final int VALID_UPPER_BOUND = 41; |
| |
| /** |
| * @see #validateEClassifier_WellFormedInstanceTypeName(EClassifier, DiagnosticChain, Map) |
| */ |
| public static final int WELL_FORMED_INSTANCE_TYPE_NAME = 42; |
| |
| /** |
| * @see #validateEClass_WellFormedMapEntryClass(EClass, DiagnosticChain, Map) |
| */ |
| public static final int WELL_FORMED_MAP_ENTRY_CLASS = 43; |
| |
| /** |
| * @see #validateEClass_WellFormedMapEntryClass(EClass, DiagnosticChain, Map) |
| */ |
| public static final int WELL_FORMED_NAME = 44; |
| |
| /** |
| * @see #validateEPackage_WellFormedNsPrefix(EPackage, DiagnosticChain, Map) |
| */ |
| public static final int WELL_FORMED_NS_PREFIX = 45; |
| |
| /** |
| * @see #validateEPackage_WellFormedNsURI(EPackage, DiagnosticChain, Map) |
| */ |
| public static final int WELL_FORMED_NS_URI = 46; |
| |
| /** |
| * @see #validateEAnnotation_WellFormedSourceURI(EAnnotation, DiagnosticChain, Map) |
| */ |
| public static final int WELL_FORMED_SOURCE_URI = 47; |
| |
| /** |
| * @see #validateEClass_DisjointFeatureAndOperationSignatures(EClass, DiagnosticChain, Map) |
| */ |
| public static final int DISJOINT_FEATURE_AND_OPERATION_SIGNATURES = 48; |
| |
| /** |
| * @see #validateEClass_WellFormedMapEntryClass(EClass, DiagnosticChain, Map) |
| */ |
| public static final int WELL_FORMED_MAP_ENTRY_NO_INSTANCE_CLASS_NAME = 49; |
| |
| /** |
| * @see #validateEReference_ConsistentUnique(EReference, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_UNIQUE = 50; |
| |
| /** |
| * @see #validateEReference_ConsistentContainer(EReference, DiagnosticChain, Map) |
| */ |
| public static final int CONSISTENT_CONTAINER = 51; |
| |
| /** |
| * A constant with a fixed name that can be used as the base value for additional hand written constants in a derived class. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| protected static final int DIAGNOSTIC_CODE_COUNT = CONSISTENT_CONTAINER; |
| |
| /** |
| * The cached base package validator. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| protected XMLTypeValidator xmlTypeValidator; |
| |
| /** |
| * Creates an instance of the switch. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public EcoreValidator() |
| { |
| super(); |
| xmlTypeValidator = XMLTypeValidator.INSTANCE; |
| } |
| |
| /** |
| * Returns the package of this validator switch. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| protected EPackage getEPackage() |
| { |
| return EcorePackage.eINSTANCE; |
| } |
| |
| /** |
| * Calls <code>validateXXX</code> for the corresponding classifier of the model. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| protected boolean validate(int classifierID, Object value, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| switch (classifierID) |
| { |
| case EcorePackage.EATTRIBUTE: |
| return validateEAttribute((EAttribute)value, diagnostics, context); |
| case EcorePackage.EANNOTATION: |
| return validateEAnnotation((EAnnotation)value, diagnostics, context); |
| case EcorePackage.ECLASS: |
| return validateEClass((EClass)value, diagnostics, context); |
| case EcorePackage.ECLASSIFIER: |
| return validateEClassifier((EClassifier)value, diagnostics, context); |
| case EcorePackage.EDATA_TYPE: |
| return validateEDataType((EDataType)value, diagnostics, context); |
| case EcorePackage.EENUM: |
| return validateEEnum((EEnum)value, diagnostics, context); |
| case EcorePackage.EENUM_LITERAL: |
| return validateEEnumLiteral((EEnumLiteral)value, diagnostics, context); |
| case EcorePackage.EFACTORY: |
| return validateEFactory((EFactory)value, diagnostics, context); |
| case EcorePackage.EMODEL_ELEMENT: |
| return validateEModelElement((EModelElement)value, diagnostics, context); |
| case EcorePackage.ENAMED_ELEMENT: |
| return validateENamedElement((ENamedElement)value, diagnostics, context); |
| case EcorePackage.EOBJECT: |
| return validateEObject((EObject)value, diagnostics, context); |
| case EcorePackage.EOPERATION: |
| return validateEOperation((EOperation)value, diagnostics, context); |
| case EcorePackage.EPACKAGE: |
| return validateEPackage((EPackage)value, diagnostics, context); |
| case EcorePackage.EPARAMETER: |
| return validateEParameter((EParameter)value, diagnostics, context); |
| case EcorePackage.EREFERENCE: |
| return validateEReference((EReference)value, diagnostics, context); |
| case EcorePackage.ESTRUCTURAL_FEATURE: |
| return validateEStructuralFeature((EStructuralFeature)value, diagnostics, context); |
| case EcorePackage.ETYPED_ELEMENT: |
| return validateETypedElement((ETypedElement)value, diagnostics, context); |
| case EcorePackage.ESTRING_TO_STRING_MAP_ENTRY: |
| return validateEStringToStringMapEntry((Map.Entry<?, ?>)value, diagnostics, context); |
| case EcorePackage.EGENERIC_TYPE: |
| return validateEGenericType((EGenericType)value, diagnostics, context); |
| case EcorePackage.ETYPE_PARAMETER: |
| return validateETypeParameter((ETypeParameter)value, diagnostics, context); |
| case EcorePackage.EBIG_DECIMAL: |
| return validateEBigDecimal((BigDecimal)value, diagnostics, context); |
| case EcorePackage.EBIG_INTEGER: |
| return validateEBigInteger((BigInteger)value, diagnostics, context); |
| case EcorePackage.EBOOLEAN: |
| return validateEBoolean((Boolean)value, diagnostics, context); |
| case EcorePackage.EBOOLEAN_OBJECT: |
| return validateEBooleanObject((Boolean)value, diagnostics, context); |
| case EcorePackage.EBYTE: |
| return validateEByte((Byte)value, diagnostics, context); |
| case EcorePackage.EBYTE_ARRAY: |
| return validateEByteArray((byte[])value, diagnostics, context); |
| case EcorePackage.EBYTE_OBJECT: |
| return validateEByteObject((Byte)value, diagnostics, context); |
| case EcorePackage.ECHAR: |
| return validateEChar((Character)value, diagnostics, context); |
| case EcorePackage.ECHARACTER_OBJECT: |
| return validateECharacterObject((Character)value, diagnostics, context); |
| case EcorePackage.EDATE: |
| return validateEDate((Date)value, diagnostics, context); |
| case EcorePackage.EDIAGNOSTIC_CHAIN: |
| return validateEDiagnosticChain((DiagnosticChain)value, diagnostics, context); |
| case EcorePackage.EDOUBLE: |
| return validateEDouble((Double)value, diagnostics, context); |
| case EcorePackage.EDOUBLE_OBJECT: |
| return validateEDoubleObject((Double)value, diagnostics, context); |
| case EcorePackage.EE_LIST: |
| return validateEEList((EList<?>)value, diagnostics, context); |
| case EcorePackage.EENUMERATOR: |
| return validateEEnumerator((Enumerator)value, diagnostics, context); |
| case EcorePackage.EFEATURE_MAP: |
| return validateEFeatureMap((FeatureMap)value, diagnostics, context); |
| case EcorePackage.EFEATURE_MAP_ENTRY: |
| return validateEFeatureMapEntry((FeatureMap.Entry)value, diagnostics, context); |
| case EcorePackage.EFLOAT: |
| return validateEFloat((Float)value, diagnostics, context); |
| case EcorePackage.EFLOAT_OBJECT: |
| return validateEFloatObject((Float)value, diagnostics, context); |
| case EcorePackage.EINT: |
| return validateEInt((Integer)value, diagnostics, context); |
| case EcorePackage.EINTEGER_OBJECT: |
| return validateEIntegerObject((Integer)value, diagnostics, context); |
| case EcorePackage.EJAVA_CLASS: |
| return validateEJavaClass((Class<?>)value, diagnostics, context); |
| case EcorePackage.EJAVA_OBJECT: |
| return validateEJavaObject(value, diagnostics, context); |
| case EcorePackage.ELONG: |
| return validateELong((Long)value, diagnostics, context); |
| case EcorePackage.ELONG_OBJECT: |
| return validateELongObject((Long)value, diagnostics, context); |
| case EcorePackage.EMAP: |
| return validateEMap((Map<?, ?>)value, diagnostics, context); |
| case EcorePackage.ERESOURCE: |
| return validateEResource((Resource)value, diagnostics, context); |
| case EcorePackage.ERESOURCE_SET: |
| return validateEResourceSet((ResourceSet)value, diagnostics, context); |
| case EcorePackage.ESHORT: |
| return validateEShort((Short)value, diagnostics, context); |
| case EcorePackage.ESHORT_OBJECT: |
| return validateEShortObject((Short)value, diagnostics, context); |
| case EcorePackage.ESTRING: |
| return validateEString((String)value, diagnostics, context); |
| case EcorePackage.ETREE_ITERATOR: |
| return validateETreeIterator((TreeIterator<?>)value, diagnostics, context); |
| case EcorePackage.EINVOCATION_TARGET_EXCEPTION: |
| return validateEInvocationTargetException((InvocationTargetException)value, diagnostics, context); |
| default: |
| return true; |
| } |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEAttribute(EAttribute eAttribute, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eAttribute, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidLowerBound(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidUpperBound(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ConsistentBounds(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidType(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEStructuralFeature_ValidDefaultValueLiteral(eAttribute, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEAttribute_ConsistentTransient(eAttribute, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the ConsistentTransient constraint of '<em>EAttribute</em>'. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEAttribute_ConsistentTransient(EAttribute eAttribute, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| EDataType eAttributeType = eAttribute.getEAttributeType(); |
| boolean result = |
| isEffectivelyTransient(eAttribute) || |
| eAttributeType == null || |
| eAttributeType.isSerializable() || |
| FeatureMapUtil.isFeatureMapEntry(eAttributeType); |
| if (!result && diagnostics != null) |
| { |
| String attributeName = eAttribute.getName(); |
| if (eAttribute.getEContainingClass() != null) |
| { |
| attributeName = eAttribute.getEContainingClass().getName() + "." + attributeName; |
| } |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_TRANSIENT, |
| "_UI_EAttributeConsistentTransient_diagnostic", |
| new String[] { attributeName }, |
| new Object[] { eAttribute, EcorePackage.Literals.ESTRUCTURAL_FEATURE__TRANSIENT }, |
| context)); |
| } |
| return result; |
| } |
| |
| private static boolean isEffectivelyTransient(EStructuralFeature eStructuralFeature) |
| { |
| if (eStructuralFeature.isTransient()) |
| { |
| EStructuralFeature group = ExtendedMetaData.INSTANCE.getGroup(eStructuralFeature); |
| return group == null || isEffectivelyTransient(group); |
| } |
| else |
| { |
| return false; |
| } |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEAnnotation(EAnnotation eAnnotation, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eAnnotation, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eAnnotation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eAnnotation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eAnnotation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eAnnotation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eAnnotation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eAnnotation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eAnnotation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eAnnotation, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEAnnotation_WellFormedSourceURI(eAnnotation, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the WellFormedSourceURI constraint of '<em>EAnnotation</em>'. |
| * <!-- begin-user-doc --> |
| * The source URI must either be either <code>null</code> or {@link #isWellFormedURI(String) well formed}. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEAnnotation_WellFormedSourceURI(EAnnotation eAnnotation, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| String source = eAnnotation.getSource(); |
| boolean result = source == null || isWellFormedURI(source); |
| if (!result && diagnostics != null) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_SOURCE_URI, |
| "_UI_EAnnotationSourceURINotWellFormed_diagnostic", |
| new Object[] { source }, |
| new Object[] { eAnnotation, EcorePackage.Literals.EANNOTATION__SOURCE }, |
| context)); |
| } |
| return result; |
| } |
| |
| /** |
| * A well formed URI string must have a non-zero length, |
| * and must encode any special characters such as the space character. |
| * As such, creating a {@link URI#createURI(String, boolean) URI}, |
| * ignoring the properly encoded characters, |
| * and converting that to a {@link URI#toString() string}, |
| * must yield this URI string itself. |
| * @param uri the URI string in question. |
| * @return whether the URI is well formed. |
| */ |
| protected static boolean isWellFormedURI(String uri) |
| { |
| try |
| { |
| return uri != null && uri.length() != 0 && uri.equals(URI.createURI(uri, true).toString()); |
| } |
| catch (Throwable exception) |
| { |
| return false; |
| } |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEClass(EClass eClass, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eClass, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClassifier_WellFormedInstanceTypeName(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClassifier_UniqueTypeParameterNames(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClass_InterfaceIsAbstract(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClass_AtMostOneID(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClass_UniqueFeatureNames(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClass_UniqueOperationSignatures(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClass_NoCircularSuperTypes(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClass_WellFormedMapEntryClass(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClass_ConsistentSuperTypes(eClass, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClass_DisjointFeatureAndOperationSignatures(eClass, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the InterfaceIsAbstract constraint of '<em>EClass</em>'. |
| * <!-- begin-user-doc --> |
| * A class that is an interface must be abstract. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEClass_InterfaceIsAbstract(EClass eClass, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = !eClass.isInterface() || eClass.isAbstract(); |
| if (!result && diagnostics != null) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| INTERFACE_IS_ABSTRACT, |
| "_UI_EClassInterfaceNotAbstract_diagnostic", |
| null, |
| new Object[] { eClass, EcorePackage.Literals.ECLASS__ABSTRACT }, |
| context)); |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the AtMostOneID constraint of '<em>EClass</em>'. |
| * <!-- begin-user-doc --> |
| * There can be at most one attribute that is an ID. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEClass_AtMostOneID(EClass eClass, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| EAttribute eIDAttribute = eClass.getEIDAttribute(); |
| |
| // A document root can have multiple ID attributes because there can be multiple global element or attribute declarations of type ID |
| // and these will be the ID in the complex types that reference them, |
| // i.e., they aren't really the ID of the document root. |
| // |
| if (eIDAttribute != null && !ExtendedMetaData.INSTANCE.isDocumentRoot(eClass)) |
| { |
| List<EAttribute> eIDAttributes = new ArrayList<EAttribute>(); |
| eIDAttributes.add(eIDAttribute); |
| |
| for (EAttribute eAttribute : eClass.getEAllAttributes()) |
| { |
| if (eAttribute.isID() && eIDAttribute != eAttribute) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| eIDAttributes.add(eAttribute); |
| } |
| } |
| } |
| |
| if (!result && diagnostics != null) |
| { |
| // We do not want to diagnose any errors that have already been diagnosed by a super type. |
| // |
| for (EClass eSuperType : eClass.getESuperTypes()) |
| { |
| EList<EStructuralFeature> eAllStructuralFeatures = eSuperType.getEAllStructuralFeatures(); |
| if (eAllStructuralFeatures.containsAll(eIDAttributes)) |
| { |
| return false; |
| } |
| } |
| |
| List<String> labels = new ArrayList<String>(); |
| List<Object> objects = new ArrayList<Object>(); |
| objects.add(eClass); |
| for (EAttribute eAttribute : eIDAttributes) |
| { |
| labels.add(getFeatureLabel(eAttribute,context)); |
| objects.add(eAttribute); |
| } |
| objects.add(EcorePackage.Literals.ECLASS__EALL_ATTRIBUTES); |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| AT_MOST_ONE_ID, |
| "_UI_EClassAtMostOneID_diagnostic", |
| labels.toArray(new Object[labels.size()]), |
| objects.toArray(new Object [objects.size()]), |
| context)); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the UniqueFeatureNames constraint of '<em>EClass</em>'. |
| * <!-- begin-user-doc --> |
| * No two features may have matching names. |
| * Feature names are matched ignoring their case and their underscore separators. |
| * It is an error to have two features with names that are equal but only a warning to have two features with names that match. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEClass_UniqueFeatureNames(EClass eClass, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| int size = eClass.getFeatureCount(); |
| if (size > 0) |
| { |
| // Build a list of the keys |
| // |
| Map<String, List<EStructuralFeature>> keys = new HashMap<String, List<EStructuralFeature>>(); |
| for (int i = 0; i < size; ++i) |
| { |
| EStructuralFeature eStructuralFeature = eClass.getEStructuralFeature(i); |
| String name = eStructuralFeature.getName(); |
| |
| // Don't bother complaining about things with no name, since there are constraints for that problem. |
| // |
| if (name != null) |
| { |
| // Drop the _ separators and normalize the case. |
| // |
| String key = name.replace("_", "").toLowerCase(); |
| List<EStructuralFeature> eStructuralFeatures = keys.get(key); |
| if (eStructuralFeatures == null) |
| { |
| eStructuralFeatures = new ArrayList<EStructuralFeature>(); |
| keys.put(key, eStructuralFeatures); |
| } |
| eStructuralFeatures.add(eStructuralFeature); |
| |
| if (eStructuralFeatures.size() > 1) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| } |
| } |
| } |
| } |
| |
| if (!result && diagnostics != null) |
| { |
| // We do not want to diagnose any errors that have already been diagnosed by a super type. |
| // |
| for (EClass eSuperType : eClass.getESuperTypes()) |
| { |
| EList<EStructuralFeature> eAllStructuralFeatures = eSuperType.getEAllStructuralFeatures(); |
| for (Iterator<Map.Entry<String, List<EStructuralFeature>>> i = keys.entrySet().iterator(); i.hasNext(); ) |
| { |
| Map.Entry<String, List<EStructuralFeature>> entry = i.next(); |
| if (eAllStructuralFeatures.containsAll(entry.getValue())) |
| { |
| i.remove(); |
| } |
| } |
| } |
| |
| for (Map.Entry<String, List<EStructuralFeature>> entry : keys.entrySet()) |
| { |
| List<EStructuralFeature> eStructuralFeatures = entry.getValue(); |
| if (eStructuralFeatures.size() > 1) |
| { |
| List<String> names = new UniqueEList<String>(); |
| List<Object> objects = new ArrayList<Object>(); |
| objects.add(eClass); |
| for (EStructuralFeature eStructuralFeature : eStructuralFeatures) |
| { |
| names.add(eStructuralFeature.getName()); |
| objects.add(eStructuralFeature); |
| } |
| objects.add(EcorePackage.Literals.ECLASS__EALL_STRUCTURAL_FEATURES); |
| |
| if (names.size() == objects.size() - 2) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.WARNING, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_FEATURE_NAMES, |
| "_UI_EClassDissimilarEStructuralFeatureName_diagnostic", |
| names.toArray(new Object[names.size()]), |
| objects.toArray(new Object[objects.size()]), |
| context)); |
| |
| } |
| else |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_FEATURE_NAMES, |
| "_UI_EClassUniqueEStructuralFeatureName_diagnostic", |
| new Object [] { names.get(0) }, |
| objects.toArray(new Object[objects.size()]), |
| context)); |
| } |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the UniqueOperationSignatures constraint of '<em>EClass</em>'. |
| * <!-- begin-user-doc --> |
| * No two operations defined in the same class may have matching signatures. |
| * The signature is determined by the name of the operation and the types of its parameters. |
| * If the name is the same and the types match, the signatures match. |
| * Types match if they are the same classifier, or both classifiers have instance class names that are the same. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEClass_UniqueOperationSignatures(EClass eClass, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return uniqueOperationSignaturesValidator.validateEOperationSignatures(eClass, eClass.getEOperations(), eClass.getEOperations(), diagnostics, context); |
| } |
| |
| private class EOperationSignatureValidator |
| { |
| protected String messageKey; |
| protected int messageCode; |
| protected boolean ignoreOperationsWithSuppressedVisibility; |
| |
| public EOperationSignatureValidator(String messageKey, int messageCode) |
| { |
| this.messageKey = messageKey; |
| this.messageCode = messageCode; |
| } |
| |
| public EOperationSignatureValidator(String messageKey, int messageCode, boolean ignoreOperationsWithSuppressedVisibility) |
| { |
| this.messageKey = messageKey; |
| this.messageCode = messageCode; |
| this.ignoreOperationsWithSuppressedVisibility = ignoreOperationsWithSuppressedVisibility; |
| } |
| |
| public final boolean validateEOperationSignatures |
| (EClass eClass, EList<EOperation> eOperations, Collection<EOperation> otherEOperations, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| for (EOperation eOperation : eOperations) |
| { |
| if (!ignoreOperationsWithSuppressedVisibility || !EcoreUtil.isSuppressedVisibility(eOperation)) |
| { |
| String name = eOperation.getName(); |
| if (name != null) |
| { |
| EList<EParameter> eParameters = eOperation.getEParameters(); |
| int eParameterSize = eParameters.size(); |
| LOOP: |
| for (EOperation otherEOperation : otherEOperations) |
| { |
| // Match against every other operation but this one. |
| // |
| if (otherEOperation == eOperation) |
| { |
| break; |
| } |
| else |
| { |
| String otherName = otherEOperation.getName(); |
| if (name.equals(otherName)) |
| { |
| EList<EParameter> otherEParmeters = otherEOperation.getEParameters(); |
| if (otherEParmeters.size() == eParameterSize) |
| { |
| for (int i = 0; i < eParameterSize; ++i) |
| { |
| EParameter eParameter = eParameters.get(i); |
| EParameter otherEParameter = otherEParmeters.get(i); |
| EClassifier eType = eParameter.getEType(); |
| EClassifier otherEType = otherEParameter.getEType(); |
| |
| // There is no match if the types are different |
| // and they don't each specify the same non-null instance class name. |
| // |
| if (eType != otherEType) |
| { |
| if (eType != null && otherEType != null) |
| { |
| String instanceClassName = eType.getInstanceClassName(); |
| String otherInstanceClassName = otherEType.getInstanceClassName(); |
| if (instanceClassName != otherInstanceClassName || instanceClassName == null || eParameter.isMany() != otherEParameter.isMany()) |
| { |
| continue LOOP; |
| } |
| } |
| else |
| { |
| continue LOOP; |
| } |
| } |
| else if (eParameter.isMany() != otherEParameter.isMany()) |
| { |
| continue LOOP; |
| } |
| } |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| |
| EModelElement target = getTarget(otherEOperation); |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| messageCode, |
| messageKey, |
| messageCode == DISJOINT_FEATURE_AND_OPERATION_SIGNATURES ? |
| new Object[] { getObjectLabel(eOperation, context), getObjectLabel(target, context) } : |
| new Object[] { getObjectLabel(target, context), getObjectLabel(eOperation, context) }, |
| messageCode == DISJOINT_FEATURE_AND_OPERATION_SIGNATURES ? |
| new Object[] { eClass, eOperation, target, EcorePackage.Literals.ECLASS__EALL_OPERATIONS } : |
| new Object[] { eClass, target, eOperation, EcorePackage.Literals.ECLASS__EALL_OPERATIONS }, |
| context)); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| protected EModelElement getTarget(EOperation targetEOperation) |
| { |
| return targetEOperation; |
| } |
| } |
| |
| private final EOperationSignatureValidator uniqueOperationSignaturesValidator = |
| new EOperationSignatureValidator("_UI_EClassUniqueEOperationSignatures_diagnostic", UNIQUE_OPERATION_SIGNATURES); |
| |
| /** |
| * There are other constraints we should check such as consistency of the return type, |
| * correctness of the signature with respect to type substitution, |
| * and so on... |
| * Validates the UniqueOperationSignatures constraint of '<em>EClass</em>'. |
| * <!-- begin-user-doc --> |
| * No two operation defined in the same class may have matching signatures. |
| * The signature is determined by the name of the operation and the types of its parameters. |
| * If the name is the same and the types match, the signatures match. |
| * Types match if they are same classifier, of both classifiers have instance class names that are the same. |
| * <!-- end-user-doc --> |
| * @generated NOT YET |
| */ |
| @SuppressWarnings("unused") |
| private boolean validateEClass_UniqueOperationSignatures2(EClass eClass, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| EList<EOperation> eAllOperations = eClass.getEAllOperations(); |
| if (!eAllOperations.isEmpty()) |
| { |
| // Iterate over all the operations but skip all the operations in the first super. |
| // |
| List<EOperation> eOperations = eAllOperations; |
| EList<EClass> eSuperTypes = eClass.getESuperTypes(); |
| if (!eSuperTypes.isEmpty()) |
| { |
| eOperations = eAllOperations.subList(eSuperTypes.get(0).getEAllOperations().size(), eAllOperations.size()); |
| } |
| for (EOperation eOperation : eOperations) |
| { |
| String name = eOperation.getName(); |
| if (name != null) |
| { |
| EList<EParameter> eParameters = eOperation.getEParameters(); |
| int eParameterSize = eParameters.size(); |
| LOOP: |
| for (EOperation otherEOperation : eAllOperations) |
| { |
| // Match against every other operation but this one. |
| // |
| if (otherEOperation == eOperation) |
| { |
| break; |
| } |
| else |
| { |
| String otherName = otherEOperation.getName(); |
| if (name.equals(otherName)) |
| { |
| EList<EParameter> otherEParmeters = otherEOperation.getEParameters(); |
| if (otherEParmeters.size() == eParameterSize) |
| { |
| for (int i = 0; i < eParameterSize; ++i) |
| { |
| EParameter eParameter = eParameters.get(i); |
| EParameter otherEParameter = otherEParmeters.get(i); |
| EClassifier eType = eParameter.getEType(); |
| EClassifier otherEType = otherEParameter.getEType(); |
| |
| // There is no match if the types are different |
| // and they don't each specify the same non-null instance class name. |
| // |
| if (eType != otherEType) |
| { |
| if (eType != null && otherEType != null) |
| { |
| String instanceClassName = eType.getInstanceClassName(); |
| String otherInstanceClassName = otherEType.getInstanceClassName(); |
| if (instanceClassName != otherInstanceClassName && instanceClassName != null && otherInstanceClassName != null) |
| { |
| continue LOOP; |
| } |
| } |
| } |
| } |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| |
| // We do not want to diagnose any error that have already been diagnosed by a super type. |
| // |
| for (EClass eSuperType : eClass.getEAllSuperTypes()) |
| { |
| EList<EOperation> superTypeEAllOperations = eSuperType.getEAllOperations(); |
| if (superTypeEAllOperations.contains(eOperation) && superTypeEAllOperations.contains(otherEOperation)) |
| { |
| continue LOOP; |
| } |
| } |
| |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_OPERATION_SIGNATURES, |
| "_UI_EClassUniqueEOperationSignatures_diagnostic", |
| new Object[] { getObjectLabel(eOperation, context), getObjectLabel(otherEOperation, context) }, |
| new Object[] { eClass, eOperation, otherEOperation, EcorePackage.Literals.ECLASS__EALL_OPERATIONS }, |
| context)); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the NoCircularSuperTypes constraint of '<em>EClass</em>'. |
| * <!-- begin-user-doc --> |
| * A super type must not appear in its own list of all super types. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEClass_NoCircularSuperTypes(EClass eClass, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| EList<EClass> eAllSuperTypes = eClass.getEAllSuperTypes(); |
| boolean result = !eAllSuperTypes.contains(eClass); |
| if (result) |
| { |
| for (EClass otherEClass : eAllSuperTypes) |
| { |
| if (otherEClass.getEAllSuperTypes().contains(eClass)) |
| { |
| result = false; |
| break; |
| } |
| } |
| } |
| if (!result && diagnostics != null) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| NO_CIRCULAR_SUPER_TYPES, |
| "_UI_EClassNoCircularSuperTypes_diagnostic", |
| null, |
| new Object[] { eClass, EcorePackage.Literals.ECLASS__EALL_SUPER_TYPES }, |
| context)); |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the WellFormedMapEntryClass constraint of '<em>EClass</em>'. |
| * <!-- begin-user-doc --> |
| * A map entry class must have features named 'key' and 'value'. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEClass_WellFormedMapEntryClass(EClass eClass, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| if (eClass.getInstanceClassName() == "java.util.Map$Entry") |
| { |
| EStructuralFeature keyFeature = eClass.getEStructuralFeature("key"); |
| if (keyFeature == null) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_MAP_ENTRY_CLASS, |
| "_UI_EClassNotWellFormedMapEntry_diagnostic", |
| new Object[] { "key" }, |
| new Object[] { eClass, EcorePackage.Literals.ECLASS__EALL_STRUCTURAL_FEATURES }, |
| context)); |
| } |
| } |
| EStructuralFeature valueFeature = eClass.getEStructuralFeature("value"); |
| if (valueFeature == null) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_MAP_ENTRY_CLASS, |
| "_UI_EClassNotWellFormedMapEntry_diagnostic", |
| new Object[] { "value" }, |
| new Object[] { eClass, EcorePackage.Literals.ECLASS__EALL_STRUCTURAL_FEATURES }, |
| context)); |
| } |
| } |
| } |
| else |
| { |
| for (EClass eSuperType : eClass.getEAllSuperTypes()) |
| { |
| if (eSuperType.getInstanceClassName() == "java.util.Map$Entry") |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_MAP_ENTRY_NO_INSTANCE_CLASS_NAME, |
| "_UI_EClassNotWellFormedMapEntryNoInstanceClassName_diagnostic", |
| null, |
| new Object[] { eClass, EcorePackage.Literals.ECLASSIFIER__INSTANCE_TYPE_NAME }, |
| context)); |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the ConsistentSuperTypes constraint of '<em>EClass</em>'. |
| * <!-- begin-user-doc --> |
| * The same class must not occur more than once among the generic super types |
| * nor among all the generic super types |
| * where occurrences in the latter represent conflicting instantiations of the same classifier. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEClass_ConsistentSuperTypes(EClass eClass, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| |
| // Maintain a list of classifiers for looking up conflicts. |
| // |
| ArrayList<EClassifier> superTypes = new ArrayList<EClassifier>(); |
| |
| // Look for duplicates among the generic super types. |
| // |
| EList<EGenericType> eGenericSuperTypes = eClass.getEGenericSuperTypes(); |
| for (EGenericType eGenericSuperType : eGenericSuperTypes) |
| { |
| // Ignore it if it isn't a class. Not being a class is diagnosed for the generic type itself. |
| // |
| EClassifier eClassifier = eGenericSuperType.getEClassifier(); |
| if (eClassifier instanceof EClass) |
| { |
| int index = superTypes.indexOf(eClassifier); |
| if (index != -1) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_SUPER_TYPES_DUPLICATE, |
| "_UI_EClassNoDuplicateSuperTypes_diagnostic", |
| new Object [] { eGenericSuperTypes.indexOf(eGenericSuperType), index }, |
| new Object[] { eClass, eGenericSuperTypes.get(index), eGenericSuperType, EcorePackage.Literals.ECLASS__EGENERIC_SUPER_TYPES }, |
| context)); |
| } |
| } |
| } |
| superTypes.add(eClassifier); |
| } |
| |
| if (result) |
| { |
| superTypes.clear(); |
| EList<EGenericType> eAllGenericSuperTypes = eClass.getEAllGenericSuperTypes(); |
| for (EGenericType eGenericSuperType : eAllGenericSuperTypes) |
| { |
| EClassifier eClassifier = eGenericSuperType.getEClassifier(); |
| if (eClassifier instanceof EClass) |
| { |
| int index = superTypes.indexOf(eClassifier); |
| if (index != -1) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_SUPER_TYPES_CONFLICT, |
| "_UI_EClassConsistentSuperTypes_diagnostic", |
| new Object [] { getObjectLabel(eClassifier, context) }, |
| new Object[] { eClass, eGenericSuperType, eAllGenericSuperTypes.get(index), EcorePackage.Literals.ECLASS__EALL_GENERIC_SUPER_TYPES }, |
| context)); |
| } |
| } |
| } |
| superTypes.add(eClassifier); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the DisjointFeatureAndOperationSignatures constraint of '<em>EClass</em>'. |
| * <!-- begin-user-doc --> |
| * Each feature defined in the class is |
| * interpreted as implicitly defining the operations |
| * with the signatures corresponding to the generated accessors for that feature |
| * hence the same type of constraint as {@link #validateEClass_UniqueOperationSignatures(EClass, DiagnosticChain, Map)} applies. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEClass_DisjointFeatureAndOperationSignatures(EClass eClass, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| EList<EOperation> eOperations = eClass.getEOperations(); |
| final Map<EOperation, EStructuralFeature> implicitEOperationToEStructuralFeatureMap = new LinkedHashMap<EOperation, EStructuralFeature>(); |
| if (!eOperations.isEmpty()) |
| { |
| for (EStructuralFeature eStructuralFeature : eClass.getEStructuralFeatures()) |
| { |
| String featureName = eStructuralFeature.getName(); |
| EClassifier eType = eStructuralFeature.getEType(); |
| if (featureName != null && featureName.length() != 0 && eType != null) |
| { |
| featureName = featureName.substring(0,1).toUpperCase() + featureName.substring(1); |
| if (!EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.GET)) |
| { |
| String getAccessor = (eStructuralFeature.isMany() || !"boolean".equals(eType.getInstanceClassName()) ? "get" : "is") + featureName; |
| if ("getClass".equals(getAccessor)) |
| { |
| getAccessor = "getClass_"; |
| } |
| EOperation eOperation = EcoreFactory.eINSTANCE.createEOperation(); |
| eOperation.setName(getAccessor); |
| eOperation.setUpperBound(eStructuralFeature.getUpperBound()); |
| eOperation.setOrdered(eStructuralFeature.isOrdered()); |
| eOperation.setUnique(eStructuralFeature.isUnique()); |
| eOperation.setEType(eType); |
| implicitEOperationToEStructuralFeatureMap.put(eOperation, eStructuralFeature); |
| } |
| if (!eStructuralFeature.isMany() && eStructuralFeature.isChangeable() && !EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.SET)) |
| { |
| String setAccessor = "set" + featureName; |
| EOperation eOperation = EcoreFactory.eINSTANCE.createEOperation(); |
| eOperation.setName(setAccessor); |
| EParameter eParameter = EcoreFactory.eINSTANCE.createEParameter(); |
| eParameter.setName(featureName); |
| eParameter.setEType(eType); |
| eOperation.getEParameters().add(eParameter); |
| implicitEOperationToEStructuralFeatureMap.put(eOperation, eStructuralFeature); |
| } |
| if (eStructuralFeature.isUnsettable()) |
| { |
| if (!EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.IS_SET)) |
| { |
| String isSetAccessor = "isSet" + featureName; |
| EOperation eOperation = EcoreFactory.eINSTANCE.createEOperation(); |
| eOperation.setName(isSetAccessor); |
| eOperation.setEType(EcorePackage.Literals.EBOOLEAN); |
| implicitEOperationToEStructuralFeatureMap.put(eOperation, eStructuralFeature); |
| } |
| if (!EcoreUtil.isSuppressedVisibility(eStructuralFeature, EcoreUtil.UNSET)) |
| { |
| String unsetAccessor = "unset" + featureName; |
| EOperation eOperation = EcoreFactory.eINSTANCE.createEOperation(); |
| eOperation.setName(unsetAccessor); |
| implicitEOperationToEStructuralFeatureMap.put(eOperation, eStructuralFeature); |
| } |
| } |
| } |
| } |
| |
| result = |
| new EOperationSignatureValidator("_UI_EClassDisjointFeatureAndOperationSignatures_diagnostic", DISJOINT_FEATURE_AND_OPERATION_SIGNATURES, true) |
| { |
| @Override |
| protected EModelElement getTarget(EOperation otherEOperation) |
| { |
| return implicitEOperationToEStructuralFeatureMap.get(otherEOperation); |
| } |
| }.validateEOperationSignatures(eClass, eOperations, implicitEOperationToEStructuralFeatureMap.keySet(), diagnostics, context); |
| } |
| return result; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEClassifier(EClassifier eClassifier, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eClassifier, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eClassifier, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eClassifier, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eClassifier, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eClassifier, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eClassifier, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eClassifier, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eClassifier, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eClassifier, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eClassifier, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClassifier_WellFormedInstanceTypeName(eClassifier, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClassifier_UniqueTypeParameterNames(eClassifier, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the WellFormedInstanceTypeName constraint of '<em>EClassifier</em>'. |
| * <!-- begin-user-doc --> |
| * The instance type name may be null only for a class or an enum |
| * must be {@link EGenericTypeBuilder#parseInstanceTypeName(String) well formed} when not null, |
| * and must not specify type arguments if the classifier specifies type parameters. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEClassifier_WellFormedInstanceTypeName(EClassifier eClassifier, DiagnosticChain diagnostics, final Map<Object, Object> context) |
| { |
| String instanceTypeName = eClassifier.getInstanceTypeName(); |
| Diagnostic typeBuilderDiagnostic = |
| instanceTypeName == null ? |
| null : |
| new EGenericTypeBuilder() |
| { |
| @Override |
| protected BasicDiagnostic createDiagnostic(int severity, String source, int code, String messageKey, Object[] messageSubstitutions, Object[] data) |
| { |
| return EcoreValidator.this.createDiagnostic(severity, source, code, messageKey, messageSubstitutions, data, context); |
| } |
| |
| @Override |
| protected ResourceLocator getResourceLocator() |
| { |
| return EcoreValidator.this.getResourceLocator(); |
| } |
| |
| @Override |
| protected String getString(String key, Object[] substitutions) |
| { |
| return EcoreValidator.this.getString(key, substitutions); |
| } |
| |
| @Override |
| protected void report(DiagnosticChain diagnostics, String key, Object[] substitutions, int index) |
| { |
| EcoreValidator.this.report(diagnostics, key, substitutions, index, context); |
| } |
| }.parseInstanceTypeName(instanceTypeName); |
| String formattedName = null; |
| boolean result = |
| instanceTypeName != null ? |
| typeBuilderDiagnostic.getSeverity() == Diagnostic.OK && |
| instanceTypeName.equals(formattedName = EcoreUtil.toJavaInstanceTypeName((EGenericType)typeBuilderDiagnostic.getData().get(0))) : |
| eClassifier instanceof EClass || eClassifier instanceof EEnum; |
| if (!result && diagnostics != null) |
| { |
| BasicDiagnostic diagnosic = |
| createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_INSTANCE_TYPE_NAME, |
| "_UI_EClassifierInstanceTypeNameNotWellFormed_diagnostic", |
| new Object[] { getValueLabel(EcorePackage.Literals.ESTRING, instanceTypeName, context) }, |
| new Object[] { eClassifier, EcorePackage.Literals.ECLASSIFIER__INSTANCE_TYPE_NAME }, |
| context); |
| if (typeBuilderDiagnostic != null) |
| { |
| if (!typeBuilderDiagnostic.getChildren().isEmpty()) |
| { |
| diagnosic.addAll(typeBuilderDiagnostic); |
| } |
| else if (instanceTypeName != null && formattedName != null) |
| { |
| // The string must contain inappropriate whitespace, so find the index for the first difference. |
| // |
| int i = 0; |
| for (int length = Math.min(instanceTypeName.length(), formattedName.length()); |
| i < length; |
| i = Character.offsetByCodePoints(instanceTypeName, i, 1)) |
| { |
| if (instanceTypeName.codePointAt(i) != formattedName.codePointAt(i)) |
| { |
| break; |
| } |
| } |
| |
| diagnosic.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_INSTANCE_TYPE_NAME, |
| instanceTypeName.codePointAt(i) == ' ' ? "_UI_EClassifierInstanceTypeNameUnexpectedSpace_diagnostic" : "_UI_EClassifierInstanceTypeNameExpectedSpace_diagnostic", |
| new Object[] { i }, |
| new Object[] { i }, |
| context)); |
| } |
| } |
| diagnostics.add(diagnosic); |
| } |
| if (result && instanceTypeName != null && instanceTypeName.indexOf('<') != -1 && eClassifier.getETypeParameters().size() != 0) |
| { |
| result = false; |
| if (diagnostics != null) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_INSTANCE_TYPE_NAME, |
| "_UI_EClassifierInstanceTypeNameUnexpectedTypeArguments_diagnostic", |
| null, |
| new Object[] { eClassifier, EcorePackage.Literals.ECLASSIFIER__INSTANCE_TYPE_NAME }, |
| context)); |
| } |
| } |
| |
| return result; |
| } |
| |
| /** |
| * Validates the UniqueTypeParameterNames constraint of '<em>EClassifier</em>'. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEClassifier_UniqueTypeParameterNames(EClassifier eClassifier, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| Map<String, List<ETypeParameter>> keys = new HashMap<String, List<ETypeParameter>>(); |
| for (ETypeParameter eTypeParameter : eClassifier.getETypeParameters()) |
| { |
| String name = eTypeParameter.getName(); |
| if (name != null) |
| { |
| List<ETypeParameter> eTypeParameters = keys.get(name); |
| if (eTypeParameters == null) |
| { |
| eTypeParameters = new ArrayList<ETypeParameter>(); |
| keys.put(name, eTypeParameters); |
| } |
| eTypeParameters.add(eTypeParameter); |
| if (eTypeParameters.size() > 1) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| } |
| } |
| } |
| } |
| |
| if (!result && diagnostics != null) |
| { |
| for (Map.Entry<String, List<ETypeParameter>> entry : keys.entrySet()) |
| { |
| List<ETypeParameter> eTypeParameters = entry.getValue(); |
| if (eTypeParameters.size() > 1) |
| { |
| List<Object> objects = new ArrayList<Object>(); |
| objects.add(eClassifier); |
| for (ETypeParameter eTypeParameter : eTypeParameters) |
| { |
| objects.add(eTypeParameter); |
| } |
| objects.add(EcorePackage.Literals.ECLASSIFIER__ETYPE_PARAMETERS ); |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_TYPE_PARAMETER_NAMES, |
| "_UI_UniqueTypeParameterNames_diagnostic", |
| new Object[] { entry.getKey() }, |
| objects.toArray(new Object[objects.size()]), |
| context)); |
| |
| } |
| } |
| |
| } |
| return result; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEDataType(EDataType eDataType, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eDataType, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eDataType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eDataType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eDataType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eDataType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eDataType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eDataType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eDataType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eDataType, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eDataType, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClassifier_WellFormedInstanceTypeName(eDataType, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClassifier_UniqueTypeParameterNames(eDataType, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEEnum(EEnum eEnum, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eEnum, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClassifier_WellFormedInstanceTypeName(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEClassifier_UniqueTypeParameterNames(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEEnum_UniqueEnumeratorNames(eEnum, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEEnum_UniqueEnumeratorLiterals(eEnum, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the UniqueEnumeratorNames constraint of '<em>EEnum</em>'. |
| * <!-- begin-user-doc --> |
| * No two enum literals may have matching names. |
| * Literal names are matched ignoring their case and their underscore separators. |
| * It is an error to have two enum literals with names that are equal but only a warning to have two enum literals with names that match. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEEnum_UniqueEnumeratorNames(EEnum eEnum, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| EList<EEnumLiteral> eLiterals = eEnum.getELiterals(); |
| Map<String, List<EEnumLiteral>> keys = new HashMap<String, List<EEnumLiteral>>(); |
| for (EEnumLiteral eEnumLiteral : eLiterals) |
| { |
| String name = eEnumLiteral.getName(); |
| if (name != null) |
| { |
| String key = name.replace("_", "").toUpperCase(); |
| List<EEnumLiteral> eEnumLiterals = keys.get(key); |
| if (eEnumLiterals == null) |
| { |
| eEnumLiterals = new ArrayList<EEnumLiteral>(); |
| keys.put(key, eEnumLiterals); |
| } |
| eEnumLiterals.add(eEnumLiteral); |
| if (eEnumLiterals.size() > 1) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| } |
| } |
| } |
| } |
| |
| if (!result && diagnostics != null) |
| { |
| for (Map.Entry<String, List<EEnumLiteral>> entry : keys.entrySet()) |
| { |
| List<EEnumLiteral> eEnumLiterals = entry.getValue(); |
| if (eEnumLiterals.size() > 1) |
| { |
| List<String> names = new UniqueEList<String>(); |
| List<Object> objects = new ArrayList<Object>(); |
| objects.add(eEnum); |
| for (EEnumLiteral eEnumLiteral : eEnumLiterals) |
| { |
| names.add(eEnumLiteral.getName()); |
| objects.add(eEnumLiteral); |
| } |
| objects.add(EcorePackage.Literals.EENUM__ELITERALS); |
| |
| if (names.size() == objects.size() - 2) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.WARNING, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_ENUMERATOR_NAMES, |
| "_UI_EEnumDissimilarEnumeratorNames_diagnostic", |
| names.toArray(new Object[names.size()]), |
| objects.toArray(new Object[objects.size()]), |
| context)); |
| |
| } |
| else |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_ENUMERATOR_NAMES, |
| "_UI_EEnumUniqueEnumeratorNames_diagnostic", |
| new Object [] { names.get(0) }, |
| objects.toArray(new Object[objects.size()]), |
| context)); |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the UniqueEnumeratorLiterals constraint of '<em>EEnum</em>'. |
| * <!-- begin-user-doc --> |
| * No two enum literals may have the same literal value. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEEnum_UniqueEnumeratorLiterals(EEnum eEnum, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| EList<EEnumLiteral> eLiterals = eEnum.getELiterals(); |
| Map<String, List<EEnumLiteral>> keys = new HashMap<String, List<EEnumLiteral>>(); |
| for (EEnumLiteral eEnumLiteral : eLiterals) |
| { |
| String literal = eEnumLiteral.getLiteral(); |
| if (literal != null) |
| { |
| List<EEnumLiteral> eEnumLiterals = keys.get(literal); |
| if (eEnumLiterals == null) |
| { |
| eEnumLiterals = new ArrayList<EEnumLiteral>(); |
| keys.put(literal, eEnumLiterals); |
| } |
| eEnumLiterals.add(eEnumLiteral); |
| |
| if (eEnumLiterals.size() > 1) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| EEnumLiteral otherEEnumLiteral = eEnumLiterals.get(0); |
| // Don't complain about the literals if they are the same as the names and the names collide. |
| // |
| String name = eEnumLiteral.getName(); |
| if (name != null && name.equals(literal) & name.equals(otherEEnumLiteral.getName())) |
| { |
| eEnumLiterals.remove(eEnumLiteral); |
| } |
| } |
| } |
| } |
| } |
| |
| if (!result && diagnostics != null) |
| { |
| for (Map.Entry<String, List<EEnumLiteral>> entry : keys.entrySet()) |
| { |
| List<EEnumLiteral> eEnumLiterals = entry.getValue(); |
| if (eEnumLiterals.size() > 1) |
| { |
| List<Object> objects = new ArrayList<Object>(); |
| objects.add(eEnum); |
| for (EEnumLiteral eEnumLiteral : eEnumLiterals) |
| { |
| objects.add(eEnumLiteral); |
| } |
| objects.add(EcorePackage.Literals.EENUM__ELITERALS); |
| |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_ENUMERATOR_LITERALS, |
| "_UI_EEnumUniqueEnumeratorLiterals_diagnostic", |
| new Object[] { entry.getKey() }, |
| objects.toArray(new Object[objects.size()]), |
| context)); |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEEnumLiteral(EEnumLiteral eEnumLiteral, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eEnumLiteral, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eEnumLiteral, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eEnumLiteral, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eEnumLiteral, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eEnumLiteral, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eEnumLiteral, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eEnumLiteral, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eEnumLiteral, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eEnumLiteral, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eEnumLiteral, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEFactory(EFactory eFactory, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return validate_EveryDefaultConstraint(eFactory, diagnostics, context); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEModelElement(EModelElement eModelElement, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return validate_EveryDefaultConstraint(eModelElement, diagnostics, context); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateENamedElement(ENamedElement eNamedElement, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eNamedElement, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eNamedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eNamedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eNamedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eNamedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eNamedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eNamedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eNamedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eNamedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eNamedElement, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the WellFormedName constraint of '<em>ENamed Element</em>'. |
| * <!-- begin-user-doc --> |
| * The name must be a valid Java identifier. |
| * I.e., it must start with a {@link Character#isJavaIdentifierStart(int) Java identifier start character}, |
| * that is followed by zero or more {@link Character#isJavaIdentifierPart(int) Java identifier part characters}. |
| * This constraint is only enforced in a {@link #STRICT_NAMED_ELEMENT_NAMES} context. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateENamedElement_WellFormedName(ENamedElement eNamedElement, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (context != null && Boolean.FALSE.equals(context.get(STRICT_NAMED_ELEMENT_NAMES))) |
| { |
| return true; |
| } |
| |
| boolean result = false; |
| String name = eNamedElement.getName(); |
| if (name != null) |
| { |
| int length = name.length(); |
| if (length > 0) |
| { |
| int codePoint = name.codePointAt(0); |
| if (Character.isJavaIdentifierStart(codePoint) && codePoint != '$') |
| { |
| result = true; |
| for (int i = Character.offsetByCodePoints(name, 0, 1); i < length; i = Character.offsetByCodePoints(name, i, 1)) |
| { |
| codePoint = name.codePointAt(i); |
| if (codePoint == '$' || !Character.isJavaIdentifierPart(codePoint)) |
| { |
| result = false; |
| break; |
| } |
| } |
| } |
| } |
| } |
| |
| if (!result && diagnostics != null) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_NAME, |
| "_UI_ENamedElementNameNotWellFormed_diagnostic", |
| new Object[] { getValueLabel(EcorePackage.Literals.ESTRING, name, context) }, |
| new Object[] { eNamedElement, EcorePackage.Literals.ENAMED_ELEMENT__NAME }, |
| context)); |
| } |
| return result; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEObject(EObject eObject, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return validate_EveryDefaultConstraint(eObject, diagnostics, context); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEOperation(EOperation eOperation, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eOperation, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidLowerBound(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidUpperBound(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ConsistentBounds(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidType(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEOperation_UniqueParameterNames(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEOperation_UniqueTypeParameterNames(eOperation, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEOperation_NoRepeatingVoid(eOperation, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the UniqueParameterNames constraint of '<em>EOperation</em>'. |
| * <!-- begin-user-doc --> |
| * No two parameters may have the same name. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEOperation_UniqueParameterNames(EOperation eOperation, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| Map<String, List<EParameter>> keys = new HashMap<String, List<EParameter>>(); |
| for (EParameter eParameter : eOperation.getEParameters()) |
| { |
| String name = eParameter.getName(); |
| if (name != null) |
| { |
| List<EParameter> eParameters = keys.get(name); |
| if (eParameters == null) |
| { |
| eParameters = new ArrayList<EParameter>(); |
| keys.put(name, eParameters); |
| } |
| eParameters.add(eParameter); |
| if (eParameters.size() > 1) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| } |
| } |
| } |
| } |
| |
| if (!result && diagnostics != null) |
| { |
| for (Map.Entry<String, List<EParameter>> entry : keys.entrySet()) |
| { |
| List<EParameter> eParameters = entry.getValue(); |
| if (eParameters.size() > 1) |
| { |
| List<Object> objects = new ArrayList<Object>(); |
| objects.add(eOperation); |
| for (EParameter eParameter : eParameters) |
| { |
| objects.add(eParameter); |
| } |
| objects.add(EcorePackage.Literals.EOPERATION__EPARAMETERS); |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_PARAMETER_NAMES, |
| "_UI_EOperationUniqueParameterNames_diagnostic", |
| new Object[] { entry.getKey() }, |
| objects.toArray(new Object[objects.size()]), |
| context)); |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the UniqueTypeParameterNames constraint of '<em>EOperation</em>'. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEOperation_UniqueTypeParameterNames(EOperation eOperation, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| Map<String, List<ETypeParameter>> keys = new HashMap<String, List<ETypeParameter>>(); |
| for (ETypeParameter eTypeParameter : eOperation.getETypeParameters()) |
| { |
| String name = eTypeParameter.getName(); |
| if (name != null) |
| { |
| List<ETypeParameter> eTypeParameters = keys.get(name); |
| if (eTypeParameters == null) |
| { |
| eTypeParameters = new ArrayList<ETypeParameter>(); |
| keys.put(name, eTypeParameters); |
| } |
| eTypeParameters.add(eTypeParameter); |
| if (eTypeParameters.size() > 1) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| } |
| } |
| } |
| } |
| |
| if (!result && diagnostics != null) |
| { |
| for (Map.Entry<String, List<ETypeParameter>> entry : keys.entrySet()) |
| { |
| List<ETypeParameter> eTypeParameters = entry.getValue(); |
| if (eTypeParameters.size() > 1) |
| { |
| List<Object> objects = new ArrayList<Object>(); |
| objects.add(eOperation); |
| for (ETypeParameter eTypeParameter : eTypeParameters) |
| { |
| objects.add(eTypeParameter); |
| } |
| objects.add(EcorePackage.Literals.EOPERATION__ETYPE_PARAMETERS ); |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_TYPE_PARAMETER_NAMES, |
| "_UI_UniqueTypeParameterNames_diagnostic", |
| new Object[] { entry.getKey() }, |
| objects.toArray(new Object[objects.size()]), |
| context)); |
| |
| } |
| } |
| |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the NoRepeatingVoid constraint of '<em>EOperation</em>'. |
| * <!-- begin-user-doc --> |
| * An operation without a type, which represents void, must have an upper bound of 1. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEOperation_NoRepeatingVoid(EOperation eOperation, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| int upperBound = eOperation.getUpperBound(); |
| boolean result = upperBound == 1 || eOperation.getEType() != null; |
| if (!result && diagnostics != null) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| NO_REPEATING_VOID, |
| "_UI_EOperationNoRepeatingVoid_diagnostic", |
| new Object [] { upperBound }, |
| new Object[] { eOperation, EcorePackage.Literals.ETYPED_ELEMENT__UPPER_BOUND }, |
| context)); |
| } |
| return result; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEPackage(EPackage ePackage, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(ePackage, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEPackage_WellFormedNsURI(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEPackage_WellFormedNsPrefix(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEPackage_UniqueSubpackageNames(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEPackage_UniqueClassifierNames(ePackage, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEPackage_UniqueNsURIs(ePackage, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the WellFormedNsURI constraint of '<em>EPackage</em>'. |
| * <!-- begin-user-doc --> |
| * The namespace URI must be {@link #isWellFormedURI(String) well formed} and may not be <code>null</code>. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEPackage_WellFormedNsURI(EPackage ePackage, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| String nsURI = ePackage.getNsURI(); |
| boolean result = isWellFormedURI(nsURI); |
| if (!result && diagnostics != null) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_NS_URI, |
| "_UI_EPackageNsURINotWellFormed_diagnostic", |
| new Object[] { nsURI }, |
| new Object[] { ePackage, EcorePackage.Literals.EPACKAGE__NS_URI }, |
| context)); |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the WellFormedNsPrefix constraint of '<em>EPackage</em>'. |
| * <!-- begin-user-doc --> |
| * The namespace prefix must be either the empty string |
| * or a {@link XMLTypeValidator#validateNCName(String, DiagnosticChain, Map) valid NCName} |
| * that does not start with any case combination of the three letters |
| * <a href="http://www.w3.org/TR/REC-xml-names/#xmlReserved">"xml"</a>. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEPackage_WellFormedNsPrefix(EPackage ePackage, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| String nsPrefix = ePackage.getNsPrefix(); |
| boolean |
| result = "".equals(nsPrefix) || |
| nsPrefix != null && |
| XMLTypeValidator.INSTANCE.validateNCName(nsPrefix, null, context) && |
| (!nsPrefix.toLowerCase().startsWith("xml") || XMLNamespacePackage.eNS_URI.equals(ePackage.getNsURI())); |
| if (!result && diagnostics != null) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_NS_PREFIX, |
| "_UI_EPackageNsPrefixNotWellFormed_diagnostic", |
| new Object[] { nsPrefix }, |
| new Object[] { ePackage, EcorePackage.Literals.EPACKAGE__NS_PREFIX }, |
| context)); |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the UniqueSubpackageNames constraint of '<em>EPackage</em>'. |
| * <!-- begin-user-doc --> |
| * No two packages my have the same name. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEPackage_UniqueSubpackageNames(EPackage ePackage, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| Map<String, List<EPackage>> keys = new HashMap<String, List<EPackage>>(); |
| for (EPackage eSubpackage : ePackage.getESubpackages()) |
| { |
| String name = eSubpackage.getName(); |
| if (name != null) |
| { |
| List<EPackage> eSubpackages = keys.get(name); |
| if (eSubpackages == null) |
| { |
| eSubpackages = new ArrayList<EPackage>(); |
| keys.put(name, eSubpackages); |
| } |
| eSubpackages.add(eSubpackage); |
| if (eSubpackages.size() > 1) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| } |
| } |
| } |
| } |
| |
| if (!result && diagnostics != null) |
| { |
| for (Map.Entry<String, List<EPackage>> entry : keys.entrySet()) |
| { |
| List<EPackage> eSubpackages = entry.getValue(); |
| if (eSubpackages.size() > 1) |
| { |
| List<Object> objects = new ArrayList<Object>(); |
| objects.add(ePackage); |
| for (EPackage eSubpackage : eSubpackages) |
| { |
| objects.add(eSubpackage); |
| } |
| objects.add(EcorePackage.Literals.EPACKAGE__ESUBPACKAGES); |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_SUBPACKAGE_NAMES, |
| "_UI_EPackageUniqueSubpackageNames_diagnostic", |
| new Object[] { entry.getKey() }, |
| objects.toArray(new Object[objects.size()]), |
| context)); |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the UniqueClassifierNames constraint of '<em>EPackage</em>'. |
| * <!-- begin-user-doc --> |
| * No two classifiers may have matching names. |
| * Classifier names are matched ignoring their case and their underscore separators. |
| * It is an error to have two classifier with names that are equal but only a warning to have two classifiers with names that match. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEPackage_UniqueClassifierNames(EPackage ePackage, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| Map<String, List<EClassifier>> keys = new HashMap<String, List<EClassifier>>(); |
| for (EClassifier eClassifier : ePackage.getEClassifiers()) |
| { |
| String name = eClassifier.getName(); |
| |
| // Don't bother complaining about things with no name, since there are constraints for that problem. |
| // |
| if (name != null) |
| { |
| // Drop the _ separators and normalize the case. |
| // |
| String key = name.replace("_", "").toLowerCase(); |
| List<EClassifier> eClassifiers = keys.get(key); |
| if (eClassifiers == null) |
| { |
| eClassifiers = new ArrayList<EClassifier>(); |
| keys.put(key, eClassifiers); |
| } |
| eClassifiers.add(eClassifier); |
| |
| if (eClassifiers.size() > 1) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| } |
| } |
| } |
| } |
| |
| if (!result && diagnostics != null) |
| { |
| for (Map.Entry<String, List<EClassifier>> entry : keys.entrySet()) |
| { |
| List<EClassifier> eClassifiers = entry.getValue(); |
| if (eClassifiers.size() > 1) |
| { |
| List<String> names = new UniqueEList<String>(); |
| List<Object> objects = new ArrayList<Object>(); |
| objects.add(ePackage); |
| for (EClassifier eClassifier : eClassifiers) |
| { |
| names.add(eClassifier.getName()); |
| objects.add(eClassifier); |
| } |
| objects.add(EcorePackage.Literals.EPACKAGE__ECLASSIFIERS); |
| |
| if (names.size() == objects.size() - 2) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.WARNING, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_CLASSIFIER_NAMES, |
| "_UI_EPackageDissimilarClassifierNames_diagnostic", |
| names.toArray(new Object[names.size()]), |
| objects.toArray(new Object[objects.size()]), |
| context)); |
| |
| } |
| else |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_CLASSIFIER_NAMES, |
| "_UI_EPackageUniqueClassifierNames_diagnostic", |
| new Object [] { names.get(0) }, |
| objects.toArray(new Object[objects.size()]), |
| context)); |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the UniqueNsURIs constraint of '<em>EPackage</em>'. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEPackage_UniqueNsURIs(EPackage ePackage, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| String nsURI = ePackage.getNsURI(); |
| if (nsURI != null) |
| { |
| EPackage rootEPackage = ePackage; |
| for (EPackage eSuperPackage = ePackage.getESuperPackage(); eSuperPackage != null; eSuperPackage = eSuperPackage.getESuperPackage()) |
| { |
| rootEPackage = eSuperPackage; |
| } |
| |
| UniqueEList<EPackage> ePackages = new UniqueEList.FastCompare<EPackage>(); |
| ePackages.add(rootEPackage); |
| for (int i = 0; i < ePackages.size(); ++i) |
| { |
| ePackages.addAll(ePackages.get(i).getESubpackages()); |
| } |
| ePackages.remove(ePackage); |
| |
| for (EPackage otherEPackage : ePackages) |
| { |
| if (nsURI.equals(otherEPackage.getNsURI())) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| UNIQUE_NS_URIS, |
| "_UI_EPackageUniqueNsURIs_diagnostic", |
| new Object[] { nsURI }, |
| new Object[] { ePackage, otherEPackage, EcorePackage.Literals.EPACKAGE__ESUBPACKAGES }, |
| context)); |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEParameter(EParameter eParameter, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eParameter, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidLowerBound(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidUpperBound(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ConsistentBounds(eParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidType(eParameter, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEReference(EReference eReference, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eReference, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidLowerBound(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidUpperBound(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ConsistentBounds(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidType(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEStructuralFeature_ValidDefaultValueLiteral(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEReference_ConsistentOpposite(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEReference_SingleContainer(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEReference_ConsistentKeys(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEReference_ConsistentUnique(eReference, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEReference_ConsistentContainer(eReference, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the ConsistentOpposite constraint of '<em>EReference</em>'. |
| * <!-- begin-user-doc --> |
| * An {@link EReference#getEOpposite() opposite} is optional but if one exists, |
| * it must be a feature of this references's {@link EReference#getEReferenceType() type}, |
| * it must have this reference as its opposite, |
| * and, if this feature is {@link EStructuralFeature#isTransient() transient}, |
| * then the opposite must also be transient, |
| * must not {@link EReference#isResolveProxies() resolve proxies}. |
| * or must be a {@link EReference#isContainment() containment}, |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEReference_ConsistentOpposite(EReference eReference, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| EReference eOpposite = eReference.getEOpposite(); |
| if (eOpposite != null) |
| { |
| if (eReference.getEContainingClass() != null) |
| { |
| EReference oppositeEOpposite = eOpposite.getEOpposite(); |
| if (oppositeEOpposite != eReference) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_OPPOSITE_NOT_MATCHING, |
| "_UI_EReferenceOppositeOfOppositeInconsistent_diagnostic", |
| null, |
| new Object[] { eReference, eOpposite, oppositeEOpposite, EcorePackage.Literals.EREFERENCE__EOPPOSITE }, |
| context)); |
| } |
| } |
| EClassifier eType = eReference.getEType(); |
| if (eType != null) |
| { |
| EClass oppositeEContainingClass = eOpposite.getEContainingClass(); |
| if (oppositeEContainingClass != null && oppositeEContainingClass != eType) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_OPPOSITE_NOT_FROM_TYPE, |
| "_UI_EReferenceOppositeNotFeatureOfType_diagnostic", |
| null, |
| new Object[] { eReference, eOpposite, eType, EcorePackage.Literals.EREFERENCE__EOPPOSITE }, |
| context)); |
| } |
| } |
| } |
| } |
| if (result) |
| { |
| result = eReference != eOpposite; |
| if (diagnostics != null && !result) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_OPPOSITE_BAD_TRANSIENT, |
| "_UI_EReferenceSelfOpposite_diagnostic", |
| null, |
| new Object[] { eReference, eOpposite, EcorePackage.Literals.EREFERENCE__EOPPOSITE, EcorePackage.Literals.EREFERENCE__EOPPOSITE }, |
| context)); |
| } |
| } |
| if (result) |
| { |
| result = |
| !isEffectivelyTransient(eReference) || |
| isEffectivelyTransient(eOpposite) || |
| !eOpposite.isResolveProxies() || |
| eOpposite.isContainment(); |
| if (diagnostics != null && !result) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_OPPOSITE_BAD_TRANSIENT, |
| "_UI_EReferenceTransientOppositeNotTransient_diagnostic", |
| null, |
| new Object[] { eReference, eOpposite, EcorePackage.Literals.EREFERENCE__EOPPOSITE, EcorePackage.Literals.ESTRUCTURAL_FEATURE__TRANSIENT }, |
| context)); |
| } |
| } |
| if (result) |
| { |
| result = !eReference.isContainment() || !eOpposite.isContainment(); |
| if (diagnostics != null && !result) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_OPPOSITE_BOTH_CONTAINMENT, |
| "_UI_EReferenceOppositeBothContainment_diagnostic", |
| null, |
| new Object[] { eReference, eOpposite, EcorePackage.Literals.EREFERENCE__EOPPOSITE, EcorePackage.Literals.EREFERENCE__CONTAINMENT }, |
| context)); |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the SingleContainer constraint of '<em>EReference</em>'. |
| * <!-- begin-user-doc --> |
| * A {@link EReference#isContainer() container} reference must have a upper bound of 1. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEReference_SingleContainer(EReference eReference, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = !eReference.isContainer() || eReference.getUpperBound() == 1; |
| if (diagnostics != null && !result) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| SINGLE_CONTAINER, |
| "_UI_EReferenceSingleContainer_diagnostic", |
| new Object[] { eReference.getUpperBound() }, |
| new Object[] { eReference, EcorePackage.Literals.ETYPED_ELEMENT__UPPER_BOUND }, |
| context)); |
| } |
| return result; |
| } |
| |
| |
| /** |
| * Validates the ConsistentKeys constraint of '<em>EReference</em>'. |
| * <!-- begin-user-doc --> |
| * The {@link EReference#getEKeys() keys} of a reference must be features of the reference's {@link ETypedElement#getEType()}. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEReference_ConsistentKeys(EReference eReference, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| EList<EAttribute> eKeys = eReference.getEKeys(); |
| if (!eKeys.isEmpty()) |
| { |
| EClass eClass = eReference.getEReferenceType(); |
| if (eClass != null) |
| { |
| for (EAttribute eAttribute :eKeys) |
| { |
| if (eClass.getFeatureID(eAttribute) == -1) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_KEYS, |
| "_UI_EReferenceConsistentKeys_diagnostic", |
| new Object[] { getObjectLabel(eAttribute, context) }, |
| new Object[] { eReference, eAttribute, EcorePackage.Literals.EREFERENCE__EKEYS }, |
| context)); |
| } |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the ConsistentUnique constraint of '<em>EReference</em>'. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEReference_ConsistentUnique(EReference eReference, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| // Multi-valued references that are containment or bidirectional must be unique. |
| // |
| boolean result = true; |
| if (eReference.isMany() && |
| (eReference.isContainment() || eReference.getEOpposite() != null) && |
| !eReference.isUnique()) |
| { |
| result = false; |
| if (diagnostics != null) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_UNIQUE, |
| "_UI_EReferenceConsistentUnique_diagnostic", |
| null, |
| new Object[] { eReference, EcorePackage.Literals.ETYPED_ELEMENT__UNIQUE }, |
| context)); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the ConsistentContainer constraint of '<em>EReference</em>'. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEReference_ConsistentContainer(EReference eReference, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (eReference.isContainment() && eReference.getEContainingClass() != null) |
| { |
| EClass eClass = eReference.getEReferenceType(); |
| if (eClass != null) |
| { |
| for (EReference otherEReference : eClass.getEAllReferences()) |
| { |
| if (otherEReference.isRequired() && otherEReference.isContainer() && otherEReference.getEOpposite() != eReference) |
| { |
| if (diagnostics != null) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_CONTAINER, |
| "_UI_EReferenceConsistentContainer_diagnostic", |
| new Object[] { getObjectLabel(otherEReference, context) }, |
| new Object[] { eReference, otherEReference, EcorePackage.Literals.ETYPED_ELEMENT__LOWER_BOUND }, |
| context)); |
| } |
| return false; |
| } |
| } |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEStructuralFeature(EStructuralFeature eStructuralFeature, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eStructuralFeature, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidLowerBound(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidUpperBound(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ConsistentBounds(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidType(eStructuralFeature, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEStructuralFeature_ValidDefaultValueLiteral(eStructuralFeature, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the ValidDefaultValueLiteral constraint of '<em>EStructural Feature</em>'. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEStructuralFeature_ValidDefaultValueLiteral(EStructuralFeature eStructuralFeature, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| String defaultValueLiteral = eStructuralFeature.getDefaultValueLiteral(); |
| Object defaultValue = null; |
| EDataType eDataType = null; |
| boolean result = true; |
| boolean warning = false; |
| if (defaultValueLiteral != null) |
| { |
| EClassifier eType = eStructuralFeature.getEType(); |
| if (eType instanceof EDataType) |
| { |
| eDataType = (EDataType)eType; |
| defaultValue = eStructuralFeature.getDefaultValue(); |
| if (defaultValue == null) |
| { |
| // We need to be conservative and diagnose a problem only if we are quite sure that type is built-in |
| // and hence that the lack of a default value really represents a problem with being unable to convert the literal to a value dynamically, |
| // not just a problem that the specialized factory conversion logic hasn't been generated yet. |
| // |
| if (isBuiltinEDataType(eDataType)) |
| { |
| result = false; |
| } |
| else |
| { |
| // If there is a conversion delegate then the lack of a default value really does indicate that there is a problem converting the literal to a value, |
| // unless there is no instance class, in which case we mustn't be able to load the class and we can't expect the conversion delegate to function. |
| // |
| EDataType.Internal.ConversionDelegate conversionDelegate = ((EDataType.Internal)eDataType).getConversionDelegate(); |
| if (conversionDelegate != null && eDataType.getInstanceClass() != null) |
| { |
| result = false; |
| } |
| else |
| { |
| // If the data type is an enum or derives from an enum |
| // then it's unlikely there is ever specialized code for converting the value |
| // so probably the literal is bad and we should at least produce a warning. |
| // |
| EEnum eEnum = getEEnum(eDataType); |
| if (eEnum != null) |
| { |
| result = false; |
| warning = true; |
| } |
| } |
| } |
| } |
| else |
| { |
| result = getRootEValidator(context).validate(eDataType, defaultValue, null, context); |
| } |
| } |
| else |
| { |
| result = false; |
| } |
| } |
| if (diagnostics != null && !result) |
| { |
| BasicDiagnostic diagnostic = |
| createDiagnostic |
| (warning? Diagnostic.WARNING : Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| VALID_DEFAULT_VALUE_LITERAL, |
| "_UI_EStructuralFeatureValidDefaultValueLiteral_diagnostic", |
| new Object[] { defaultValueLiteral }, |
| new Object[] { eStructuralFeature, EcorePackage.Literals.ESTRUCTURAL_FEATURE__DEFAULT_VALUE_LITERAL }, |
| context); |
| if (defaultValue != null) |
| { |
| getRootEValidator(context).validate(eDataType, defaultValue, diagnostic, context); |
| } |
| diagnostics.add(diagnostic); |
| } |
| return result; |
| } |
| |
| private EEnum getEEnum(EDataType eDataType) |
| { |
| if (eDataType instanceof EEnum) |
| { |
| return (EEnum)eDataType; |
| } |
| |
| EDataType baseType = ExtendedMetaData.INSTANCE.getBaseType(eDataType); |
| if (baseType != null) |
| { |
| return getEEnum(baseType); |
| } |
| |
| return null; |
| } |
| |
| protected boolean isBuiltinEDataType(EDataType eDataType) |
| { |
| EPackage ePackage = eDataType.getEPackage(); |
| if (ePackage == EcorePackage.eINSTANCE || ePackage == XMLTypePackage.eINSTANCE || ePackage == XMLNamespacePackage.eINSTANCE) |
| { |
| return true; |
| } |
| |
| EDataType baseType = ExtendedMetaData.INSTANCE.getBaseType(eDataType); |
| if (baseType != null) |
| { |
| return isBuiltinEDataType(baseType); |
| } |
| |
| EDataType itemType = ExtendedMetaData.INSTANCE.getItemType(eDataType); |
| if (itemType != null) |
| { |
| return isBuiltinEDataType(itemType); |
| } |
| |
| List<EDataType> memberTypes = ExtendedMetaData.INSTANCE.getMemberTypes(eDataType); |
| if (!memberTypes.isEmpty()) |
| { |
| for (EDataType memberType : memberTypes) |
| { |
| if (!isBuiltinEDataType(memberType)) |
| { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateETypedElement(ETypedElement eTypedElement, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eTypedElement, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidLowerBound(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidUpperBound(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ConsistentBounds(eTypedElement, diagnostics, context); |
| if (result || diagnostics != null) result &= validateETypedElement_ValidType(eTypedElement, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the ValidLowerBound constraint of '<em>ETyped Element</em>'. |
| * <!-- begin-user-doc --> |
| * The {@link ETypedElement#getLowerBound() lower bound} must be greater or equal to 0 |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateETypedElement_ValidLowerBound(ETypedElement eTypedElement, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| int lowerBound = eTypedElement.getLowerBound(); |
| boolean result = lowerBound >= 0; |
| if (diagnostics != null && !result) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| VALID_LOWER_BOUND, |
| "_UI_ETypedElementValidLowerBound_diagnostic", |
| new Object[] { lowerBound }, |
| new Object[] { eTypedElement, EcorePackage.Literals.ETYPED_ELEMENT__LOWER_BOUND }, |
| context)); |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the ValidUpperBound constraint of '<em>ETyped Element</em>'. |
| * <!-- begin-user-doc --> |
| * The {@link ETypedElement#getUpperBound() upper bound} must be either |
| * {@link ETypedElement#UNBOUNDED_MULTIPLICITY}, |
| * {@link ETypedElement#UNSPECIFIED_MULTIPLICITY}, |
| * or greater than 0. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateETypedElement_ValidUpperBound(ETypedElement eTypedElement, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| int upperBound = eTypedElement.getUpperBound(); |
| boolean result = |
| upperBound > 0 || |
| upperBound == ETypedElement.UNSPECIFIED_MULTIPLICITY || |
| upperBound == ETypedElement.UNBOUNDED_MULTIPLICITY; |
| if (diagnostics != null && !result) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| VALID_UPPER_BOUND, |
| "_UI_ETypedElementValidUpperBound_diagnostic", |
| new Object[] { upperBound }, |
| new Object[] { eTypedElement, EcorePackage.Literals.ETYPED_ELEMENT__UPPER_BOUND }, |
| context)); |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the ConsistentBounds constraint of '<em>ETyped Element</em>'. |
| * <!-- begin-user-doc --> |
| * The {@link ETypedElement#getLowerBound() lower bound} must be less than or equal to the {@link ETypedElement#getUpperBound() upper bound}, |
| * unless the upper bound is one of the two special values |
| * {@link ETypedElement#UNBOUNDED_MULTIPLICITY} or {@link ETypedElement#UNSPECIFIED_MULTIPLICITY}. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateETypedElement_ConsistentBounds(ETypedElement eTypedElement, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| int lowerBound = eTypedElement.getLowerBound(); |
| int upperBound = eTypedElement.getUpperBound(); |
| boolean result = upperBound < 0 || lowerBound <= upperBound; |
| if (diagnostics != null && !result) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_BOUNDS, |
| "_UI_ETypedElementConsistentBounds_diagnostic", |
| new Object[] { lowerBound, upperBound }, |
| new Object[] { eTypedElement,EcorePackage.Literals.ETYPED_ELEMENT__LOWER_BOUND, EcorePackage.Literals.ETYPED_ELEMENT__UPPER_BOUND }, |
| context)); |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the ValidType constraint of '<em>ETyped Element</em>'. |
| * <!-- begin-user-doc --> |
| * The {@link ETypedElement#getEGenericType() type} may be <code>null</code> only if this in an {@link EOperation operation}. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateETypedElement_ValidType(ETypedElement eTypedElement, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| EGenericType eGenericType = eTypedElement.getEGenericType(); |
| if (eGenericType == null && !(eTypedElement instanceof EOperation)) |
| { |
| result = false; |
| if (diagnostics != null) |
| { |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| VALID_TYPE, |
| "_UI_ETypedElementNoType_diagnostic", |
| null, |
| new Object[] { eTypedElement, EcorePackage.Literals.ETYPED_ELEMENT__ETYPE }, |
| context)); |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEStringToStringMapEntry(Map.Entry<?, ?> eStringToStringMapEntry, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return validate_EveryDefaultConstraint((EObject)eStringToStringMapEntry, diagnostics, context); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEGenericType(EGenericType eGenericType, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eGenericType, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eGenericType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eGenericType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eGenericType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eGenericType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eGenericType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eGenericType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eGenericType, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eGenericType, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEGenericType_ConsistentType(eGenericType, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEGenericType_ConsistentBounds(eGenericType, diagnostics, context); |
| if (result || diagnostics != null) result &= validateEGenericType_ConsistentArguments(eGenericType, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * Validates the ConsistentType constraint of '<em>EGeneric Type</em>'. |
| * <!-- begin-user-doc --> |
| * A generic type must not reference both a {@link EGenericType#getEClassifier() classifier} |
| * and a {@link EGenericType#getETypeParameter() type parameter}. |
| * The referenced type parameter must be in scope, i.e., |
| * its {@link EObject#eContainer()} must be an {@link EcoreUtil#isAncestor(EObject, EObject)} of this generic type. |
| * A generic type used as a {@link EClass#getEGenericSuperTypes() generic super type} |
| * must have a classifier that refers to a {@link EClass class}. |
| * A generic type used as a {@link EGenericType#getETypeArguments() type argument} of a generic type used as a generic super type |
| * must specify either a classifier or a type parameter, i.e., it can't be a wildcard. |
| * A generic type may omit both the classifier and the type argument to act as a wildcard |
| * only when used as a type argument of some generic type, |
| * with the above exception. |
| * If present, the classifier of generic type used as the {@link ETypedElement#getEType() type} of an {@link EAttribute attribute} |
| * must be a {@link EDataType data type}. |
| * If present, the classifier of generic type used as the type of a {@link EReference reference} |
| * must be a class. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEGenericType_ConsistentType(EGenericType eGenericType, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| |
| ETypeParameter eTypeParameter = eGenericType.getETypeParameter(); |
| EClassifier eClassifier = eGenericType.getEClassifier(); |
| if (eTypeParameter != null) |
| { |
| if (eClassifier != null) |
| { |
| // Can't have both a classifier and a type parameter. |
| // |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_TYPE_NO_TYPE_PARAMETER_AND_CLASSIFIER, |
| "_UI_EGenericTypeNoTypeParameterAndClassifier_diagnostic", |
| null, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ECLASSIFIER, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_PARAMETER }, |
| context)); |
| } |
| } |
| |
| // The referencing generic type must be contained to be in scope |
| // |
| EObject scope = eTypeParameter.eContainer(); |
| boolean inScope = EcoreUtil.isAncestor(scope, eGenericType); |
| if (inScope) |
| { |
| // And even if it is contained, it must not be a forward reference. |
| // eTypeParameterIndex == index is allowed when the type parameter is |
| // the type argument of the bound, though, |
| // i.e., when the type argument is not nested directly as a child of the type parameter. |
| // |
| List<?> typeParameters = (List<?>)scope.eGet(eTypeParameter.eContainmentFeature()); |
| EObject usage = eGenericType; |
| for (EObject container = usage.eContainer(); container != scope; container = container.eContainer()) |
| { |
| usage = container; |
| } |
| int index = typeParameters.indexOf(usage); |
| int eTypeParameterIndex = typeParameters.indexOf(eTypeParameter); |
| inScope = index == -1 || |
| index > eTypeParameterIndex || |
| eGenericType.eContainingFeature() != EcorePackage.Literals.ETYPE_PARAMETER__EBOUNDS; |
| } |
| |
| if (!inScope) |
| { |
| // The type parameter must be in scope and must not be a forward reference. |
| // |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_TYPE_TYPE_PARAMETER_NOT_IN_SCOPE, |
| "_UI_EGenericTypeOutOfScopeTypeParameter_diagnostic", |
| null, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_PARAMETER }, |
| context)); |
| } |
| } |
| } |
| |
| EReference eContainmentFeature = eGenericType.eContainmentFeature(); |
| if (eContainmentFeature == EcorePackage.Literals.ECLASS__EGENERIC_SUPER_TYPES) |
| { |
| // When used as a generic super type, there must be a classifier that refers to a class. |
| // |
| if (!(eGenericType.getEClassifier() instanceof EClass)) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_TYPE_CLASS_REQUIRED, |
| "_UI_EGenericTypeNoClass_diagnostic", |
| null, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ECLASSIFIER }, |
| context)); |
| } |
| } |
| } |
| else if (eContainmentFeature == EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS) |
| { |
| if (eGenericType.eContainer().eContainmentFeature() == EcorePackage.Literals.ECLASS__EGENERIC_SUPER_TYPES) |
| { |
| // The type arguments of a generic super type must not be a wildcard. |
| // |
| if (eClassifier == null && eTypeParameter == null) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_TYPE_WILDCARD_NOT_PERMITTED, |
| "_UI_EGenericTypeNoTypeParameterOrClassifier_diagnostic", |
| null, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ECLASSIFIER, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_PARAMETER }, |
| context)); |
| } |
| } |
| } |
| } |
| else if (eContainmentFeature != null) |
| { |
| // Wildcards are only allowed in type arguments. |
| // |
| if (eClassifier == null && eTypeParameter == null) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_TYPE_WILDCARD_NOT_PERMITTED, |
| "_UI_EGenericTypeNoTypeParameterOrClassifier_diagnostic", |
| null, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ECLASSIFIER, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_PARAMETER }, |
| context)); |
| } |
| } |
| else if (eClassifier != null) |
| { |
| EObject eContainer = eGenericType.eContainer(); |
| if (eContainer instanceof EStructuralFeature) |
| { |
| if (eClassifier instanceof EClass) |
| { |
| if (eContainer instanceof EAttribute) |
| { |
| // The classifier of an attribute's generic type must be a data type. |
| // |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_TYPE_CLASS_NOT_PERMITTED, |
| "_UI_EAttributeNoDataType_diagnostic", |
| null, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ECLASSIFIER }, |
| context)); |
| } |
| } |
| } |
| else if (eClassifier instanceof EDataType) |
| { |
| if (eContainer instanceof EReference) |
| { |
| // The classifier of an references's generic type must be a class. |
| // |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_TYPE_DATA_TYPE_NOT_PERMITTED, |
| "_UI_EReferenceNoClass_diagnostic", |
| null, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ECLASSIFIER }, |
| context)); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| if (eClassifier != null && eContainmentFeature != null && eContainmentFeature != EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE) |
| { |
| // A primitive type can only be used as the generic type of a typed element. |
| // |
| String instanceClassName = eClassifier.getInstanceClassName(); |
| if (instanceClassName == "boolean" || |
| instanceClassName == "byte" || |
| instanceClassName == "char" || |
| instanceClassName == "double" || |
| instanceClassName == "float" || |
| instanceClassName == "int" || |
| instanceClassName == "long" || |
| instanceClassName == "short") |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_TYPE_PRIMITIVE_TYPE_NOT_PERMITTED, |
| "_UI_EGenericTypeInvalidPrimitiveType_diagnostic", |
| new Object[] { instanceClassName }, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ECLASSIFIER }, |
| context)); |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the ConsistentBounds constraint of '<em>EGeneric Type</em>'. |
| * <!-- begin-user-doc --> |
| * A generic type may have bounds only when used as a {@link EGenericType#getETypeArguments() type argument}. |
| * A generic type may not have both a {@link EGenericType#getELowerBound() lower} and an {@link EGenericType#getEUpperBound() upper bound}. |
| * A generic type may not have bounds |
| * as well as a {@link EGenericType#getEClassifier() classifier} or a {@link EGenericType#getETypeParameter() type parameter}. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEGenericType_ConsistentBounds(EGenericType eGenericType, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| |
| EGenericType eLowerBound = eGenericType.getELowerBound(); |
| EGenericType eUpperBound = eGenericType.getEUpperBound(); |
| if (eLowerBound != null || eUpperBound != null) |
| { |
| EStructuralFeature eContainmentFeature = eGenericType.eContainmentFeature(); |
| if (eContainmentFeature == EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS) |
| { |
| // Can't have both an upper and lower bound. |
| // |
| if (eLowerBound != null && eUpperBound != null) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_BOUNDS_NO_LOWER_AND_UPPER, |
| "_UI_EGenericTypeNoUpperAndLowerBound_diagnostic", |
| null, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ELOWER_BOUND, EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND }, |
| context)); |
| } |
| } |
| |
| // Can't have a classifier or a type parameter as well as bounds. |
| // |
| if (eGenericType.getEClassifier() != null || eGenericType.getETypeParameter() != null) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_BOUNDS_NO_BOUNDS_WITH_TYPE_PARAMETER_OR_CLASSIFIER, |
| "_UI_EGenericTypeNoTypeParameterOrClassifierAndBound_diagnostic", |
| null, |
| new Object[] { eGenericType, eGenericType.getEClassifier() != null ? EcorePackage.Literals.EGENERIC_TYPE__ECLASSIFIER : EcorePackage.Literals.EGENERIC_TYPE__ETYPE_PARAMETER }, |
| context)); |
| } |
| } |
| } |
| else |
| { |
| // Can only have bounds when used as a type argument. |
| // |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_BOUNDS_NOT_ALLOWED, |
| "_UI_EGenericTypeBoundsOnlyForTypeArgument_diagnostic", |
| null, |
| new Object[] { eGenericType, eLowerBound != null ? EcorePackage.Literals.EGENERIC_TYPE__ELOWER_BOUND : EcorePackage.Literals.EGENERIC_TYPE__EUPPER_BOUND }, |
| context)); |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Validates the ConsistentArguments constraint of '<em>EGeneric Type</em>'. |
| * <!-- begin-user-doc --> |
| * A generic type can have {@link EGenericType#getETypeArguments() type arguments} |
| * only if it has a {@link EGenericType#getEClassifier() classifier} that specifies {@link EClassifier#getETypeParameters()}; |
| * the number of type arguments must match the number of type parameters. |
| * It is only a warning for there to be no arguments when there are parameters, but any other mismatch is an error. |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean validateEGenericType_ConsistentArguments(EGenericType eGenericType, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| boolean result = true; |
| EClassifier eClassifier = eGenericType.getEClassifier(); |
| EList<EGenericType> eTypeArguments = eGenericType.getETypeArguments(); |
| int eTypeArgumentSize = eTypeArguments.size(); |
| if (eClassifier == null) |
| { |
| if (eTypeArgumentSize != 0) |
| { |
| // Can't have type arguments unless there is a classifier |
| // |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_ARGUMENTS_NONE_ALLOWED, |
| "_UI_EGenericTypeNoArguments_diagnostic", |
| null, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS }, |
| context)); |
| } |
| } |
| } |
| else |
| { |
| EList<ETypeParameter> eTypeParameters = eClassifier.getETypeParameters(); |
| int eTypeParameterSize = eTypeParameters.size(); |
| if (eTypeArgumentSize == 0) |
| { |
| if (eTypeParameterSize > 0) |
| { |
| // Have no arguments when they are allowed is only a warning. |
| // |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.WARNING, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_ARGUMENTS_NONE, |
| "_UI_EGenericTypeArgumentsNeeded_diagnostic", |
| new Object [] { eClassifier.getName(), eTypeParameterSize }, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS }, |
| context)); |
| |
| } |
| } |
| } |
| else if (eTypeArgumentSize != eTypeParameters.size()) |
| { |
| // Incorrect number of type arguments. |
| // |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_ARGUMENTS_INCORRECT_NUMBER, |
| "_UI_EGenericTypeIncorrectArguments_diagnostic", |
| new Object [] { eClassifier.getName(), eTypeArgumentSize, eTypeParameterSize }, |
| new Object[] { eGenericType, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS }, |
| context)); |
| |
| } |
| } |
| else |
| { |
| Map<ETypeParameter, EGenericType> substitutions = new HashMap<ETypeParameter, EGenericType>(); |
| for (int i = 0; i < eTypeParameterSize; ++i) |
| { |
| ETypeParameter eTypeParameter = eTypeParameters.get(i); |
| EGenericType eTypeArgument = eTypeArguments.get(i); |
| substitutions.put(eTypeParameter, eTypeArgument); |
| } |
| for (int i = 0; i < eTypeParameterSize; ++i) |
| { |
| ETypeParameter eTypeParameter = eTypeParameters.get(i); |
| EGenericType eTypeArgument = eTypeArguments.get(i); |
| if (!isValidSubstitution(eTypeArgument, eTypeParameter, substitutions)) |
| { |
| if (diagnostics == null) |
| { |
| return false; |
| } |
| else |
| { |
| result = false; |
| diagnostics.add |
| (createDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| CONSISTENT_ARGUMENTS_INVALID_SUBSTITUTION, |
| "_UI_EGenericTypeArgumentInvalidSubstitution_diagnostic", |
| new Object [] |
| { |
| getObjectLabel(eTypeArgument, context), |
| getObjectLabel(eTypeParameter, context) |
| }, |
| new Object[] { eGenericType, eTypeArgument, eTypeParameter, EcorePackage.Literals.EGENERIC_TYPE__ETYPE_ARGUMENTS }, |
| context)); |
| } |
| } |
| } |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * Returns whether the generic type argument is a valid substitution for the type parameter. |
| * A generic type is a valid substitution |
| * if it is {@link #isBounded(EGenericType, EGenericType, Map) bounded} by |
| * every {@link ETypeParameter#getEBounds() bound} of the type parameter. |
| * It follows that for a type parameter without bounds, every type argument is a valid substitution. |
| * @param eTypeArgument the generic type argument to consider. |
| * @param eTypeParameter the type parameter in question. |
| * @return whether the generic type argument is a valid substitution for the type parameter. |
| */ |
| protected boolean isValidSubstitution(EGenericType eTypeArgument, ETypeParameter eTypeParameter, Map<ETypeParameter, EGenericType> substitutions) |
| { |
| EList<EGenericType> eBounds = eTypeParameter.getEBounds(); |
| if (!eBounds.isEmpty()) |
| { |
| if (eTypeArgument.getEClassifier() == null && |
| eTypeArgument.getETypeParameter() == null && |
| eTypeArgument.getEUpperBound() == null && |
| eTypeArgument.getELowerBound() == null) |
| { |
| return true; |
| } |
| for (EGenericType eBound : eBounds) |
| { |
| if (!isBounded(eTypeArgument, eBound, substitutions)) |
| { |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * Returns whether the first generic type is bounded by the second. |
| * If they both reference a classifier, |
| * then the classifier of the first must be bounded by the classifier of the second, |
| * and the type arguments must {@link #matchingTypeArguments(EList, EList, Map) match}. |
| * A classifier is bounded by another classifier, |
| * if they are the same classifier, |
| * if both are classes and the first is a {@link EClass#isSuperTypeOf(EClass)} the second, |
| * or if both have an non-null {@link EClassifier#getInstanceClass() instance class} |
| * for which the first is {@link Class#isAssignableFrom(Class) assignable from} the second, |
| * or, failing all these, if they have non-null {@link EClassifier#getInstanceTypeName()} that are equal. |
| * If the bound references a classifier, and the generic type argument references a type parameter, |
| * one of the {@link ETypeParameter#getEBounds() bounds} of that type parameter must be bounded by bound. |
| * If the bound has a {@link EGenericType#getELowerBound() lower bound}, |
| * the generic type argument must be bounded by that lower bound. |
| * If the bound has an {@link EGenericType#getEUpperBound() upper bound}, |
| * the generic type argument must be bounded by that upper bound. |
| * If the bound references a type parameter, |
| * the generic type argument must be bounded by every bound of that type parameter. |
| * If the bound has a lower bound, |
| * the generic type argument must be bounded by it. |
| * If the bound has an upper bound, |
| * the generic type argument must be bound that upper bound. |
| * Failing all these cases, the bound is a wildcard with no constraint, and the type argument is bounded. |
| * @param eGenericType the generic type in question. |
| * @param eBound the bound it's being assessed against. |
| * @param substitutions the map of substitutions that are in effect. |
| * @return whether the first generic type is bounded by the second. |
| */ |
| public static boolean isBounded(EGenericType eGenericType, EGenericType eBound, Map<? extends ETypeParameter, ? extends EGenericType> substitutions) |
| { |
| if (eGenericType == eBound) |
| { |
| return true; |
| } |
| |
| // Check if the bound specifies a classifier... |
| // |
| EClassifier eBoundEClassifier = eBound.getEClassifier(); |
| if (eBoundEClassifier != null) |
| { |
| // If the type also specifies a classifier... |
| // |
| EClassifier eClassifier = eGenericType.getEClassifier(); |
| if (eClassifier != null) |
| { |
| // If the are the same then it is bounded properly... |
| // |
| if (eBoundEClassifier != eClassifier) |
| { |
| // We test their relationship either via them both being classes... |
| // |
| if (eBoundEClassifier instanceof EClass && eClassifier instanceof EClass) |
| { |
| EClass eClass = (EClass)eClassifier; |
| |
| // Since we will do the processing recursively, we need to ensure we don't stack overflow if there is a circular super type. |
| // |
| if (INSTANCE.validateEClass_NoCircularSuperTypes(eClass, null, null)) |
| { |
| // Determine if there is a bounding generic super type. |
| // |
| for (EGenericType eGenericSuperType : eClass.getEGenericSuperTypes()) |
| { |
| // Set up the substitutions of any type parameters this class has with respect to the type arguments for them. |
| // |
| Map<? extends ETypeParameter, ? extends EGenericType> localSubstitutions = substitutions; |
| |
| // Test if there are type parameters that might require substitution. |
| // |
| EList<ETypeParameter> eTypeParameters = eClass.getETypeParameters(); |
| int size = eTypeParameters.size(); |
| if (size > 0) |
| { |
| EList<EGenericType> eTypeArguments = eGenericType.getETypeArguments(); |
| if (size == eTypeArguments.size()) |
| { |
| HashMap<ETypeParameter, EGenericType> additionalLocalSubstitutions = new HashMap<ETypeParameter, EGenericType>(substitutions); |
| for (int i = 0; i < size; ++i) |
| { |
| additionalLocalSubstitutions.put(eTypeParameters.get(i), eTypeArguments.get(i)); |
| } |
| localSubstitutions = additionalLocalSubstitutions; |
| } |
| } |
| if (isBounded(eGenericSuperType, eBound, localSubstitutions)) |
| { |
| return true; |
| } |
| } |
| } |
| |
| // If none of the generic super types are bounded, then we've failed. |
| // |
| return false; |
| } |
| else |
| { |
| // Or we test their relationship via their instance classes, if they have them. |
| // |
| Class<?> eBoundClass = eBoundEClassifier.getInstanceClass(); |
| if (eBoundClass != null) |
| { |
| Class<?> eClassifierClass = eClassifier.getInstanceClass(); |
| if (eClassifierClass != null && !eBoundClass.isAssignableFrom(eClassifierClass)) |
| { |
| return false; |
| } |
| // If the classifier being bounded doesn't have type parameters... |
| // |
| else if (eClassifier.getETypeParameters().isEmpty()) |
| { |
| // Then there won't be any type arguments, |
| // so even if the bound has type arguments, |
| // we must assume the classifier is bounded |
| // because we don't know that the implementation class in Java isn't properly bounded. |
| // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=331475 |
| // |
| return true; |
| } |
| } |
| } |
| } |
| |
| // If neither approach finds a contradiction, we must assume they are okay and then check all the arguments. |
| // |
| return matchingTypeArguments(eGenericType.getETypeArguments(), eBound.getETypeArguments(), substitutions); |
| } |
| else |
| { |
| ETypeParameter eTypeParameter = eGenericType.getETypeParameter(); |
| if (eTypeParameter != null) |
| { |
| EGenericType substitution = substitutions.get(eTypeParameter); |
| if (substitution == eGenericType) |
| { |
| return true; |
| } |
| else if (substitution != null && substitution.getEUpperBound() != eGenericType && substitution.getELowerBound() != eGenericType && !isCircularSubstitution(eTypeParameter, substitution, substitutions)) |
| { |
| return isBounded(substitution, eBound, substitutions); |
| } |
| else |
| { |
| // If there is a type parameter, one of its bounds must be bounded by the bound. |
| // |
| boolean result = false; |
| for (EGenericType eTypeParameterBound : eTypeParameter.getEBounds()) |
| { |
| if (isBounded(eTypeParameterBound, eBound, substitutions)) |
| { |
| result = true; |
| break; |
| } |
| } |
| return result; |
| } |
| } |
| else |
| { |
| // If there is a upper bound, the bound must bound it. |
| // |
| EGenericType eUpperBound = eGenericType.getEUpperBound(); |
| if (eUpperBound != null) |
| { |
| return isBounded(eUpperBound, eBound, substitutions); |
| } |
| else |
| { |
| // Failing all those cases, there must be an lower bound that bounds it. |
| // |
| EGenericType eLowerBound = eGenericType.getELowerBound(); |
| return eLowerBound != null && isBounded(eLowerBound, eBound, substitutions); |
| } |
| } |
| } |
| } |
| else |
| { |
| ETypeParameter eBoundETypeParameter = eBound.getETypeParameter(); |
| if (eBoundETypeParameter != null) |
| { |
| ETypeParameter eTypeParameter = eGenericType.getETypeParameter(); |
| if (eTypeParameter == eBoundETypeParameter) |
| { |
| return true; |
| } |
| else |
| { |
| EGenericType substitution = substitutions.get(eBoundETypeParameter); |
| if (substitution != null) |
| { |
| return isBounded(eGenericType, substitution, substitutions); |
| } |
| else if (eTypeParameter != null) |
| { |
| substitution = substitutions.get(eTypeParameter); |
| if (substitution == eGenericType) |
| { |
| return true; |
| } |
| else if (substitution != null && substitution.getEUpperBound() != eGenericType && substitution.getELowerBound() != eGenericType) |
| { |
| return isBounded(substitution, eBound, substitutions); |
| } |
| else |
| { |
| boolean result = false; |
| for (EGenericType eTypeParameterEBound : eTypeParameter.getEBounds()) |
| { |
| if (!(result = isBounded(eTypeParameterEBound, eBound, substitutions))) |
| { |
| for (EGenericType eBoundETypeParameterEBound : eBoundETypeParameter.getEBounds()) |
| { |
| if (isBounded(eTypeParameterEBound, eBoundETypeParameterEBound, substitutions)) |
| { |
| result = true; |
| break; |
| } |
| } |
| } |
| if (!result) |
| { |
| return false; |
| } |
| } |
| return result; |
| } |
| } |
| else |
| { |
| if (eGenericType.getEUpperBound() != null) |
| { |
| return isBounded(eGenericType.getEUpperBound(), eBound, substitutions); |
| } |
| else |
| { |
| return false; |
| } |
| } |
| } |
| } |
| else |
| { |
| // If the generic type is a wildcard, it can't be bounded by another wildcard. |
| // |
| if (eGenericType.getETypeParameter() == null && eGenericType.getEClassifier() == null) |
| { |
| return false; |
| } |
| EGenericType eBoundEUpperBound = eBound.getEUpperBound(); |
| if (eBoundEUpperBound != null) |
| { |
| return isBounded(eGenericType, eBoundEUpperBound, substitutions); |
| } |
| else |
| { |
| EGenericType eBoundELowerBound = eBound.getELowerBound(); |
| if (eBoundELowerBound != null) |
| { |
| // If there is an lower bound, the type argument must bound it. |
| // |
| return isBounded(eBoundELowerBound, eGenericType, substitutions); |
| } |
| |
| // The bound is a wildcard with no constraints. |
| // |
| return false; |
| } |
| } |
| } |
| } |
| |
| private static boolean isCircularSubstitution(ETypeParameter eTypeParameter, EGenericType substitution, Map<? extends ETypeParameter, ? extends EGenericType> substitutions) |
| { |
| Set<ETypeParameter> visited = new HashSet<ETypeParameter>(); |
| for (ETypeParameter otherETypeParameter = substitution.getETypeParameter(); otherETypeParameter != null; ) |
| { |
| if (otherETypeParameter == eTypeParameter) |
| { |
| return true; |
| } |
| |
| if (!visited.add(otherETypeParameter)) |
| { |
| return false; |
| } |
| |
| EGenericType otherSubstitution = substitutions.get(otherETypeParameter); |
| if (otherSubstitution == null) |
| { |
| return false; |
| } |
| |
| otherETypeParameter = otherSubstitution.getETypeParameter(); |
| } |
| |
| return false; |
| } |
| |
| public static boolean matchingTypeArguments |
| (EList<EGenericType> eTypeArguments1, EList<EGenericType> eTypeArguments2, Map<? extends ETypeParameter, ? extends EGenericType> substitutions) |
| { |
| int size = eTypeArguments1.size(); |
| if (size != eTypeArguments2.size()) |
| { |
| return false; |
| } |
| else |
| { |
| for (int i = 0; i < size; ++i) |
| { |
| EGenericType eTypeArgument1 = eTypeArguments1.get(i); |
| EGenericType eTypeArgument2 = eTypeArguments2.get(i); |
| if (!isMatching(eTypeArgument1, eTypeArgument2, substitutions)) |
| { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| |
| public static boolean isMatching(EGenericType eGenericType, EGenericType eBound, Map<? extends ETypeParameter, ? extends EGenericType> substitutions) |
| { |
| if (eGenericType == eBound) |
| { |
| return true; |
| } |
| |
| // Check if the bound specifies a classifier... |
| // |
| EClassifier eBoundEClassifier = eBound.getEClassifier(); |
| if (eBoundEClassifier != null) |
| { |
| // If the type also specifies a classifier... |
| // |
| EClassifier eClassifier = eGenericType.getEClassifier(); |
| if (eClassifier != null) |
| { |
| // If they are the same classifier, they are of course equal. |
| // |
| if (eClassifier != eBoundEClassifier) |
| { |
| // Consider the instance type names they wrap |
| // to see if they are non-null and equal. |
| // |
| String instanceTypeName1 = eClassifier.getInstanceTypeName(); |
| String instanceTypeName2 = eBoundEClassifier.getInstanceTypeName(); |
| |
| // I.e., the classifiers are considered equal if they wrap the same non-null type. |
| // |
| if (instanceTypeName1 == null || !instanceTypeName1.equals(instanceTypeName2)) |
| { |
| return false; |
| } |
| } |
| |
| // TODO What about the instance type name and the fact that we should be matching its type argument structure? |
| // If they match so far, we must assume they are okay and then check all the arguments. |
| // |
| return equalTypeArguments(eGenericType.getETypeArguments(), eBound.getETypeArguments(), substitutions); |
| } |
| else |
| { |
| return false; |
| } |
| } |
| else |
| { |
| ETypeParameter eBoundETypeParameter = eBound.getETypeParameter(); |
| if (eBoundETypeParameter != null) |
| { |
| ETypeParameter eTypeParameter = eGenericType.getETypeParameter(); |
| if (eTypeParameter == eBoundETypeParameter) |
| { |
| return true; |
| } |
| else |
| { |
| EGenericType substitution = substitutions.get(eTypeParameter); |
| if (substitution != null) |
| { |
| return substitution == eGenericType || isMatching(substitution, eBound, substitutions); |
| } |
| else if ((substitution = substitutions.get(eBoundETypeParameter)) != null) |
| { |
| return substitution == eBound || isMatching(eGenericType, substitution, substitutions); |
| } |
| else |
| { |
| return false; |
| } |
| } |
| } |
| else |
| { |
| // If the generic type is a different wildcard, it doesn't match. |
| // |
| if (eGenericType.getEClassifier() == null && eGenericType.getETypeParameter() == null) |
| { |
| return |
| isMatching(eGenericType.getELowerBound(), eBound.getELowerBound(), substitutions) && |
| isMatching(eGenericType.getEUpperBound(), eBound.getEUpperBound(), substitutions); |
| } |
| else |
| { |
| EGenericType eBoundEUpperBound = eBound.getEUpperBound(); |
| if (eBoundEUpperBound != null) |
| { |
| return isBounded(eGenericType, eBoundEUpperBound, substitutions); |
| } |
| else |
| { |
| EGenericType eBoundELowerBound = eBound.getELowerBound(); |
| if (eBoundELowerBound != null) |
| { |
| // Reverse the test. |
| // |
| return isMatching(eBoundELowerBound, eGenericType, substitutions); |
| } |
| |
| // The bound is a wildcard with no constraints. |
| // |
| return true; |
| } |
| } |
| } |
| } |
| } |
| |
| public static boolean equalTypeArguments |
| (EList<EGenericType> eTypeArguments1, EList<EGenericType> eTypeArguments2, Map<? extends ETypeParameter, ? extends EGenericType> substitutions) |
| { |
| int size = eTypeArguments1.size(); |
| if (size != eTypeArguments2.size()) |
| { |
| return false; |
| } |
| else |
| { |
| for (int i = 0; i < size; ++i) |
| { |
| EGenericType eTypeArgument1 = eTypeArguments1.get(i); |
| EGenericType eTypeArgument2 = eTypeArguments2.get(i); |
| if (!equalTypeArguments(eTypeArgument1, eTypeArgument2, substitutions)) |
| { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| |
| public static boolean equalTypeArguments |
| (EGenericType eGenericType1, EGenericType eGenericType2, Map<? extends ETypeParameter, ? extends EGenericType> substitutions) |
| { |
| // If they are the same instance they are equal. |
| // |
| if (eGenericType1 == eGenericType2) |
| { |
| return true; |
| } |
| // If one is null (but the other is not) then they are not equal. |
| // |
| else if (eGenericType1 == null || eGenericType2 == null) |
| { |
| return false; |
| } |
| else |
| { |
| // Consider the classifiers in a special way |
| // to take into account the fact they they often acts as wrappers for instance type names |
| // and that two classifiers that wrap the same instance type name should be considered equal. |
| // |
| EClassifier eClassifier1 = eGenericType1.getEClassifier(); |
| EClassifier eClassifier2 = eGenericType2.getEClassifier(); |
| |
| // If they are the same classifier, they are of course equal. |
| // |
| if (eClassifier1 != eClassifier2) |
| { |
| // If they both aren't null... |
| // |
| if (eClassifier1 != null && eClassifier2 != null) |
| { |
| // Consider the instance type names they wrap |
| // to see if they are non-null and equal. |
| // |
| String instanceTypeName1 = eClassifier1.getInstanceTypeName(); |
| String instanceTypeName2 = eClassifier2.getInstanceTypeName(); |
| |
| // I.e., the classifiers are considered equal if they wrap the same non-null type. |
| // |
| if (instanceTypeName1 == null || !instanceTypeName1.equals(instanceTypeName2)) |
| { |
| return false; |
| } |
| } |
| // If one is null (but the other is not) then they can't be equal. |
| // |
| else if (eClassifier1 != null || eClassifier2 != null) |
| { |
| return false; |
| } |
| } |
| |
| ETypeParameter eTypeParameter1 = eGenericType1.getETypeParameter(); |
| EGenericType substitution = substitutions.get(eTypeParameter1); |
| if (substitution != null) |
| { |
| return equalTypeArguments(substitution, eGenericType2, substitutions); |
| } |
| ETypeParameter eTypeParameter2 = eGenericType2.getETypeParameter(); |
| substitution = substitutions.get(eTypeParameter2); |
| if (substitution != null) |
| { |
| return equalTypeArguments(eGenericType1, substitution, substitutions); |
| } |
| |
| // The arguments, type parameters, lower bounds and upper bounds must be equal type arguments. |
| // |
| return |
| eTypeParameter1 == eTypeParameter2 && |
| equalTypeArguments(eGenericType1.getETypeArguments(), eGenericType2.getETypeArguments(), substitutions) && |
| equalTypeArguments(eGenericType1.getELowerBound(), eGenericType2.getELowerBound(), substitutions) && |
| equalTypeArguments(eGenericType1.getEUpperBound(), eGenericType2.getEUpperBound(), substitutions); |
| } |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateETypeParameter(ETypeParameter eTypeParameter, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| if (!validate_NoCircularContainment(eTypeParameter, diagnostics, context)) return false; |
| boolean result = validate_EveryMultiplicityConforms(eTypeParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryDataValueConforms(eTypeParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryReferenceIsContained(eTypeParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryBidirectionalReferenceIsPaired(eTypeParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryProxyResolves(eTypeParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_UniqueID(eTypeParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryKeyUnique(eTypeParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validate_EveryMapEntryUnique(eTypeParameter, diagnostics, context); |
| if (result || diagnostics != null) result &= validateENamedElement_WellFormedName(eTypeParameter, diagnostics, context); |
| return result; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEBigDecimal(BigDecimal eBigDecimal, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEBigInteger(BigInteger eBigInteger, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEBoolean(boolean eBoolean, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEBooleanObject(Boolean eBooleanObject, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEByte(byte eByte, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEByteArray(byte[] eByteArray, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEByteObject(Byte eByteObject, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEChar(char eChar, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateECharacterObject(Character eCharacterObject, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEDate(Date eDate, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEDiagnosticChain(DiagnosticChain eDiagnosticChain, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEDouble(double eDouble, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEDoubleObject(Double eDoubleObject, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEEList(EList<?> eeList, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEEnumerator(Enumerator eEnumerator, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEFeatureMap(FeatureMap eFeatureMap, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEFeatureMapEntry(FeatureMap.Entry eFeatureMapEntry, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEFloat(float eFloat, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEFloatObject(Float eFloatObject, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEInt(int eInt, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEIntegerObject(Integer eIntegerObject, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEJavaClass(Class<?> eJavaClass, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEJavaObject(Object eJavaObject, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateELong(long eLong, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateELongObject(Long eLongObject, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEMap(Map<?, ?> eMap, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEResource(Resource eResource, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEResourceSet(ResourceSet eResourceSet, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEShort(short eShort, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEShortObject(Short eShortObject, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEString(String eString, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateETreeIterator(TreeIterator<?> eTreeIterator, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean validateEInvocationTargetException(InvocationTargetException eInvocationTargetException, DiagnosticChain diagnostics, Map<Object, Object> context) |
| { |
| return true; |
| } |
| |
| /** |
| * Returns the resource locator that will be used to fetch messages for this validator's diagnostics. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public ResourceLocator getResourceLocator() |
| { |
| // TODO |
| // Specialize this to return a resource locator for messages specific to this validator. |
| // Ensure that you remove @generated or mark it @generated NOT |
| return super.getResourceLocator(); |
| } |
| |
| /** |
| * A utility for parsing generic types and generic type parameters. |
| * @since 2.3 |
| */ |
| public static class EGenericTypeBuilder |
| { |
| /** |
| * A singleton instance of the generic type build. |
| */ |
| public static final EGenericTypeBuilder INSTANCE = new EGenericTypeBuilder(); |
| |
| private static final char [] NO_CHARS = {}; |
| |
| /** |
| * Parses an instance type name and returns a diagnostic representing the result of the analysis. |
| * The {@link Diagnostic#getData() data} of the diagnostic will contain as the first object, the resulting {@link EGenericType generic type}. |
| * @param instanceTypeName an instance type name. |
| * @return the diagnostic result of the analysis. |
| */ |
| public Diagnostic parseInstanceTypeName(final String instanceTypeName) |
| { |
| BasicDiagnostic placeholder = new BasicDiagnostic(); |
| char [] instanceTypeNameCharacterArray = instanceTypeName == null ? NO_CHARS: instanceTypeName.toCharArray(); |
| EGenericType eGenericType = handleInstanceTypeName(instanceTypeNameCharacterArray, 0, instanceTypeNameCharacterArray.length, placeholder); |
| BasicDiagnostic result = |
| createDiagnostic |
| (placeholder.getSeverity(), |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_INSTANCE_TYPE_NAME, |
| "_UI_EClassifierInstanceTypeNameAnalysisResult_diagnostic", |
| new Object [] { instanceTypeName }, |
| new Object [] { eGenericType, instanceTypeName }); |
| result.addAll(placeholder); |
| return result; |
| } |
| |
| /** |
| * Parses a list of type parameters and returns a diagnostic representing the result of the analysis. |
| * The {@link Diagnostic#getData() data} of the diagnostic will contain as the first object, the resulting list of {@link ETypeParameter type parameters}. |
| * @param typeParameterList a comma separated list of type parameters delimited by '<' and '>'. |
| * @return the diagnostic result of the analysis. |
| */ |
| public Diagnostic parseTypeParameterList(final String typeParameterList) |
| { |
| BasicDiagnostic placeholder = new BasicDiagnostic(); |
| char [] instanceTypeNameCharacterArray = typeParameterList == null ? NO_CHARS : typeParameterList.toCharArray(); |
| List<ETypeParameter> eTypeParameters = handleTypeParameters(instanceTypeNameCharacterArray, 0, instanceTypeNameCharacterArray.length, placeholder); |
| BasicDiagnostic result = |
| createDiagnostic |
| (placeholder.getSeverity(), |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_INSTANCE_TYPE_NAME, |
| "_UI_EClassifierInstanceTypeNameAnalysisResult_diagnostic", |
| new Object [] { typeParameterList }, |
| new Object [] { eTypeParameters, typeParameterList }); |
| result.addAll(placeholder); |
| return result; |
| } |
| |
| /** |
| * Parses a list of type arguments and returns a diagnostic representing the result of the analysis. |
| * The {@link Diagnostic#getData() data} of the diagnostic will contain as the first object, the resulting list of {@link EGenericType type arguments}. |
| * @param typeArgumentList a comma separated list of type arguments. |
| * @return the diagnostic result of the analysis. |
| * @since 2.4 |
| */ |
| public Diagnostic parseTypeArgumentList(final String typeArgumentList) |
| { |
| BasicDiagnostic placeholder = new BasicDiagnostic(); |
| char [] instanceTypeNameCharacterArray = typeArgumentList == null ? NO_CHARS : typeArgumentList.toCharArray(); |
| List<EGenericType> eTypeArguments = handleTypeArguments(instanceTypeNameCharacterArray, 0, instanceTypeNameCharacterArray.length, placeholder); |
| BasicDiagnostic result = |
| createDiagnostic |
| (placeholder.getSeverity(), |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_INSTANCE_TYPE_NAME, |
| "_UI_EClassifierInstanceTypeNameAnalysisResult_diagnostic", |
| new Object [] { typeArgumentList }, |
| new Object [] { eTypeArguments, typeArgumentList }); |
| result.addAll(placeholder); |
| return result; |
| } |
| |
| /** |
| * Parses a type parameter and returns a diagnostic representing the result of the analysis. |
| * The {@link Diagnostic#getData() data} of the diagnostic will contain as the first object, the resulting {@link ETypeParameter type parameter}. |
| * @param typeParameter comma separated list of type parameters delimited by '<' and '>'. |
| * @return the diagnostic result of the analysis. |
| */ |
| public Diagnostic parseTypeParameter(final String typeParameter) |
| { |
| BasicDiagnostic placeholder = new BasicDiagnostic(); |
| char [] instanceTypeNameCharacterArray = typeParameter == null ? NO_CHARS : typeParameter.toCharArray(); |
| ETypeParameter eTypeParameter = handleTypeParameter(instanceTypeNameCharacterArray, 0, instanceTypeNameCharacterArray.length, placeholder); |
| BasicDiagnostic result = |
| createDiagnostic |
| (placeholder.getSeverity(), |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_INSTANCE_TYPE_NAME, |
| "_UI_EClassifierInstanceTypeNameAnalysisResult_diagnostic", |
| new Object [] { typeParameter }, |
| new Object [] { eTypeParameter, typeParameter }); |
| result.addAll(placeholder); |
| return result; |
| } |
| |
| /** |
| * Finds or creates an {@link EClassifier classifier} with the given instance type name. |
| * @param instanceTypeName the instance type name for which a classifier is needed. |
| * @return a classifier with the instance type name. |
| */ |
| protected EClassifier resolveEClassifier(String instanceTypeName) |
| { |
| EDataType eDataType = EcoreFactory.eINSTANCE.createEDataType(); |
| eDataType.setInstanceTypeName(instanceTypeName); |
| return eDataType; |
| } |
| |
| /** |
| * Creates a new diagnostic for a problem at the given index. |
| * @param diagnostics the target for the new diagnostic. |
| * @param key the key for the message. |
| * @param substitutions the substitutions for the key; <code>null</code> if there are no substitutions. |
| * @param index the index at which the problem occurred. |
| */ |
| protected void report(DiagnosticChain diagnostics, String key, Object [] substitutions, int index) |
| { |
| report(diagnostics, getString(key, substitutions), index); |
| } |
| |
| /** |
| * Creates a new diagnostic for a problem at the given index. |
| * @param diagnostics the target for the new diagnostic. |
| * @param message the text describing the problem. |
| * @param index the index at which the problem occurred. |
| */ |
| protected void report(DiagnosticChain diagnostics, String message, int index) |
| { |
| if (diagnostics != null) |
| { |
| diagnostics.add |
| (new BasicDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_INSTANCE_TYPE_NAME, |
| message, |
| new Object [] { index })); |
| } |
| } |
| |
| /** |
| * A well formed instance type name must syntactically denote a valid Java type name; |
| * names denoting keywords are considered well formed. |
| * It must start with a qualified name consisting of one or more "." separated identifiers, |
| * where each identifier must start with a {@link Character#isJavaIdentifierStart(int) Java identifier start character}, |
| * that is followed by zero or more {@link Character#isJavaIdentifierPart(int) Java identifier part characters}. |
| * The methods {@link #isIdentifierStart(int)} and {@link #isIdentifierPart(int)} are used so that this behavior can be specialized. |
| * This qualified name may optionally be followed by zero or more pairs of "[]" characters |
| * or by type arguments consisting of the pair of "<>" characters |
| * with embedded {@link #handleTypeArguments(char[], int, int, DiagnosticChain) well formed type arguments}. |
| * @param instanceTypeName the instance type name in question. |
| * @param start the start of the characters under consideration. |
| * @param end the end of the characters under consideration. |
| * @param diagnostics the target in which to accumulate diagnostics. |
| * @return the generic type representing the instance type name. |
| */ |
| protected EGenericType handleInstanceTypeName(char [] instanceTypeName, int start, int end, DiagnosticChain diagnostics) |
| { |
| EGenericType eGenericType = EcoreFactory.eINSTANCE.createEGenericType(); |
| StringBuilder qualifiedName = new StringBuilder(); |
| int identifierStart = -1; |
| int identifierLast = -1; |
| int brackets = 0; |
| List<EGenericType> typeArguments = null; |
| LOOP: |
| for (int i = start; i < end; i = Character.offsetByCodePoints(instanceTypeName, 0, instanceTypeName.length, i, 1)) |
| { |
| int codePoint = Character.codePointAt(instanceTypeName, i); |
| if (codePoint == '[') |
| { |
| if (identifierStart == -1 && (qualifiedName.length() == 0 || qualifiedName.charAt(qualifiedName.length() - 1) == '.')) |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameBracketWithoutPrecedingIdentifier_diagnostic", |
| new Object [] { i }, |
| i); |
| return eGenericType; |
| } |
| else |
| { |
| for (int j = i + 1; j < end; j = Character.offsetByCodePoints(instanceTypeName, 0, instanceTypeName.length, j, 1)) |
| { |
| codePoint = Character.codePointAt(instanceTypeName, j); |
| if (codePoint == ']') |
| { |
| i = j; |
| ++brackets; |
| continue LOOP; |
| } |
| else if (!Character.isWhitespace(codePoint)) |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameNoClosingBracket2_diagnostic", |
| new Object [] { j, new String(Character.toChars(codePoint))}, |
| j); |
| return eGenericType; |
| } |
| } |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameNoClosingBracket_diagnostic", |
| new Object [] { end }, |
| end); |
| return eGenericType; |
| } |
| } |
| else if (brackets > 0) |
| { |
| if (!Character.isWhitespace(codePoint)) |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameBracketExpected_diagnostic", |
| new Object [] { i, new String(Character.toChars(codePoint))}, |
| i); |
| return eGenericType; |
| } |
| } |
| else if (codePoint == '.') |
| { |
| if (identifierStart == -1) |
| { |
| if (qualifiedName.length() == 0 || qualifiedName.charAt(qualifiedName.length() - 1) == '.') |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameDotWithoutPrecedingIdentifier_diagnostic", |
| new Object [] { i }, |
| i); |
| return eGenericType; |
| } |
| else |
| { |
| qualifiedName.append('.'); |
| } |
| } |
| else |
| { |
| qualifiedName.append(instanceTypeName, identifierStart, identifierLast - identifierStart + 1); |
| qualifiedName.append('.'); |
| identifierStart = -1; |
| identifierLast = -1; |
| } |
| } |
| else if (identifierStart != -1 ? isIdentifierPart(codePoint) : isIdentifierStart(codePoint)) |
| { |
| if (identifierStart == -1) |
| { |
| if (qualifiedName.length() > 0 && qualifiedName.charAt(qualifiedName.length() - 1) != '.') |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameDotExpectedBeforeIdentifier_diagnostic", |
| new Object [] { i }, |
| i); |
| return eGenericType; |
| } |
| identifierStart = i; |
| } |
| identifierLast = i; |
| } |
| else if (Character.isWhitespace(codePoint)) |
| { |
| if (identifierStart == -1) |
| { |
| // Ignore leading whitespace |
| } |
| else if (qualifiedName.length() == 0 || qualifiedName.charAt(qualifiedName.length() - 1) == '.') |
| { |
| qualifiedName.append(instanceTypeName, identifierStart, identifierLast - identifierStart + 1); |
| identifierStart = -1; |
| identifierLast = -1; |
| } |
| else |
| { |
| // Ignore trailing whitespace |
| } |
| } |
| else if (codePoint == '<') |
| { |
| if (identifierStart == -1 && (qualifiedName.length() == 0 || qualifiedName.charAt(qualifiedName.length() - 1) == '.')) |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameAngleBracketWithoutPrecedingIdentifier_diagnostic", |
| new Object [] { i }, |
| i); |
| return eGenericType; |
| } |
| for (int j = end - 1; j > i; --j) |
| { |
| if (instanceTypeName[j] == '>') |
| { |
| typeArguments = handleTypeArguments(instanceTypeName, i + 1, j, diagnostics); |
| i = j; |
| continue LOOP; |
| } |
| } |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameUnterminatedAngleBracket_diagnostic", |
| new Object [] { i }, |
| i); |
| return eGenericType; |
| } |
| else |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameUnexpectedCharacter_diagnostic", |
| new Object [] { i, new String(Character.toChars(codePoint)) }, |
| i); |
| return eGenericType; |
| } |
| } |
| |
| if (identifierStart == -1 && (qualifiedName.length() == 0 || qualifiedName.charAt(qualifiedName.length() - 1) == '.')) |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameExpectingIdentifier_diagnostic", |
| new Object [] { end }, |
| end); |
| } |
| else |
| { |
| if (identifierStart != -1) |
| { |
| qualifiedName.append(instanceTypeName, identifierStart, identifierLast - identifierStart + 1); |
| } |
| while (brackets-- > 0) |
| { |
| qualifiedName.append("[]"); |
| } |
| String qualifiedNameString = qualifiedName.toString(); |
| eGenericType.setEClassifier(resolveEClassifier(qualifiedNameString)); |
| if (typeArguments != null) |
| { |
| eGenericType.getETypeArguments().addAll(typeArguments); |
| } |
| } |
| return eGenericType; |
| } |
| |
| /** |
| * Returns whether this code point is a valid start of an identifier. |
| * @param codePoint the code point in question. |
| * @return whether this code point is a valid start of an identifier. |
| */ |
| protected boolean isIdentifierStart(int codePoint) |
| { |
| return Character.isJavaIdentifierStart(codePoint); |
| } |
| |
| /** |
| * Returns whether this code point is a valid part of an identifier, i.e., whether it's valid after the first character. |
| * @param codePoint the code point in question. |
| * @return whether this code point is a valid part of an identifier. |
| */ |
| protected boolean isIdentifierPart(int codePoint) |
| { |
| return Character.isJavaIdentifierPart(codePoint); |
| } |
| |
| /** |
| * Well formed type arguments must syntactically denote a comma separated sequence of |
| * {@link #handleTypeArgument(char[], int, int, DiagnosticChain) well formed type arguments}. |
| * Whitespace before or after arguments is ignored. |
| * @param instanceTypeName the instance type name in question. |
| * @param start the start of the characters under consideration. |
| * @param end the end of the characters under consideration. |
| * @param diagnostics the target in which to accumulate diagnostics. |
| * @return a list of generic type representing the type arguments. |
| */ |
| protected List<EGenericType> handleTypeArguments(char [] instanceTypeName, int start, int end, DiagnosticChain diagnostics) |
| { |
| List<EGenericType> result = new ArrayList<EGenericType>(); |
| int depth = 0; |
| int typeArgumentStart = start; |
| for (int i = start; i < end; i = Character.offsetByCodePoints(instanceTypeName, 0, instanceTypeName.length, i, 1)) |
| { |
| int codePoint = Character.codePointAt(instanceTypeName, i); |
| switch (codePoint) |
| { |
| case '<': |
| { |
| ++depth; |
| break; |
| } |
| case '>': |
| { |
| --depth; |
| break; |
| } |
| case ',': |
| { |
| if (depth == 0) |
| { |
| result.add(handleTypeArgument(instanceTypeName, typeArgumentStart, i, diagnostics)); |
| typeArgumentStart = i + 1; |
| } |
| break; |
| } |
| default: |
| { |
| if (typeArgumentStart == -1) |
| { |
| typeArgumentStart = i; |
| } |
| break; |
| } |
| } |
| } |
| result.add(handleTypeArgument(instanceTypeName, typeArgumentStart, end, diagnostics)); |
| return result; |
| } |
| |
| /** |
| * A well formed type argument must denote a valid Java type argument. |
| * It may start with a "?" |
| * which may be optionally followed by the keyword "extends" or "super" |
| * which in turn, when present, must be followed by a |
| * {@link #handleInstanceTypeName(char[], int, int, DiagnosticChain) well formed type instance name}. |
| * White space before the keyword is optional but at least one space character is expected after the keyword. |
| * Otherwise, the whole string must be a well formed instance type name. |
| * @param instanceTypeName the instance type name in question. |
| * @param start the start of the characters under consideration. |
| * @param end the end of the characters under consideration. |
| * @param diagnostics the target in which to accumulate diagnostics. |
| * @return the generic type representing the type argument. |
| */ |
| protected EGenericType handleTypeArgument(char [] instanceTypeName, int start, int end, DiagnosticChain diagnostics) |
| { |
| EGenericType eGenericType = null; |
| int firstNonWhiteSpaceIndex = start; |
| LOOP: |
| for (int i = start; i < end; i = Character.offsetByCodePoints(instanceTypeName, 0, instanceTypeName.length, i, 1)) |
| { |
| int codePoint = Character.codePointAt(instanceTypeName, i); |
| switch (codePoint) |
| { |
| case '?': |
| { |
| if (eGenericType == null) |
| { |
| eGenericType = EcoreFactory.eINSTANCE.createEGenericType(); |
| break; |
| } |
| else |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameTooManyQuestionMarks_diagnostic", |
| new Object [] { i }, |
| i); |
| break LOOP; |
| } |
| } |
| case 'e': |
| { |
| if (eGenericType != null) |
| { |
| if (i + 7 < end && |
| instanceTypeName[i + 1] == 'x' && |
| instanceTypeName[i + 2] == 't' && |
| instanceTypeName[i + 3] == 'e' && |
| instanceTypeName[i + 4] == 'n' && |
| instanceTypeName[i + 5] == 'd' && |
| instanceTypeName[i + 6] == 's' && |
| Character.isWhitespace(Character.codePointAt(instanceTypeName, i + 7))) |
| { |
| EGenericType eUpperBound = |
| handleInstanceTypeName |
| (instanceTypeName, Character.offsetByCodePoints(instanceTypeName, 0, instanceTypeName.length, i + 6, 1), end, diagnostics); |
| eGenericType.setEUpperBound(eUpperBound); |
| } |
| else |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameExpectingExtends_diagnostic", |
| new Object [] { i }, |
| i); |
| } |
| } |
| else |
| { |
| eGenericType = handleInstanceTypeName(instanceTypeName, start, end, diagnostics); |
| } |
| break LOOP; |
| } |
| case 's': |
| { |
| if (eGenericType != null) |
| { |
| if (i + 5 < end && |
| instanceTypeName[i + 1] == 'u' && |
| instanceTypeName[i + 2] == 'p' && |
| instanceTypeName[i + 3] == 'e' && |
| instanceTypeName[i + 4] == 'r' && |
| Character.isWhitespace(Character.codePointAt(instanceTypeName, i + 5))) |
| { |
| EGenericType eLowerBound = |
| handleInstanceTypeName |
| (instanceTypeName, Character.offsetByCodePoints(instanceTypeName, 0, instanceTypeName.length, i + 4, 1), end, diagnostics); |
| eGenericType.setELowerBound(eLowerBound); |
| } |
| else |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameExpectingSuper_diagnostic", |
| new Object [] { i }, |
| i); |
| } |
| } |
| else |
| { |
| eGenericType = handleInstanceTypeName(instanceTypeName, start, end, diagnostics); |
| } |
| break LOOP; |
| } |
| default: |
| { |
| if (Character.isWhitespace(codePoint)) |
| { |
| break; |
| } |
| else if (eGenericType != null) |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameExpectingExtendsOrSuper_diagnostic", |
| new Object [] { i }, |
| i); |
| break LOOP; |
| } |
| else |
| { |
| firstNonWhiteSpaceIndex = i; |
| eGenericType = handleInstanceTypeName(instanceTypeName, i, end, diagnostics); |
| break LOOP; |
| } |
| } |
| } |
| } |
| if (eGenericType == null) |
| { |
| eGenericType = EcoreFactory.eINSTANCE.createEGenericType(); |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameTypeArgumentExpected_diagnostic", |
| new Object [] { firstNonWhiteSpaceIndex }, |
| firstNonWhiteSpaceIndex); |
| } |
| return eGenericType; |
| } |
| |
| /** |
| * Well formed type parameters must syntactically denote a comma separated sequence of |
| * {@link #handleTypeParameter(char[], int, int, DiagnosticChain) well formed type parameters} delimited by "<>". |
| * Whitespace before or after parameters is ignored. |
| * @param typeParameters the type parameters question. |
| * @param start the start of the characters under consideration. |
| * @param end the end of the characters under consideration. |
| * @param diagnostics the target in which to accumulate diagnostics. |
| * @return a list of type parameters. |
| */ |
| protected List<ETypeParameter> handleTypeParameters(char [] typeParameters, int start, int end, DiagnosticChain diagnostics) |
| { |
| List<ETypeParameter> result = new ArrayList<ETypeParameter>(); |
| int depth = 0; |
| int typeArgumentStart = -1; |
| for (int i = start; i < end; i = Character.offsetByCodePoints(typeParameters, 0, typeParameters.length, i, 1)) |
| { |
| int codePoint = Character.codePointAt(typeParameters, i); |
| switch (codePoint) |
| { |
| case '<': |
| { |
| ++depth; |
| break; |
| } |
| case '>': |
| { |
| if (--depth == 0) |
| { |
| result.add(handleTypeParameter(typeParameters, typeArgumentStart, i, diagnostics)); |
| } |
| break; |
| } |
| case ',': |
| { |
| if (depth == 1) |
| { |
| result.add(handleTypeParameter(typeParameters, typeArgumentStart, i, diagnostics)); |
| typeArgumentStart = i + 1; |
| } |
| break; |
| } |
| default: |
| { |
| if (typeArgumentStart == -1) |
| { |
| typeArgumentStart = i; |
| } |
| break; |
| } |
| } |
| } |
| if (depth != 0) |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameUnterminatedAngleBracket_diagnostic", |
| new Object [] { start }, |
| start); |
| } |
| return result; |
| } |
| |
| /** |
| * A well formed type parameter must denote a valid Java type parameter. |
| * It must start with a well formed java identifier |
| * which may be optionally followed by the keyword "extends" |
| * which in turn, when present, must be followed by |
| * one or more '&' separated {@link #handleTypeArgument(char[], int, int, DiagnosticChain) well formed type arguments} representing the bounds. |
| * White space before the keyword is optional but at least one space character is expected after the keyword. |
| * @param typeParameters the instance type name in question. |
| * @param start the start of the characters under consideration. |
| * @param end the end of the characters under consideration. |
| * @param diagnostics the target in which to accumulate diagnostics. |
| * @return the type parameter. |
| */ |
| protected ETypeParameter handleTypeParameter(char [] typeParameters, int start, int end, DiagnosticChain diagnostics) |
| { |
| ETypeParameter eTypeParameter = EcoreFactory.eINSTANCE.createETypeParameter(); |
| int identifierStart = -1; |
| int identifierLast = -1; |
| boolean identifierDone = false; |
| LOOP: |
| for (int i = start; i < end; i = Character.offsetByCodePoints(typeParameters, 0, typeParameters.length, i, 1)) |
| { |
| int codePoint = Character.codePointAt(typeParameters, i); |
| if (Character.isWhitespace(codePoint)) |
| { |
| if (identifierStart != -1) |
| { |
| identifierDone = true; |
| } |
| } |
| else if (identifierDone) |
| { |
| if (codePoint == 'e' && |
| i + 7 < end && |
| typeParameters[i + 1] == 'x' && |
| typeParameters[i + 2] == 't' && |
| typeParameters[i + 3] == 'e' && |
| typeParameters[i + 4] == 'n' && |
| typeParameters[i + 5] == 'd' && |
| typeParameters[i + 6] == 's' && |
| Character.isWhitespace(Character.codePointAt(typeParameters, i + 7))) |
| { |
| i += 7; |
| int boundStart = i; |
| while (i < end) |
| { |
| char character = typeParameters[i]; |
| if (character == '&') |
| { |
| EGenericType eBound = handleInstanceTypeName(typeParameters, boundStart, i, diagnostics); |
| eTypeParameter.getEBounds().add(eBound); |
| boundStart = i + 1; |
| } |
| ++i; |
| } |
| EGenericType eBound = handleInstanceTypeName(typeParameters, boundStart, i, diagnostics); |
| eTypeParameter.getEBounds().add(eBound); |
| } |
| else |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameExpectingExtends_diagnostic", |
| new Object [] { i }, |
| i); |
| } |
| break LOOP; |
| } |
| else if (identifierStart != -1 ? isIdentifierPart(codePoint) : isIdentifierStart(codePoint)) |
| { |
| if (identifierStart == -1) |
| { |
| identifierStart = i; |
| } |
| identifierLast = i; |
| } |
| else |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameUnexpectedCharacter_diagnostic", |
| new Object [] { i, new String(Character.toChars(codePoint)) }, |
| i); |
| break LOOP; |
| } |
| } |
| |
| if (identifierLast == -1) |
| { |
| report |
| (diagnostics, |
| "_UI_EClassifierInstanceTypeNameExpectingIdentifier_diagnostic", |
| new Object [] { end }, |
| end); |
| } |
| else |
| { |
| eTypeParameter.setName(new String(typeParameters, identifierStart, identifierLast - identifierStart + 1)); |
| } |
| return eTypeParameter; |
| } |
| |
| /** |
| * Creates a new {@link BasicDiagnostic#BasicDiagnostic(int, String, int, String, Object[]) basic diagnostic}. |
| * It calls {@link #getString(String, Object[])} for the message substitution. |
| * @param severity an indicator of the severity of the problem. |
| * @param source the unique identifier of the source. |
| * @param code the source-specific identity code. |
| * @param messageKey the key of the message. |
| * @param messageSubstitutions the substitutions for the key; <code>null</code> if there are no substitutions. |
| * @param data the data associated with the diagnostic |
| * @return a new diagnostic. |
| * @see BasicDiagnostic#BasicDiagnostic(int, String, int, String, Object[]) |
| * @since 2.4 |
| */ |
| protected BasicDiagnostic createDiagnostic |
| (int severity, String source, int code, String messageKey, Object[] messageSubstitutions, Object[] data) |
| { |
| String message = getString(messageKey, messageSubstitutions); |
| return new BasicDiagnostic(severity, source, code, message, data); |
| } |
| |
| /** |
| * Returns a translated message with the given substitutions. |
| * The {@link #getResourceLocator() resource locator} is used. |
| * @param key the key for the message. |
| * @param substitutions the substitutions for the key; <code>null</code> if there are no substitutions. |
| * @return the message. |
| * @since 2.4 |
| */ |
| protected String getString(String key, Object [] substitutions) |
| { |
| ResourceLocator resourceLocator = getResourceLocator(); |
| return substitutions == null ? resourceLocator.getString(key) : resourceLocator.getString(key, substitutions); |
| } |
| |
| /** |
| * Returns the resource locator for {@link #getString(String, Object[]) fetching} messages. |
| * @return the resource locator for fetching messages. |
| * @since 2.4 |
| */ |
| protected ResourceLocator getResourceLocator() |
| { |
| return EcorePlugin.INSTANCE; |
| } |
| } |
| |
| /** |
| * Creates a new diagnostic for a problem at the given index. |
| * @param diagnostics the target for the new diagnostic. |
| * @param key the key for the message. |
| * @param substitutions the substitutions for the key; <code>null</code> if there are no substitutions. |
| * @param index the index at which the problem occurred. |
| * @see EGenericTypeBuilder#report(DiagnosticChain, String, Object[], int) |
| * @since 2.4 |
| */ |
| protected void report(DiagnosticChain diagnostics, String key, Object[] substitutions, int index, Map<Object, Object> context) |
| { |
| if (diagnostics != null) |
| { |
| diagnostics.add |
| (new BasicDiagnostic |
| (Diagnostic.ERROR, |
| DIAGNOSTIC_SOURCE, |
| WELL_FORMED_INSTANCE_TYPE_NAME, |
| getString(key, substitutions), |
| new Object [] { index })); |
| } |
| } |
| |
| } //EcoreValidator |