001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *    Mariana Cedica
011 */
012package org.nuxeo.ecm.automation.core.operations.services;
013
014import java.util.HashMap;
015import java.util.Map;
016
017import org.nuxeo.ecm.automation.AutomationService;
018import org.nuxeo.ecm.automation.InvalidChainException;
019import org.nuxeo.ecm.automation.OperationContext;
020import org.nuxeo.ecm.automation.OperationException;
021import org.nuxeo.ecm.automation.core.Constants;
022import org.nuxeo.ecm.automation.core.annotations.Context;
023import org.nuxeo.ecm.automation.core.annotations.Operation;
024import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
025import org.nuxeo.ecm.automation.core.annotations.Param;
026import org.nuxeo.ecm.automation.jaxrs.io.documents.PaginableDocumentModelListImpl;
027import org.nuxeo.ecm.core.api.DocumentModel;
028import org.nuxeo.ecm.platform.query.api.PageProvider;
029
030/**
031 * Run an embedded operation chain for each page of the pageProvider given as input. The output is undefined (Void)
032 *
033 * @since 5.6
034 */
035@Operation(id = RunOperationOnProvider.ID, category = Constants.CAT_SUBCHAIN_EXECUTION, label = "Run For Each Page", description = "Run an operation for each page of the provider defined by the provider name, the operation input is the curent page ", aliases = { "Context.RunOperationOnProvider" })
036public class RunOperationOnProvider {
037    public static final String ID = "RunOperationOnProvider";
038
039    @Context
040    protected OperationContext ctx;
041
042    @Context
043    protected AutomationService service;
044
045    @Param(name = "id")
046    protected String chainId;
047
048    @Param(name = "isolate", required = false, values = { "true" })
049    protected boolean isolate = true;
050
051    @OperationMethod
052    public void run(PaginableDocumentModelListImpl paginableList)
053
054    throws InvalidChainException, OperationException, Exception {
055        PageProvider<DocumentModel> pageProvider = paginableList.getProvider();
056        Map<String, Object> vars = isolate ? new HashMap<String, Object>(ctx.getVars()) : ctx.getVars();
057        OperationContext subctx = new OperationContext(ctx.getCoreSession(), vars);
058        final long initialRC = pageProvider.getResultsCount();
059        final long initialNoPages = pageProvider.getNumberOfPages();
060
061        PaginableDocumentModelListImpl input = new PaginableDocumentModelListImpl(pageProvider);
062        while (pageProvider.getCurrentPageIndex() < initialNoPages) {
063            subctx.setInput(input);
064            service.run(subctx, chainId);
065            if (!pageProvider.isNextPageAvailable()) {
066                break;
067            }
068            // check if the chain run is "consuming" docs returned by the
069            // pageProvider or not
070            pageProvider.refresh();
071            input = new PaginableDocumentModelListImpl(pageProvider);
072
073            if (pageProvider.getResultsCount() == initialRC) {
074                pageProvider.nextPage();
075                input = new PaginableDocumentModelListImpl(pageProvider);
076            }
077        }
078
079    }
080}