private ModelElementProxy produceSingleForeachUsingParserRule( ObservableInjectingParser parser, DelayedReference reference, Object next, String ruleName) throws NoSuchMethodException, UnknownProductionRuleException, IllegalAccessException, InvocationTargetException, ModelElementCreationException { // invoke the parser to execute the template Method methodToCall = parser.getClass().getMethod(ruleName); // parser.reset(); if (!Modifier.isFinal(methodToCall.getModifiers())) { throw new UnknownProductionRuleException( ruleName + " is not a production rule in generated Parser."); } boolean originalResolveProxiesValue = parser.isResolveProxies(); parser.setResolveProxies(false); DelegationParsingObserver delegator = new DelegationParsingObserver(); IParsingObserver originalObserver = parser.getObserver(); if (originalObserver != null) { delegator.addParsingObserver(originalObserver); } delegator.addParsingObserver(new ForeachParsingObserver((TextBlock) reference.getTextBlock())); parser.setObserver(delegator); IModelElementProxy proxyForContextElement = null; if (reference.getContextElement() instanceof IModelElementProxy) { proxyForContextElement = (IModelElementProxy) reference.getContextElement(); } else { proxyForContextElement = new ResolvedModelElementProxy(reference.getContextElement()); } parser.setCurrentForeachElement(next); if (parser.getContextManager().getContextForElement(reference.getContextElement()) == null) { parser.addContext(proxyForContextElement); if (proxyForContextElement.getRealObject() != null && reference.getContextElement() instanceof EObject) { parser .getContextManager() .notifyProxyResolvedWith( proxyForContextElement, reference.getContextElement(), /* * no creation context element needs to be provided here because the proxy has just been created and has not been * added to any other context */ null); } } else { parser .getCurrentContextStack() .push(proxyForContextElement); // the Context object was already created elsewhere } try { ModelElementProxy parseReturn = (ModelElementProxy) methodToCall.invoke(parser); if (parseReturn == null) { throw new ModelElementCreationException( "Unable to create model element using parse rule " + ruleName + ". Parse errors: " + parser.getInjector().getErrorList()); } return parseReturn; } finally { parser.getCurrentContextStack().pop(); parser.setObserver(originalObserver); parser.setResolveProxies(originalResolveProxiesValue); } }
private boolean setDelayedReferenceWithPredicate( DelayedReference reference, IModelAdapter modelAdapter, ContextManager contextManager, Object contextElement, ObservableInjectingParser parser) throws ModelAdapterException { try { contextElement = DelayedReferencesHelper.getNavigatedContextElementFromReference( reference, modelAdapter, contextManager, contextElement); // when the element is a Proxy resolve it first resolveModelElementProxy(reference, modelAdapter); if (reference.getOclQuery() == null) { parser .getInjector() .addError(new ParsingError("You must specify an OCL query.", reference.getToken())); return false; } Collection<?> result = DelayedReferencesHelper.evaluateForeachOcl( (EObject) reference.getModelElement(), reference, modelAdapter, contextElement); List<ForeachProductionResult> producedResults = new ArrayList<ForeachProductionResult>(); // loop over the results to handle them one by one, // delete all elements that were created by this foreach but are // not valid anymore String mode = reference.getMode(); IRuleName ruleNameFinder = reference.getRuleNameFinder(); for (Object singleForeachResult : result) { if (!(singleForeachResult instanceof Boolean) || ((Boolean) singleForeachResult).booleanValue()) { // look if there are possible when/as constructs PredicateSemantic activePredicateSemantic = getActivePredicateFromWhenAsClauses( reference, modelAdapter, contextElement, singleForeachResult); Template templateUsedForProduction = getTemplateFromPredicateSemantic(activePredicateSemantic, reference); // TODO it would be nice to compute the rule name from the template; however, if no // textblocks are being produced, the reference doesn't have the link to the // ForeachPropertyInit set, so the template can't be determined and isn't passed in by the // parser run; only the rule name is passed String parserRuleNameToUseForProduction = computeRuleName( parser, singleForeachResult, activePredicateSemantic, mode, ruleNameFinder); if (parserRuleNameToUseForProduction == null) { throw new UnknownProductionRuleException( "At least one as parameter is needed in that case."); } ModelElementProxy foreachTargetElement = produceForOneForeachResult( reference, modelAdapter, contextElement, parser, singleForeachResult, activePredicateSemantic, parserRuleNameToUseForProduction); ForeachProductionResult resultObject = new ForeachProductionResult( foreachTargetElement, templateUsedForProduction, singleForeachResult); producedResults.add(resultObject); } } setReferenceAndUpdateForeachContexts( reference, modelAdapter, parser.getInjector(), producedResults); } catch (Exception e) { parser.getInjector().addError(new ParsingError(e.getMessage(), reference.getToken())); return false; } return true; }