/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.camunda.bpm.engine.impl.cmmn.handler;

import java.util.Collection;
import java.util.logging.Logger;

import org.camunda.bpm.engine.delegate.Expression;
import org.camunda.bpm.engine.impl.cmmn.model.CmmnActivity;
import org.camunda.bpm.engine.impl.cmmn.model.CmmnIfPartDeclaration;
import org.camunda.bpm.engine.impl.cmmn.model.CmmnOnPartDeclaration;
import org.camunda.bpm.engine.impl.cmmn.model.CmmnSentryDeclaration;
import org.camunda.bpm.engine.impl.el.ExpressionManager;
import org.camunda.bpm.model.cmmn.PlanItemTransition;
import org.camunda.bpm.model.cmmn.impl.instance.ConditionExpression;
import org.camunda.bpm.model.cmmn.instance.CaseFileItemOnPart;
import org.camunda.bpm.model.cmmn.instance.IfPart;
import org.camunda.bpm.model.cmmn.instance.OnPart;
import org.camunda.bpm.model.cmmn.instance.PlanItem;
import org.camunda.bpm.model.cmmn.instance.PlanItemOnPart;
import org.camunda.bpm.model.cmmn.instance.Sentry;

/**
 * @author Roman Smirnov
 *
 */
public class SentryHandler extends CmmnElementHandler<Sentry, CmmnSentryDeclaration> {

  private static final Logger LOGGER = Logger.getLogger(SentryHandler.class.getName());

  public CmmnSentryDeclaration handleElement(Sentry element, CmmnHandlerContext context) {

    String id = element.getId();
    Collection<OnPart> onParts = element.getOnParts();
    IfPart ifPart = element.getIfPart();

    if (ifPart == null || ifPart.getConditions().isEmpty()) {

      if (onParts == null || onParts.isEmpty()) {
        LOGGER.info("Sentry with id '"+id+"' will be ignored because there are defined no ifPart nor onParts with a condition.");
        return null;
      } else {
        boolean atLeastOneOnPartsValid = false;

        for (OnPart onPart : onParts) {
          if (onPart instanceof PlanItemOnPart) {
            PlanItemOnPart planItemOnPart = (PlanItemOnPart) onPart;
            if (planItemOnPart.getSource() != null && planItemOnPart.getStandardEvent() != null) {
              atLeastOneOnPartsValid = true;
              break;
            }
          }
        }

        if (!atLeastOneOnPartsValid) {
          LOGGER.info("Sentry with id '"+id+"' will be ignored because there are defined no ifPart and all onParts are not valid.");
          return null;
        }
      }
    }

    if ((onParts == null || onParts.isEmpty())
        && (ifPart == null || ifPart.getConditions().isEmpty())) {
    }

    CmmnSentryDeclaration sentryDeclaration = new CmmnSentryDeclaration(id);

    // the ifPart will initialized immediately
    initializeIfPart(ifPart, sentryDeclaration, context);

    // ...whereas the onParts will be initialized later because the
    // the reference to the plan items (sourceRef) and the reference
    // to the sentry (sentryRef) cannot be set in this step. To set
    // the corresponding reference (sourceRef or sentryRef) on the
    // transformed sentry all planned items and all sentries inside
    // the current stage should be already transformed.

    CmmnActivity parent = context.getParent();
    if (parent != null) {
      parent.addSentry(sentryDeclaration);
    }

    return sentryDeclaration;
  }

  public void initializeOnParts(Sentry sentry, CmmnHandlerContext context) {
    Collection<OnPart> onParts = sentry.getOnParts();
    for (OnPart onPart : onParts) {
      if (onPart instanceof PlanItemOnPart) {
        initializeOnPart((PlanItemOnPart) onPart, sentry, context);
      } else {
        initializeOnPart((CaseFileItemOnPart) onPart, sentry, context);
      }
    }
  }

  protected void initializeOnPart(PlanItemOnPart onPart, Sentry sentry, CmmnHandlerContext context) {
    CmmnActivity parent = context.getParent();
    String sentryId = sentry.getId();
    CmmnSentryDeclaration sentryDeclaration = parent.getSentry(sentryId);

    PlanItem source = onPart.getSource();
    PlanItemTransition standardEvent = onPart.getStandardEvent();

    if (source != null && standardEvent != null) {
      CmmnOnPartDeclaration onPartDeclaration = new CmmnOnPartDeclaration();

      // initialize standardEvent
      String standardEventName = standardEvent.name();
      onPartDeclaration.setStandardEvent(standardEventName);

      // initialize sourceRef
      String sourceId = source.getId();
      CmmnActivity sourceActivity = parent.findActivity(sourceId);

      if (sourceActivity != null) {
        onPartDeclaration.setSource(sourceActivity);
      }

      // initialize sentryRef
      Sentry sentryRef = onPart.getSentry();
      if (sentryRef != null) {
        String sentryRefId = sentryRef.getId();

        CmmnSentryDeclaration sentryRefDeclaration = parent.getSentry(sentryRefId);
        onPartDeclaration.setSentry(sentryRefDeclaration);
      }

      // add onPartDeclaration to sentryDeclaration
      sentryDeclaration.addOnPart(onPartDeclaration);
    }

  }

  protected void initializeOnPart(CaseFileItemOnPart onPart, Sentry sentry, CmmnHandlerContext context) {
    // not yet implemented
    String id = sentry.getId();
    LOGGER.info("The onPart based on CaseFileItem of Sentry with id '"+id+"' is not supported and will be ignored.");
  }

  protected void initializeIfPart(IfPart ifPart, CmmnSentryDeclaration sentryDeclaration, CmmnHandlerContext context) {
    if (ifPart == null) {
      return;
    }

    Collection<ConditionExpression> conditions = ifPart.getConditions();

    if (conditions.size() > 1) {
      String id = sentryDeclaration.getId();
      LOGGER.info("The ifPart of Sentry with id '"+id+"' has more than one condition: only the first condition will be used, the other conditions will be ignored.");
    }

    ExpressionManager expressionManager = context.getExpressionManager();
    ConditionExpression condition = conditions.iterator().next();
    Expression conditionExpression = expressionManager.createExpression(condition.getBody());

    CmmnIfPartDeclaration ifPartDeclaration = new CmmnIfPartDeclaration();
    ifPartDeclaration.setCondition(conditionExpression);
    sentryDeclaration.setIfPart(ifPartDeclaration);
  }

}

@@ -2842,129 +2842,8 @@
  %7D%0A%0A
-    if ((onParts == null %7C%7C onParts.isEmpty())%0A        && (ifPart == null %7C%7C ifPart.getConditions().isEmpty())) %7B%0A    %7D%0A%0A
     

remove leftover code