コード例 #1
0
 /**
  * Finds the next {@link ForEachExecution} in the collection iterated by <code>
  * foreachContextIterator</code> that is for the same {@link DelayedReference#getQueryElement()
  * property init} as the <code>reference</code> and that is for the same {@link
  * ForEachExecution#getSourceModelElement() source element} as the <code>reference</code>. If no
  * such element is found, <code>null</code> is returned
  *
  * <p>Postcondition: if a non-<code>null</code> result is returned, the <code>
  * foreachContextIterator</code> is at that element so that calling {@link Iterator#remove()}
  * removes the element just returned
  *
  * @param foreachContextIterator must not be <code>null</code>
  */
 private ForEachExecution getNextForeachContext(
     Iterator<ForEachExecution> foreachContextIterator, DelayedReference reference) {
   ForEachExecution result = null;
   while (foreachContextIterator.hasNext() && result == null) {
     ForEachExecution fec = foreachContextIterator.next();
     if (fec.getForeachPedicatePropertyInit().equals(reference.getQueryElement())
         && reference.getModelElement().equals(fec.getSourceModelElement())) {
       result = fec;
     }
   }
   return result;
 }
コード例 #2
0
 private ForEachExecution produceNewForEachContext(
     DelayedReference reference, ForeachProductionResult producedResult) {
   ForEachExecution newContext = TextblocksFactory.eINSTANCE.createForEachExecution();
   newContext.setForeachPedicatePropertyInit(
       (ForeachPredicatePropertyInit) reference.getQueryElement());
   newContext.setSourceModelElement((EObject) reference.getModelElement());
   newContext.setContextElement(
       (EObject) producedResult.getForeachExpressionResultForWhichProduced());
   newContext.setTemplateUsedForProduction(producedResult.getTemplateUsedForProduction());
   newContext.setResultModelElement((EObject) reference.getRealValue());
   return newContext;
 }
コード例 #3
0
 /**
  * For a {@link ForEachExecution} that is known to be for the same source element and <code>
  * foreach</code> clause as <code>producedResult</code>, checks if the template used by the
  * previous execution as documented by <code>nextOldForeachContext</code> is the same as that used
  * in <code>producedResult</code>.
  */
 private boolean isTargetElementReusable(
     ForEachExecution nextOldForeachContext, ForeachProductionResult producedResult) {
   return nextOldForeachContext.getTemplateUsedForProduction()
       == producedResult.getTemplateUsedForProduction();
 }
コード例 #4
0
 /**
  * A <code>foreach</code> expression was (re-)evaluated, and for each result, based on any <code>
  * when</code>/ <code>as</code> {@link com.sap.furcas.metamodel.FURCAS.TCS.PredicateSemantic}
  * elements, the corresponding template's production rule was executed by the parser. This
  * produced a {@link ModelElementProxy} which has not yet been turned into a real {@link EObject}
  * yet nor has it been entered into the target feature.
  *
  * <p>Prior executions of the same <code>foreach</code> predicate on the same source model element
  * may have happened. In this case, there will be {@link ForEachExecution} records documenting
  * this. If no such records are found, all proxies produced will be materialized as {@link
  * EObject}s and {@link #setReference(DelayedReference, Object, IModelAdapter, ModelElementProxy,
  * IModelInjector, int) added/set} to/into the target feature described by the <code>reference
  * </code>.
  *
  * <p>If {@link ForEachExecution} objects are found for the source element and <code>foreach
  * </code> predicate, their {@link ForEachExecution#getResultModelElement() result elements} are
  * obtained and compared to the new {@link ForeachProductionResult production instructions} which
  * also contain the {@link Template} used to produce the target element. The template is used to
  * compare the element types in order to try to re-use already existing elements.
  *
  * <p>In case a target object from a prior evaluation can be re-used, it is set as the proxy's
  * {@link ModelElementProxy#setRealObject(Object) real object}, and no new target object is
  * created for this <code>foreach</code> result. Otherwise, a new target object is created. The
  * re-used or created object is then used to replace (single multiplicity) or to add to
  * (many-multiplicity) the target feature.
  *
  * <p>As to the re-use strategy, we distinguish between re-using the {@link ForEachExecution} hull
  * only and the {@link ForEachExecution#getResultModelElement() result element} that was produced
  * in an earlier run. Two element collections are compared, namely those listed as {@link
  * ForEachExecution#getResultModelElement() result elements} of earlier evaluations on the <code>
  * reference</code>'s {@link DelayedReference#getTextBlock() text block} for the same <code>
  * foreach</code> predicate; and those described by <code>producedResults</code> which contains
  * proxies and the templates telling the types and modes with which they were created. The two
  * collections are iterated in parallel. If the {@link ForEachExecution}'s template matches that
  * in the current <code>producedResults</code> element, the {@link
  * ForEachExecution#getResultModelElement() old result element} is re-used by {@link
  * ModelElementProxy#setRealObject(Object) setting} it on the proxy. Otherwise, a new element is
  * produced using {@link ModelInjector#createOrResolve(ModelElementProxy, ANTLR3LocationToken,
  * ANTLR3LocationToken)} and the existing {@link ForEachExecution} is updated for the new result
  * element, template, etc. If the collection of {@link ForEachExecution} elements is shorter than
  * that of the <code>producedResults</code>, additional {@link ForEachExecution} elements are
  * added to the <code>reference</code>'s {@link TextBlock#getForEachExecutions() textblock's
  * foreach context list}. Extraneous elements are deleted from it.
  *
  * <p>It's obvious that there may be more sophisticated re-use strategies based on longest
  * sequence etc., but those may be added later.
  *
  * @param injector TODO
  * @param producedResults the {@link ForeachProductionResult#getTemplateUsedForProduction()
  *     templates} need to be set only if text blocks are being produced by the parser run
  */
 private void setReferenceAndUpdateForeachContexts(
     DelayedReference reference,
     IModelAdapter modelAdapter,
     IModelInjector injector,
     List<ForeachProductionResult> producedResults)
     throws ModelElementCreationException, ModelAdapterException {
   Iterator<ForEachExecution> foreachContextIterator = null;
   ForEachExecution nextOldForeachContext = null;
   if (reference.getTextBlock() != null) {
     foreachContextIterator =
         ((TextBlock) reference.getTextBlock()).getForEachExecutions().iterator();
     nextOldForeachContext = getNextForeachContext(foreachContextIterator, reference);
   }
   int i = 0;
   for (ForeachProductionResult producedResult : producedResults) {
     // check for a re-usable target element of ForEachContext with its result element
     if (nextOldForeachContext != null
         && isTargetElementReusable(nextOldForeachContext, producedResult)) {
       // re-use the target object referenced by the ForEachContext and the ForEachContext itself
       producedResult
           .getProducedProxy()
           .setRealObject(nextOldForeachContext.getResultModelElement());
       if (producedResult.getForeachExpressionResultForWhichProduced() instanceof EObject) {
         nextOldForeachContext.setContextElement(
             (EObject) producedResult.getForeachExpressionResultForWhichProduced());
       } else if (producedResult.getForeachExpressionResultForWhichProduced() instanceof EObject) {
         nextOldForeachContext.setContextString(
             (String) producedResult.getForeachExpressionResultForWhichProduced());
       }
       reference.setRealValue(nextOldForeachContext.getResultModelElement());
     } else {
       // target element is not re-usable, a new one needs to be produced
       setReference(
           reference,
           producedResult.getForeachExpressionResultForWhichProduced(),
           modelAdapter,
           producedResult.getProducedProxy(),
           injector,
           i);
       if (reference.getTextBlock() != null
           && producedResult.getTemplateUsedForProduction() != null) {
         // if we have a ForEachContext element for the current source element and foreach
         // predicate,
         // re-use and update it:
         if (nextOldForeachContext == null) {
           // no ForEachContext element; produce a new one and append
           ForEachExecution newContext = produceNewForEachContext(reference, producedResult);
           ((TextBlock) reference.getTextBlock()).getForEachExecutions().add(newContext);
         } else {
           // ForEachContext names a template/element that can't be re-used; update it
           // correspondingly
           Object result = producedResult.getForeachExpressionResultForWhichProduced();
           if (result instanceof EObject) {
             nextOldForeachContext.setContextElement(
                 (EObject) producedResult.getForeachExpressionResultForWhichProduced());
           } else if (result instanceof String) {
             nextOldForeachContext.setContextString(
                 (String) producedResult.getForeachExpressionResultForWhichProduced());
           }
           nextOldForeachContext.setTemplateUsedForProduction(
               producedResult.getTemplateUsedForProduction());
           nextOldForeachContext.setResultModelElement(
               (EObject) producedResult.getProducedProxy().getRealObject());
         }
       }
     }
     if (nextOldForeachContext != null
         && foreachContextIterator != null
         && foreachContextIterator.hasNext()) {
       nextOldForeachContext = foreachContextIterator.next();
     } else {
       nextOldForeachContext = null;
     }
     i++;
   }
   // delete remaining old ForEachContext entries from reference's textblock
   while (nextOldForeachContext != null) {
     foreachContextIterator.remove();
     nextOldForeachContext = getNextForeachContext(foreachContextIterator, reference);
   }
 }