Search in sources :

Example 6 with CreateDocument

use of io.lumeer.engine.api.event.CreateDocument in project engine by Lumeer.

the class AssigneeChangeDetector method detectChanges.

@Override
public void detectChanges(final DocumentEvent documentEvent, final Collection collection) {
    final CollectionPurpose purpose = collection.getPurpose();
    final String assigneeAttr = purpose.getAssigneeAttributeId();
    final boolean doneState = isDoneState(documentEvent, collection);
    if (StringUtils.isNotEmpty(assigneeAttr) && isAttributeChanged(documentEvent, assigneeAttr)) {
        if (!(documentEvent instanceof CreateDocument)) {
            // delete previous due date and assignee events on the document
            delayedActionDao.deleteScheduledActions(getResourcePath(documentEvent), Set.of(NotificationType.DUE_DATE_SOON, NotificationType.PAST_DUE_DATE, NotificationType.TASK_ASSIGNED, NotificationType.TASK_REOPENED, NotificationType.DUE_DATE_CHANGED));
            if (!(documentEvent instanceof RemoveDocument) && !doneState) {
                final ZonedDateTime dueDate = getDueDate(documentEvent, collection);
                if (dueDate != null) {
                    delayedActionDao.scheduleActions(getDelayedActions(documentEvent, collection, NotificationType.PAST_DUE_DATE, dueDate));
                    if (dueDate.minus(DUE_DATE_SOON_DAYS, ChronoUnit.DAYS).isAfter(ZonedDateTime.now())) {
                        delayedActionDao.scheduleActions(getDelayedActions(documentEvent, collection, NotificationType.DUE_DATE_SOON, dueDate.minus(DUE_DATE_SOON_DAYS, ChronoUnit.DAYS)));
                    }
                }
            }
        }
        if (documentEvent instanceof UpdateDocument) {
            delayedActionDao.scheduleActions(getDelayedActions(documentEvent, collection, NotificationType.TASK_UNASSIGNED, nowPlus(), getRemovedAssignees(documentEvent, collection)));
        }
        if (!(documentEvent instanceof RemoveDocument) && !doneState) {
            // create new due date events on the document
            delayedActionDao.scheduleActions(getDelayedActions(documentEvent, collection, NotificationType.TASK_ASSIGNED, nowPlus(), getAddedAssignees(documentEvent, collection)));
        }
    }
}
Also used : RemoveDocument(io.lumeer.engine.api.event.RemoveDocument) ZonedDateTime(java.time.ZonedDateTime) UpdateDocument(io.lumeer.engine.api.event.UpdateDocument) CreateDocument(io.lumeer.engine.api.event.CreateDocument) CollectionPurpose(io.lumeer.api.model.CollectionPurpose)

Example 7 with CreateDocument

use of io.lumeer.engine.api.event.CreateDocument in project engine by Lumeer.

the class SingleStage method commitDocumentOperations.

private List<Document> commitDocumentOperations(final List<DocumentOperation> operations, final List<Document> createdDocuments, final Map<String, Collection> collectionsMapForCreatedDocuments) {
    if (operations.isEmpty() && collectionsMapForCreatedDocuments.isEmpty()) {
        return List.of();
    }
    final FunctionFacade functionFacade = task.getFunctionFacade();
    final TaskProcessingFacade taskProcessingFacade = task.getTaskProcessingFacade(taskExecutor, functionFacade);
    final PurposeChangeProcessor purposeChangeProcessor = task.getPurposeChangeProcessor();
    // Collection -> [Document]
    final Map<String, List<Document>> updatedDocuments = new HashMap<>();
    Map<String, Set<String>> documentIdsByCollection = operations.stream().map(Operation::getEntity).collect(Collectors.groupingBy(Document::getCollectionId, mapping(Document::getId, toSet())));
    final Map<String, Collection> collectionsMap = task.getDaoContextSnapshot().getCollectionDao().getCollectionsByIds(documentIdsByCollection.keySet()).stream().collect(Collectors.toMap(Collection::getId, coll -> coll));
    final Set<String> collectionsChanged = new HashSet<>();
    Map<String, Document> documentsByCorrelationId = createdDocuments.stream().collect(Collectors.toMap(doc -> doc.createIfAbsentMetaData().getString(Document.META_CORRELATION_ID), Function.identity()));
    // aggregate all operations to individual documents
    final Map<String, List<DocumentOperation>> changesByDocumentId = Utils.categorize(operations.stream(), change -> change.getEntity().getId());
    final Set<String> unprocessedCreatedDocuments = createdDocuments.stream().map(Document::getId).collect(toSet());
    createdDocuments.forEach(document -> {
        final Collection collection = collectionsMap.get(document.getCollectionId());
        final DataDocument newDataDecoded = constraintManager.encodeDataTypes(collection, document.getData());
        auditAdapter.registerCreate(collection.getId(), ResourceType.DOCUMENT, document.getId(), task.getInitiator(), automationName, null, newDataDecoded);
    });
    changesByDocumentId.forEach((id, changeList) -> {
        unprocessedCreatedDocuments.remove(id);
        final Document document = changeList.get(0).getEntity();
        final Document originalDocument = (task instanceof RuleTask) ? ((RuleTask) task).getOldDocument() : ((task instanceof FunctionTask) ? ((FunctionTask) task).getOriginalDocumentOrDefault(id, changeList.get(0).getOriginalDocument()) : changeList.get(0).getOriginalDocument());
        final Collection collection = collectionsMap.get(document.getCollectionId());
        final DataDocument aggregatedUpdate = new DataDocument();
        changeList.forEach(change -> aggregatedUpdate.put(change.getAttrId(), change.getValue()));
        final DataDocument newData = constraintManager.encodeDataTypes(collection, aggregatedUpdate);
        final DataDocument oldData = originalDocument != null ? new DataDocument(originalDocument.getData()) : new DataDocument();
        Set<String> attributesIdsToAdd = new HashSet<>(newData.keySet());
        attributesIdsToAdd.removeAll(oldData.keySet());
        if (attributesIdsToAdd.size() > 0) {
            collection.getAttributes().stream().filter(attr -> attributesIdsToAdd.contains(attr.getId())).forEach(attr -> {
                attr.setUsageCount(attr.getUsageCount() + 1);
                collection.setLastTimeUsed(ZonedDateTime.now());
                collectionsChanged.add(collection.getId());
            });
        }
        document.setUpdatedBy(task.getInitiator().getId());
        document.setUpdateDate(ZonedDateTime.now());
        final DataDocument beforePatch = task.getDaoContextSnapshot().getDataDao().getData(document.getCollectionId(), document.getId());
        DataDocument patchedData = task.getDaoContextSnapshot().getDataDao().patchData(document.getCollectionId(), document.getId(), newData);
        Document updatedDocument = task.getDaoContextSnapshot().getDocumentDao().updateDocument(document.getId(), document);
        updatedDocument.setData(patchedData);
        // notify delayed actions about data change
        if (collection.getPurposeType() == CollectionPurposeType.Tasks) {
            final Document original;
            if (originalDocument == null) {
                // when triggered by an action button, let's use the document from db
                original = new Document(document);
                original.setData(beforePatch);
            } else {
                original = originalDocument;
            }
            purposeChangeProcessor.processChanges(new UpdateDocument(updatedDocument, original), collection);
        }
        var oldDataDecoded = constraintManager.decodeDataTypes(collection, beforePatch);
        var patchedDataDecoded = constraintManager.decodeDataTypes(collection, patchedData);
        auditAdapter.registerDataChange(updatedDocument.getCollectionId(), ResourceType.DOCUMENT, updatedDocument.getId(), task.getInitiator(), automationName, null, beforePatch, oldDataDecoded, patchedData, patchedDataDecoded);
        // add patched data to new documents
        boolean created = false;
        if (StringUtils.isNotEmpty(document.createIfAbsentMetaData().getString(Document.META_CORRELATION_ID))) {
            final Document doc = documentsByCorrelationId.get(document.getMetaData().getString(Document.META_CORRELATION_ID));
            if (doc != null) {
                doc.setData(patchedData);
                created = true;
            }
        }
        if (task instanceof RuleTask) {
            if (created) {
                taskProcessingFacade.onCreateDocument(new CreateDocument(updatedDocument));
            } else {
                if (task.getRecursionDepth() == 0) {
                    // there are now 3 versions of the document:
                    // 1) the document before user triggered an update - original document (null when triggered by action button)
                    // 2) the document with the new user entered value - before patch
                    // 3) the document with the value computed by the rule based on the previous two - updated document
                    // this rule got executed because of change from 1 to 2
                    // for the recursive rules, we need to trigger rules for changes between 2 and 3
                    final UpdateDocument updateDocumentEvent;
                    final Document orig = new Document(document);
                    orig.setData(beforePatch);
                    updateDocumentEvent = new UpdateDocument(updatedDocument, orig);
                    taskProcessingFacade.onDocumentUpdate(updateDocumentEvent, ((RuleTask) task).getRule().getName());
                } else {
                    taskExecutor.submitTask(functionFacade.createTaskForUpdateDocument(collection, originalDocument, updatedDocument, aggregatedUpdate.keySet()));
                }
            }
        }
        patchedData = constraintManager.decodeDataTypes(collection, patchedData);
        updatedDocument.setData(patchedData);
        updatedDocuments.computeIfAbsent(document.getCollectionId(), key -> new ArrayList<>()).add(updatedDocument);
    });
    unprocessedCreatedDocuments.forEach(id -> {
        createdDocuments.stream().filter(d -> d.getId().equals(id)).findFirst().ifPresent(document -> {
            taskProcessingFacade.onCreateDocument(new CreateDocument(document));
        });
    });
    changesTracker.addCollections(collectionsChanged.stream().map(collectionsMap::get).collect(toSet()));
    changesTracker.addUpdatedDocuments(updatedDocuments.values().stream().flatMap(java.util.Collection::stream).collect(toSet()));
    changesTracker.updateCollectionsMap(collectionsMapForCreatedDocuments);
    changesTracker.updateCollectionsMap(collectionsMap);
    collectionsChanged.forEach(collectionId -> task.getDaoContextSnapshot().getCollectionDao().updateCollection(collectionId, collectionsMap.get(collectionId), null, false));
    return updatedDocuments.values().stream().flatMap(java.util.Collection::stream).collect(toList());
}
Also used : TaskExecutor(io.lumeer.core.task.TaskExecutor) PrintTextOperation(io.lumeer.core.task.executor.operation.PrintTextOperation) ZonedDateTime(java.time.ZonedDateTime) Operation(io.lumeer.core.task.executor.operation.Operation) StringUtils(org.apache.commons.lang3.StringUtils) CreateLinkInstance(io.lumeer.engine.api.event.CreateLinkInstance) UserMessageOperation(io.lumeer.core.task.executor.operation.UserMessageOperation) GenericPrintRequest(io.lumeer.core.task.executor.request.GenericPrintRequest) ResourceType(io.lumeer.api.model.ResourceType) Map(java.util.Map) FunctionTask(io.lumeer.core.task.FunctionTask) FunctionFacade(io.lumeer.core.facade.FunctionFacade) DocumentOperation(io.lumeer.core.task.executor.operation.DocumentOperation) DataDocument(io.lumeer.engine.api.data.DataDocument) Document(io.lumeer.api.model.Document) CreateDocument(io.lumeer.engine.api.event.CreateDocument) Set(java.util.Set) Collectors(java.util.stream.Collectors) LinkInstance(io.lumeer.api.model.LinkInstance) PurposeChangeProcessor(io.lumeer.core.facade.detector.PurposeChangeProcessor) LinkType(io.lumeer.api.model.LinkType) PrintAttributeOperation(io.lumeer.core.task.executor.operation.PrintAttributeOperation) List(java.util.List) SendEmailOperation(io.lumeer.core.task.executor.operation.SendEmailOperation) Optional(java.util.Optional) Utils(io.lumeer.core.util.Utils) ChangesTracker(io.lumeer.core.task.executor.ChangesTracker) LinkOperation(io.lumeer.core.task.executor.operation.LinkOperation) DocumentCreationOperation(io.lumeer.core.task.executor.operation.DocumentCreationOperation) SendEmailRequest(io.lumeer.core.task.executor.request.SendEmailRequest) HashMap(java.util.HashMap) Function(java.util.function.Function) ArrayList(java.util.ArrayList) NavigationOperation(io.lumeer.core.task.executor.operation.NavigationOperation) HashSet(java.util.HashSet) TaskProcessingFacade(io.lumeer.core.facade.TaskProcessingFacade) LinkCreationOperation(io.lumeer.core.task.executor.operation.LinkCreationOperation) DocumentRemovalOperation(io.lumeer.core.task.executor.operation.DocumentRemovalOperation) LinkTypeUtils(io.lumeer.core.util.LinkTypeUtils) CollectionPurposeType(io.lumeer.api.model.CollectionPurposeType) UserMessageRequest(io.lumeer.core.task.executor.request.UserMessageRequest) NavigationRequest(io.lumeer.core.task.executor.request.NavigationRequest) LinkTypeAdapter(io.lumeer.core.adapter.LinkTypeAdapter) DocumentUtils(io.lumeer.core.util.DocumentUtils) UpdateLinkInstance(io.lumeer.engine.api.event.UpdateLinkInstance) RuleTask(io.lumeer.core.task.RuleTask) OperationExecutor(io.lumeer.core.task.executor.operation.OperationExecutor) UpdateDocument(io.lumeer.engine.api.event.UpdateDocument) AutoLinkBatchTask(io.lumeer.core.task.AutoLinkBatchTask) Collection(io.lumeer.api.model.Collection) DataDocument(io.lumeer.engine.api.data.DataDocument) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) DataDocument(io.lumeer.engine.api.data.DataDocument) Document(io.lumeer.api.model.Document) CreateDocument(io.lumeer.engine.api.event.CreateDocument) UpdateDocument(io.lumeer.engine.api.event.UpdateDocument) List(java.util.List) ArrayList(java.util.ArrayList) RuleTask(io.lumeer.core.task.RuleTask) FunctionFacade(io.lumeer.core.facade.FunctionFacade) TaskProcessingFacade(io.lumeer.core.facade.TaskProcessingFacade) HashSet(java.util.HashSet) UpdateDocument(io.lumeer.engine.api.event.UpdateDocument) FunctionTask(io.lumeer.core.task.FunctionTask) CreateDocument(io.lumeer.engine.api.event.CreateDocument) Collection(io.lumeer.api.model.Collection) PurposeChangeProcessor(io.lumeer.core.facade.detector.PurposeChangeProcessor)

Example 8 with CreateDocument

use of io.lumeer.engine.api.event.CreateDocument in project engine by Lumeer.

the class TaskUpdateChangeDetector method detectChanges.

@Override
public void detectChanges(final DocumentEvent documentEvent, final Collection collection) {
    final CollectionPurpose purpose = collection.getPurpose();
    final boolean doneState = isDoneState(documentEvent, collection);
    if (!(documentEvent instanceof CreateDocument) && !(documentEvent instanceof RemoveDocument)) {
        // delete previous due date and assignee events on the document
        delayedActionDao.deleteScheduledActions(getResourcePath(documentEvent), Set.of(NotificationType.TASK_UPDATED));
        if (!doneState) {
            final Set<Assignee> observers = getObservers(documentEvent, collection);
            delayedActionDao.scheduleActions(getDelayedActions(documentEvent, collection, NotificationType.TASK_UPDATED, nowPlus(), observers));
            // assignee != initiator, initiator != observer, no change in due date, state, nor assignee => send task update
            final String assigneeAttr = purpose.getAssigneeAttributeId();
            final String dueDateAttr = purpose.getDueDateAttributeId();
            final String stateAttr = purpose.getStateAttributeId();
            if (!isAttributeChanged(documentEvent, assigneeAttr) && !isAttributeChanged(documentEvent, dueDateAttr) && !isAttributeChanged(documentEvent, stateAttr)) {
                if (observers != null) {
                    // prevent double notification when assignee is also an observer
                    final Set<Assignee> assignees = new HashSet<>(getAssignees(documentEvent, collection));
                    observers.forEach(assignee -> {
                        assignees.remove(new Assignee(assignee.getEmail(), true));
                        assignees.remove(new Assignee(assignee.getEmail(), false));
                    });
                    delayedActionDao.scheduleActions(getDelayedActions(documentEvent, collection, NotificationType.TASK_UPDATED, nowPlus(), assignees));
                } else {
                    delayedActionDao.scheduleActions(getDelayedActions(documentEvent, collection, NotificationType.TASK_UPDATED, nowPlus()));
                }
            }
        }
    }
    if (documentEvent instanceof RemoveDocument) {
        // create new due date events on the document
        if (!doneState) {
            delayedActionDao.scheduleActions(getDelayedActions(documentEvent, collection, NotificationType.TASK_REMOVED, nowPlus()));
            delayedActionDao.scheduleActions(getDelayedActions(documentEvent, collection, NotificationType.TASK_REMOVED, nowPlus(), getObservers(documentEvent, collection)));
        }
    }
}
Also used : RemoveDocument(io.lumeer.engine.api.event.RemoveDocument) CreateDocument(io.lumeer.engine.api.event.CreateDocument) CollectionPurpose(io.lumeer.api.model.CollectionPurpose) HashSet(java.util.HashSet)

Example 9 with CreateDocument

use of io.lumeer.engine.api.event.CreateDocument in project engine by Lumeer.

the class DocumentFacade method createDocumentsChain.

public DocumentsChain createDocumentsChain(List<Document> documents, List<LinkInstance> linkInstances) {
    var collectionsMap = documents.stream().filter(document -> document.getId() == null).map(document -> checkCreateDocuments(document.getCollectionId())).collect(Collectors.toMap(Resource::getId, Function.identity()));
    var linkTypesMap = linkInstances.stream().filter(linkInstance -> linkInstance.getId() == null).map(linkInstanceId -> checkCreateLinks(linkInstanceId.getLinkTypeId())).collect(Collectors.toMap(LinkType::getId, Function.identity()));
    permissionsChecker.checkDocumentLimits(documents);
    if (documents.isEmpty()) {
        return new DocumentsChain(Collections.emptyList(), Collections.emptyList());
    }
    List<Document> createdDocuments = new ArrayList<>();
    List<LinkInstance> createdLinks = new ArrayList<>();
    String previousDocumentId = linkInstances.size() == documents.size() ? Utils.firstNotNullElement(linkInstances.get(0).getDocumentIds()) : null;
    var linkInstanceIndex = 0;
    for (Document document : documents) {
        String currentDocumentId;
        if (document.getId() != null) {
            currentDocumentId = document.getId();
        } else {
            var collection = collectionsMap.get(document.getCollectionId());
            var tuple = createDocument(collection, document);
            createdDocuments.add(tuple.getSecond());
            currentDocumentId = tuple.getFirst().getId();
            collectionAdapter.updateCollectionMetadata(collection, tuple.getSecond().getData().keySet(), Collections.emptySet());
        }
        var linkInstance = linkInstances.size() > linkInstanceIndex ? linkInstances.get(linkInstanceIndex) : null;
        if (previousDocumentId != null && linkInstance != null) {
            linkInstance.setDocumentIds(Arrays.asList(previousDocumentId, currentDocumentId));
            if (linkInstance.getId() != null) {
                var updatedLinkInstance = linkInstanceDao.updateLinkInstance(linkInstance.getId(), linkInstance);
                updatedLinkInstance.setData(linkInstance.getData());
                createdLinks.add(updatedLinkInstance);
            } else {
                var linkType = linkTypesMap.get(linkInstance.getLinkTypeId());
                var linkData = linkInstanceFacade.createLinkInstance(linkType, linkInstance);
                createdLinks.add(linkData.getSecond());
            }
            linkInstanceIndex++;
        }
        previousDocumentId = currentDocumentId;
    }
    if (this.createChainEvent != null) {
        this.createChainEvent.fire(new CreateDocumentsAndLinks(createdDocuments, createdLinks));
    }
    return new DocumentsChain(createdDocuments, createdLinks);
}
Also used : Arrays(java.util.Arrays) ZonedDateTime(java.time.ZonedDateTime) DocumentsChain(io.lumeer.api.model.DocumentsChain) LinkTypeDao(io.lumeer.storage.api.dao.LinkTypeDao) HashMap(java.util.HashMap) DocumentAdapter(io.lumeer.core.adapter.DocumentAdapter) Function(java.util.function.Function) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Inject(javax.inject.Inject) CollectionDao(io.lumeer.storage.api.dao.CollectionDao) DataDao(io.lumeer.storage.api.dao.DataDao) ResourceType(io.lumeer.api.model.ResourceType) Resource(io.lumeer.api.model.common.Resource) Map(java.util.Map) ResourceCommentDao(io.lumeer.storage.api.dao.ResourceCommentDao) CollectionAdapter(io.lumeer.core.adapter.CollectionAdapter) ImportCollectionContent(io.lumeer.engine.api.event.ImportCollectionContent) ConstraintManager(io.lumeer.core.constraint.ConstraintManager) Tuple(io.lumeer.core.util.Tuple) Event(javax.enterprise.event.Event) DocumentDao(io.lumeer.storage.api.dao.DocumentDao) DataDocument(io.lumeer.engine.api.data.DataDocument) ResourceNotFoundException(io.lumeer.storage.api.exception.ResourceNotFoundException) Document(io.lumeer.api.model.Document) CreateDocument(io.lumeer.engine.api.event.CreateDocument) Set(java.util.Set) UUID(java.util.UUID) Constraint(io.lumeer.api.model.Constraint) Collectors(java.util.stream.Collectors) LinkInstance(io.lumeer.api.model.LinkInstance) LinkType(io.lumeer.api.model.LinkType) DocumentUtils(io.lumeer.core.util.DocumentUtils) Objects(java.util.Objects) FileAttachment(io.lumeer.api.model.FileAttachment) Project(io.lumeer.api.model.Project) LinkInstanceDao(io.lumeer.storage.api.dao.LinkInstanceDao) DefaultConfigurationProducer(io.lumeer.core.facade.configuration.DefaultConfigurationProducer) List(java.util.List) ResourceUtils(io.lumeer.api.util.ResourceUtils) RequestScoped(javax.enterprise.context.RequestScoped) PostConstruct(javax.annotation.PostConstruct) FavoriteItemDao(io.lumeer.storage.api.dao.FavoriteItemDao) UpdateDocument(io.lumeer.engine.api.event.UpdateDocument) Utils(io.lumeer.core.util.Utils) Collections(java.util.Collections) Collection(io.lumeer.api.model.Collection) CreateDocumentsAndLinks(io.lumeer.engine.api.event.CreateDocumentsAndLinks) DocumentsChain(io.lumeer.api.model.DocumentsChain) ArrayList(java.util.ArrayList) CreateDocumentsAndLinks(io.lumeer.engine.api.event.CreateDocumentsAndLinks) LinkInstance(io.lumeer.api.model.LinkInstance) DataDocument(io.lumeer.engine.api.data.DataDocument) Document(io.lumeer.api.model.Document) CreateDocument(io.lumeer.engine.api.event.CreateDocument) UpdateDocument(io.lumeer.engine.api.event.UpdateDocument)

Example 10 with CreateDocument

use of io.lumeer.engine.api.event.CreateDocument in project engine by Lumeer.

the class TaskProcessingFacade method onCreateDocument.

public void onCreateDocument(@Observes final CreateDocument createDocument) {
    List<Task> tasks = documentCreatedTasks(new Document(createDocument.getDocument()));
    processTasks(tasks.toArray(new Task[0]));
}
Also used : FunctionTask(io.lumeer.core.task.FunctionTask) Task(io.lumeer.core.task.Task) RuleTask(io.lumeer.core.task.RuleTask) Document(io.lumeer.api.model.Document) RemoveDocument(io.lumeer.engine.api.event.RemoveDocument) CreateDocument(io.lumeer.engine.api.event.CreateDocument) UpdateDocument(io.lumeer.engine.api.event.UpdateDocument)

Aggregations

CreateDocument (io.lumeer.engine.api.event.CreateDocument)10 UpdateDocument (io.lumeer.engine.api.event.UpdateDocument)8 Document (io.lumeer.api.model.Document)5 RemoveDocument (io.lumeer.engine.api.event.RemoveDocument)5 ZonedDateTime (java.time.ZonedDateTime)5 CollectionPurpose (io.lumeer.api.model.CollectionPurpose)4 DataDocument (io.lumeer.engine.api.data.DataDocument)4 HashSet (java.util.HashSet)4 Collection (io.lumeer.api.model.Collection)3 LinkInstance (io.lumeer.api.model.LinkInstance)2 LinkType (io.lumeer.api.model.LinkType)2 ResourceType (io.lumeer.api.model.ResourceType)2 FunctionTask (io.lumeer.core.task.FunctionTask)2 RuleTask (io.lumeer.core.task.RuleTask)2 DocumentUtils (io.lumeer.core.util.DocumentUtils)2 Utils (io.lumeer.core.util.Utils)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2