/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.metamodels.relational.aspects.validation.rules; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.teiid.designer.core.validation.ObjectValidationRule; import org.teiid.designer.core.validation.ValidationContext; import org.teiid.designer.core.validation.ValidationProblem; import org.teiid.designer.core.validation.ValidationProblemImpl; import org.teiid.designer.core.validation.ValidationResult; import org.teiid.designer.core.validation.ValidationResultImpl; import org.teiid.designer.metamodels.relational.Procedure; import org.teiid.designer.metamodels.relational.RelationalPlugin; import org.teiid.designer.metamodels.relational.util.PushdownFunctionUtil; /** * ScalarFunctionUniquenessRule * @since 8.0 */ public class SourceProcedureUniquenessRule implements ObjectValidationRule { private final String ruleName; /** * Construct an instance of ScalarFunctionUniquenessRule. * */ public SourceProcedureUniquenessRule() { super(); this.ruleName = this.getClass().getName(); } /** * @see org.teiid.designer.core.validation.ObjectValidationRule#validate(org.eclipse.emf.ecore.EObject, * org.teiid.designer.core.validation.ValidationContext) */ public void validate( final EObject eObject, final ValidationContext context ) { if (context.hasRunRule(eObject, this.ruleName)) { return; } // Check whether there are any other scalar functions with a similar signature ... final List siblings = getSiblingsForUniquenessCheck(eObject); if (siblings.size() < 2) { return; // no siblings ... } // Get the signature of the siblings ... final Map siblingsBySignature = new HashMap(); final Iterator iter = siblings.iterator(); while (iter.hasNext()) { final EObject sibling = (EObject)iter.next(); if (sibling instanceof Procedure && ((Procedure)sibling).isFunction()) { final String signature = computeSignature(sibling); List existing = (List)siblingsBySignature.get(signature); if (existing == null) { existing = new LinkedList(); siblingsBySignature.put(signature, existing); } if (!existing.contains(sibling)) { existing.add(sibling); } } } // Go through all the duplicate signatures and create errors ... final Iterator iterator = siblingsBySignature.keySet().iterator(); while (iterator.hasNext()) { final String signature = (String)iterator.next(); final List siblingsWithSameSignature = (List)siblingsBySignature.get(signature); final int numSiblingsWithSameSignature = siblingsWithSameSignature.size(); // create validation problem and addit to the results if (numSiblingsWithSameSignature > 1) { final Iterator siblingIter = siblingsWithSameSignature.iterator(); while (siblingIter.hasNext()) { final EObject sibling = (EObject)siblingIter.next(); ValidationResult result = new ValidationResultImpl(sibling); final String msg = getDuplicateMessage(numSiblingsWithSameSignature, signature); ValidationProblem problem = new ValidationProblemImpl(0, IStatus.ERROR, msg); result.addProblem(problem); // add the result to the context context.addResult(result); } } } // set the rule has been run context.recordRuleRun(eObject, this.ruleName); } protected String computeSignature(EObject eObject) { return PushdownFunctionUtil.getSignature((Procedure)eObject); } protected String getDuplicateMessage( final int numDuplicates, final String signature ) { final Object[] params = new Object[] {new Integer(numDuplicates - 1), signature}; final String msg = RelationalPlugin.Util.getString("SourceProcedureUniquenessRule.Same_signature_as_{0}_sibling(s)__{1}", params); //$NON-NLS-1$ return msg; } /** * Obtain those siblings of the supplied object that are to be considered the domain of objects for the uniqueness check. * * @param eObject the object whose name is to be checked for uniqueness amongst its siblings * @return the siblings that should be used to check for uniqueness in the name; never null */ protected List getSiblingsForUniquenessCheck( final EObject eObject ) { final EObject parent = eObject.eContainer(); if (parent != null) { // eObject is not a parent ... return parent.eContents(); } // eObject is one of the roots ... final Resource resource = eObject.eResource(); if (resource != null) { return resource.getContents(); } return new ArrayList(1); } }