protected void notifyEvent(
      String eventId,
      DocumentModel source,
      Map<String, Serializable> options,
      String comment,
      CoreSession session) {

    EventProducer evtProducer = null;

    try {
      evtProducer = Framework.getService(EventProducer.class);
    } catch (Exception e) {
      log.error("Unable to get EventProducer to send event notification", e);
    }

    DocumentEventContext docCtx = new DocumentEventContext(session, session.getPrincipal(), source);
    options.put("category", RelationEvents.CATEGORY);
    options.put("comment", comment);

    try {
      evtProducer.fireEvent(docCtx.newEvent(eventId));
    } catch (ClientException e) {
      log.error("Error while trying to send notification message", e);
    }
  }
  @Override
  public void handleEvent(Event event) throws ClientException {

    if (!DOCUMENT_CREATED.equals(event.getName())) {
      return;
    }
    EventContext ctx = event.getContext();
    if (ctx instanceof DocumentEventContext) {
      DocumentEventContext docCtx = (DocumentEventContext) ctx;
      DocumentModel doc = docCtx.getSourceDocument();
      if (doc.isProxy() || doc.isVersion()) {
        // a proxy or version keeps the uid of the document
        // being proxied or versioned => we're not allowed
        // to modify its field.
        return;
      }
      String eventId = event.getName();
      log.debug("eventId : " + eventId);
      try {
        addUIDtoDoc(doc);
      } catch (DocumentException e) {
        log.error("Error occurred while generating UID for doc: " + doc, e);
      }
    }
  }
  protected void notifyEvent(
      CoreSession session,
      String eventId,
      Map<String, Serializable> properties,
      String comment,
      String category,
      DocumentModel dm) {

    // Default category
    if (category == null) {
      category = DocumentEventCategories.EVENT_DOCUMENT_CATEGORY;
    }

    if (properties == null) {
      properties = new HashMap<String, Serializable>();
    }

    properties.put(CoreEventConstants.REPOSITORY_NAME, session.getRepositoryName());
    properties.put(CoreEventConstants.SESSION_ID, session.getSessionId());
    properties.put(CoreEventConstants.DOC_LIFE_CYCLE, dm.getCurrentLifeCycleState());

    DocumentEventContext ctx = new DocumentEventContext(session, session.getPrincipal(), dm);

    ctx.setProperties(properties);
    ctx.setComment(comment);
    ctx.setCategory(category);

    EventProducer evtProducer = Framework.getService(EventProducer.class);
    Event event = ctx.newEvent(eventId);
    evtProducer.fireEvent(event);
  }
 public static VirusScanEventContext unwrap(DocumentEventContext docCtx) {
   if (MARKER_VALUE.equals(docCtx.getProperty(MARKER_KEY))) {
     VirusScanEventContext ctx = new VirusScanEventContext(docCtx);
     ctx.setProperties(docCtx.getProperties());
     return ctx;
   }
   return null;
 }
 protected VirusScanEventContext(DocumentEventContext evtCtx) {
   super(
       evtCtx.getCoreSession(),
       evtCtx.getPrincipal(),
       evtCtx.getSourceDocument(),
       evtCtx.getDestination());
   setProperty(MARKER_KEY, MARKER_VALUE);
 }
 public VirusScanEventContext(DocumentEventContext evtCtx, List<String> blobXPaths) {
   super(
       evtCtx.getCoreSession(),
       evtCtx.getPrincipal(),
       evtCtx.getSourceDocument(),
       evtCtx.getDestination());
   setProperty(MARKER_KEY, MARKER_VALUE);
   setProperty(VIRUS_SCAN_BLOB_XPATHS, (Serializable) blobXPaths);
 }
  @Override
  public void handleEvent(Event event) throws ClientException {

    logger.trace("In handleEvent in UpdateObjectLocationOnMove ...");

    EventContext eventContext = event.getContext();
    if (eventContext == null) {
      return;
    }

    if (!(eventContext instanceof DocumentEventContext)) {
      return;
    }
    DocumentEventContext docEventContext = (DocumentEventContext) eventContext;
    DocumentModel docModel = docEventContext.getSourceDocument();

    // If this document event involves a Relation record, does this pertain to
    // a relationship between a Movement record and a CollectionObject record?
    //
    // If not, we're not interested in processing this document event
    // in this event handler, as it will have no bearing on updating a
    // computed current location for a CollectionObject.

    //
    // (The rest of the code flow below is then identical to that which
    // is followed when this document event involves a Movement record.
    String movementCsid = "";
    Enum notificationDocumentType;
    if (documentMatchesType(docModel, RELATION_DOCTYPE)) {
      if (logger.isTraceEnabled()) {
        logger.trace(
            "An event involving a Relation document was received by UpdateObjectLocationOnMove ...");
      }
      // Get a Movement CSID from the Relation record. (If we can't
      // get it, then we don't have a pertinent relation record.)
      movementCsid =
          getCsidForDesiredDocTypeFromRelation(
              docModel, MOVEMENT_DOCTYPE, COLLECTIONOBJECT_DOCTYPE);
      if (Tools.isBlank(movementCsid)) {
        logger.warn("Could not obtain CSID for Movement record from document event.");
        logger.warn(NO_FURTHER_PROCESSING_MESSAGE);
        return;
      }
      notificationDocumentType = EventNotificationDocumentType.RELATION;
    } else if (documentMatchesType(docModel, MOVEMENT_DOCTYPE)) {
      // Otherwise, get a Movement CSID directly from the Movement record.
      if (logger.isTraceEnabled()) {
        logger.trace(
            "An event involving a Movement document was received by UpdateObjectLocationOnMove ...");
      }
      // FIXME: exclude creation events for Movement records here, if we can
      // identify that we'l still be properly handling creation events
      // that include a relations list as part of the creation payload,
      // perhaps because that may trigger a separate event notification.
      movementCsid = NuxeoUtils.getCsid(docModel);
      if (Tools.isBlank(movementCsid)) {
        logger.warn("Could not obtain CSID for Movement record from document event.");
        logger.warn(NO_FURTHER_PROCESSING_MESSAGE);
        return;
      }
      notificationDocumentType = EventNotificationDocumentType.MOVEMENT;
    } else {
      if (logger.isTraceEnabled()) {
        logger.trace(
            "This event did not involve a document relevant to UpdateObjectLocationOnMove ...");
      }
      return;
    }

    // Note: currently, all Document lifecycle transitions on
    // the relevant doctype(s) are handled by this event handler,
    // not just transitions between 'soft deleted' and active states.
    //
    // We are assuming that we'll want to re-compute current locations
    // for related CollectionObjects on all such transitions, as the
    // semantics of such transitions are opaque to this event handler,
    // because arbitrary workflows can be bound to those doctype(s).
    //
    // If we need to filter out some of those lifecycle transitions,
    // such as excluding transitions to the 'locked' workflow state; or,
    // alternately, if we want to restrict this event handler's
    // scope to handle only transitions into the 'soft deleted' state,
    // we can add additional checks for doing so at this point in the code.

    // For debugging
    if (logger.isTraceEnabled()) {
      logger.trace("Movement CSID=" + movementCsid);
      logger.trace("Notification document type=" + notificationDocumentType.name());
    }

    CoreSession coreSession = docEventContext.getCoreSession();
    Set<String> collectionObjectCsids = new HashSet<>();

    if (notificationDocumentType == EventNotificationDocumentType.RELATION) {
      String relatedCollectionObjectCsid =
          getCsidForDesiredDocTypeFromRelation(
              docModel, COLLECTIONOBJECT_DOCTYPE, MOVEMENT_DOCTYPE);
      collectionObjectCsids.add(relatedCollectionObjectCsid);
    } else if (notificationDocumentType == EventNotificationDocumentType.MOVEMENT) {
      collectionObjectCsids.addAll(
          getCollectionObjectCsidsRelatedToMovement(movementCsid, coreSession));
    }

    if (collectionObjectCsids.isEmpty()) {
      logger.warn("Could not obtain any CSIDs of related CollectionObject records.");
      logger.warn(NO_FURTHER_PROCESSING_MESSAGE);
      return;
    } else {
      if (logger.isTraceEnabled()) {
        logger.trace(
            "Found "
                + collectionObjectCsids.size()
                + " CSIDs of related CollectionObject records.");
      }
    }
    // Iterate through the list of CollectionObject CSIDs found.
    // For each CollectionObject, obtain its most recent, related Movement,
    // and update relevant field(s) with values from that Movement record.
    DocumentModel collectionObjectDocModel;
    DocumentModel mostRecentMovementDocModel;
    for (String collectionObjectCsid : collectionObjectCsids) {
      if (logger.isTraceEnabled()) {
        logger.trace("CollectionObject CSID=" + collectionObjectCsid);
      }
      // Verify that the CollectionObject is retrievable.
      collectionObjectDocModel = getDocModelFromCsid(coreSession, collectionObjectCsid);
      if (collectionObjectDocModel == null) {
        continue;
      }
      // Verify that the CollectionObject record is active.
      if (!isActiveDocument(collectionObjectDocModel)) {
        continue;
      }
      // Get the CollectionObject's most recent, related Movement.
      mostRecentMovementDocModel = getMostRecentMovement(coreSession, collectionObjectCsid);
      if (mostRecentMovementDocModel == null) {
        continue;
      }
      // Update the CollectionObject with values from that Movement.
      collectionObjectDocModel =
          updateCollectionObjectValuesFromMovement(
              collectionObjectDocModel, mostRecentMovementDocModel);
      coreSession.saveDocument(collectionObjectDocModel);
    }
  }