private List<Object> applyRules(
     List<Object> treeObjects, Element newChildElementData, Element scopeElement)
     throws Exception {
   List<Rule> rules =
       ruleRepository.getRuleBywatchObjectAndWatchCategoryAndWatchSubType(
           Element.class.toString(), scopeElement.getCategory(), scopeElement.getSubType());
   for (Object o : treeObjects) {
     if (o instanceof Element && ((Element) o).getId().equals(scopeElement.getId())) {
       rootElement = (Element) o;
     }
   }
   for (Rule rule : rules) {
     System.out.println("Applying Rule :" + rule.getRuleName());
     KnowledgeBase kbase = createKnowledgeBase(rule.getRuleFile(), rule.getRuleFileType());
     StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
     StringTokenizer st = new StringTokenizer(rule.getRuleTriggerFact(), "|");
     String triggerFactPackage = st.nextToken();
     String triggerFactName = st.nextToken();
     FactType triggerFact = kbase.getFactType(triggerFactPackage, triggerFactName);
     Object triggerFactInstance = triggerFact.newInstance();
     if (rule.getRuleTriggerFactParams() != null) {
       triggerFactInstance =
           setTriggerFactInstanceParams(
               triggerFact, triggerFactInstance, rule.getRuleTriggerFactParams());
     }
     if (rule.getRuleParams() != null) {
       ksession = setSessionVariables(ksession, rule.getRuleParams());
     }
     ksession.insert(triggerFactInstance);
     ksession.insert(rootElement);
     ksession.fireAllRules();
     ksession.dispose();
   }
   return treeObjects;
 }
 public List<Element> getUniqueElementList(List<Element> ListA, List<Element> ListB) {
   for (Element eA : ListA) {
     Boolean found = false;
     for (Element eB : ListB) {
       if (eA.getId().equals(eB.getId())) {
         found = true;
         break;
       }
     }
     if (!found) {
       ListB.add(eA);
     }
   }
   return ListB;
 }
  @Override
  public EbuildleapResultObject createNewRevision(
      HomeUnitRevision currentHomeUnitRevision,
      Element newChildElement,
      ElementManifest currentElementManifest,
      Element scopeElement) {
    try {
      ero.clear();
      /*
       * validate user input
       */
      if (currentHomeUnitRevision == null || currentHomeUnitRevision.getId() == null) {
        // throw exception
        throw new Exception(
            ebuildLeapPropertiesUtil.getProperty(EbuildleapConstants.MISSING_HOMEUNITREVISION_ID));
      }

      if (newChildElement == null || newChildElement.getId() == null) {
        // throw exception
        throw new Exception(
            ebuildLeapPropertiesUtil.getProperty(EbuildleapConstants.MISSING_ELEMENT_ID));
      }

      if (currentElementManifest == null || currentElementManifest.getId() == null) {
        // throw exception
        throw new Exception(
            ebuildLeapPropertiesUtil.getProperty(EbuildleapConstants.MISSING_ELEMENTMANIFEST_ID));
      }

      if (scopeElement == null || scopeElement.getId() == null) {
        // throw exception
        throw new Exception(
            ebuildLeapPropertiesUtil.getProperty(EbuildleapConstants.MISSING_ELEMENT_ID));
      }

      /*
       * STEP 1:- Create new HomeUnitRevision in RDBMS and retrieve new
       * HomeUnitRevision ID
       */
      HomeUnitRevision currentHomeUnitRevisionData =
          homeUnitRevisionRepository.findOne(currentHomeUnitRevision.getId());
      if (currentHomeUnitRevisionData == null) {
        // Throw exception
        throw new DataRetrievalFailureException(
            ebuildLeapPropertiesUtil.getProperty(EbuildleapConstants.OBJECT_NOT_FOUND_IN_DATASTORE)
                + " - "
                + currentHomeUnitRevision.getId());
      }
      newChildElementData = elementRepository.findOne(newChildElement.getId());
      if (newChildElementData == null) {
        // Throw exception - childElement not found in RDBMS
        throw new DataRetrievalFailureException(
            ebuildLeapPropertiesUtil.getProperty(EbuildleapConstants.OBJECT_NOT_FOUND_IN_DATASTORE)
                + " - "
                + newChildElement.getId());
      } else if (elementMongoRepository.exists(newChildElementData.getId())) {
        newChildElementData = elementMongoRepository.findOne(newChildElementData.getId());
      }

      Element scopeElementData = elementRepository.findOne(scopeElement.getId());
      if (scopeElementData == null) {
        throw new DataRetrievalFailureException(
            ebuildLeapPropertiesUtil.getProperty(EbuildleapConstants.OBJECT_NOT_FOUND_IN_DATASTORE)
                + " - "
                + scopeElement.getId());
      }

      HomeUnitVersion homeUnitVersion = currentHomeUnitRevisionData.getHomeUnitVersion();

      HomeUnitRevision newRevision = new HomeUnitRevision();
      newRevision.setHomeUnitVersion(homeUnitVersion);
      newRevision.setRevisionNumber(currentHomeUnitRevisionData.getRevisionNumber() + 1);
      newRevision.setRevisionTag(
          EbuildleapConstants.AUTO_NEW_HOMEUNIT_REVISIONTAG + homeUnitVersion.getVersionTag());
      newRevision = homeUnitRevisionRepository.saveAndFlush(newRevision);
      /*
       * STEP 2:- Retrieve old HomeUnitRevision from NOSQL DB
       */
      HomeUnitRevision newMongoHomeUnitRevision =
          homeUnitRevisionMongoRepository.findOne(currentHomeUnitRevisionData.getId());
      /*
       * STEP 3:- Change the HomeUnitRevisionID and other relevant
       * properties of the HomeUnitRevision retrieved from NOSQL DB
       */
      newMongoHomeUnitRevision.setId(newRevision.getId());
      newMongoHomeUnitRevision.setRevisionTag(newRevision.getRevisionTag());
      newMongoHomeUnitRevision.setRevisionNumber(newRevision.getRevisionNumber());
      /*
       * Get the flattened list of tree containing elements connected by
       * elementmanifest
       */
      KnowledgeBase kbase = (KnowledgeBase) flattenTreeRulesKnowledge.getObject();
      StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
      List<Object> treeObjects = new ArrayList<Object>();
      ksession.setGlobal("treeObjects", treeObjects);
      ksession.insert(
          newMongoHomeUnitRevision.getHomeUnitVersion().getHomeUnit().getProduct().getElement());
      ksession.fireAllRules();
      ksession.dispose();
      /*
       * Loop thru flattened tree containing elements and elementmanifest.
       * Modify the elementmanifest by replacing old childelement with new
       * child element (**Explore the possibility of using lambdaj**)
       */
      for (Object o : treeObjects) {
        if (o instanceof ElementManifest
            && ((ElementManifest) o).getId().equals(currentElementManifest.getId())) {
          ((ElementManifest) o).setChildElement(newChildElementData);
        }
      }
      /*
       * APPLY RULES
       */
      treeObjects = applyRules(treeObjects, newChildElementData, scopeElementData);

      /*
       * Save New Revision to Mongo Repository
       */
      newMongoHomeUnitRevision = homeUnitRevisionMongoRepository.save(newMongoHomeUnitRevision);
      ArrayList<HomeUnitRevision> result = new ArrayList<HomeUnitRevision>();
      result.add(newMongoHomeUnitRevision);
      ero.setResultStatus(EbuildleapConstants.SERVICE_CALL_SUCCESSFUL);
      ero.setResult(result);
    } catch (Exception e) {
      log.debug(e.getClass() + ": " + e.getMessage(), e);
      e.printStackTrace();
      ero.setResultStatus(EbuildleapConstants.SERVICE_CALL_FAILED);
      ero.setErrCode(EbuildleapConstants.ERROR_CREATING_NEW_HOMEUNITREVISION);
      ero.setErrDescription(
          ebuildLeapPropertiesUtil.getProperty(
                  EbuildleapConstants.ERROR_CREATING_NEW_HOMEUNITREVISION)
              + " - "
              + e.getClass()
              + ": "
              + e.getMessage());
    }
    return ero;
  }