/******************************************************************************* * Copyright (c) 2008 SAP * see https://research.qkal.sap.corp/mediawiki/index.php/CoMONET * * Date: $Date: 2010-05-20 15:12:26 +0200 (Do, 20 Mai 2010) $ * @version $Revision: 9718 $ * @author: $Author: c5106462 $ *******************************************************************************/ package com.sap.furcas.parsergenerator.tcs.t2m.validation; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import com.sap.furcas.metamodel.FURCAS.TCS.ClassTemplate; import com.sap.furcas.metamodel.FURCAS.TCS.ConcreteSyntax; import com.sap.furcas.metamodel.FURCAS.TCS.FunctionTemplate; import com.sap.furcas.metamodel.FURCAS.TCS.Operator; import com.sap.furcas.metamodel.FURCAS.TCS.OperatorTemplate; import com.sap.furcas.metamodel.FURCAS.TCS.PrimitiveTemplate; import com.sap.furcas.metamodel.FURCAS.TCS.Template; import com.sap.furcas.parsergenerator.tcs.t2m.grammar.SemanticErrorBucket; import com.sap.furcas.runtime.common.exceptions.NameResolutionFailedException; import com.sap.furcas.runtime.common.interfaces.IMetaModelLookup; import com.sap.furcas.runtime.common.interfaces.ResolvedNameAndReferenceBean; import com.sap.furcas.runtime.common.util.MessageUtil; import com.sap.furcas.runtime.tcs.MetaModelElementResolutionHelper; /** * The Class UniquenessValidation. */ public class TemplateNameValidation implements ISyntaxValidationRule { /* (non-Javadoc) * @see com.sap.mi.textual.grammar.impl.tcs.t2m.validation.ISyntaxValidationRule#validate(TCS.ConcreteSyntax) */ @Override public void validate(ConcreteSyntax syntax, IMetaModelLookup<?> metaLookup, SemanticErrorBucket errorBucket) { Set<Collection<String>> names = new HashSet<Collection<String>>(); Collection<Template> templates = syntax.getTemplates(); MetaModelElementResolutionHelper resolutionHelper = new MetaModelElementResolutionHelper(metaLookup); for (Iterator<Template> iterator = templates.iterator(); iterator.hasNext();) { Template template = iterator.next(); if (template.getMetaReference() == null && (template.getNames() == null || template.getNames().size() == 0)) { errorBucket.addError("Template has null or empty name reference.", template); } else { if (!(template instanceof PrimitiveTemplate) && !(template instanceof FunctionTemplate)) { // Primitive and function Templates may reference a datatype more than once ResolvedNameAndReferenceBean resolutionBean; List<String> templatename; try { resolutionBean = resolutionHelper.resolve(template); templatename = resolutionBean.getNames(); } catch (NameResolutionFailedException e) { // can ignore this, as this validator is merely concerned with naming, not with resolution. templatename = template.getNames(); // in case this was a textual reference, need to compare names still if (templatename == null || templatename.size() == 0) { continue; } } if (template instanceof ClassTemplate) { ClassTemplate ct = (ClassTemplate) template; if (ct.getMode() != null) { templatename = new ArrayList<String>(templatename); // clone list before adding! templatename.add(ct.getMode()); } } if (template instanceof OperatorTemplate) { OperatorTemplate ot = (OperatorTemplate) template; for (Operator op : ot.getOperators()) { templatename = new ArrayList<String>(templatename); // clone list before adding! templatename.add(op.getName()); } } if (names.contains(templatename)) { // FIXME trying to manage multiple operatorTemplate specifications for distinct operator sets errorBucket.addError( "Duplicate template for same metamodel element " + MessageUtil.asModelName(templatename), template); } else { names.add(templatename); } } } } } }