001/*
002 *  Copyright 2018 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.extraction.component;
017
018import org.xml.sax.ContentHandler;
019
020import org.ametys.cms.repository.Content;
021import org.ametys.plugins.extraction.execution.ExtractionExecutionContext;
022
023/**
024 * {@link ExtractionComponent} whose execution sometimes needs to be done in two times 
025 * (in order to avoid calling {@link #execute(ContentHandler, ExtractionExecutionContext) execute} n times  for performance reasons):
026 * <ol>
027 * <li>by {@link #computeFirstLevelResults(ExtractionExecutionContext)} for returning all the first level content results;</li>
028 * <li>by {@link #executeFor(ContentHandler, Iterable, ExtractionExecutionContext)} for SAXing with the given {@link ContentHandler} and the given iterable on contents, subset of the one returned by the first method.</li>
029 * </ol>
030 * Thus, instead of calling {@link #execute(ContentHandler, ExtractionExecutionContext) execute} n times,
031 * {@link #computeFirstLevelResults(ExtractionExecutionContext) computeFirstLevelResults} is called one time 
032 * and {@link #executeFor(ContentHandler, Iterable, ExtractionExecutionContext) executeFor} is called n times with a different handler and iterable.
033 * <br>
034 * <br><b>Important: </b>The implementations must ensure that calling <code>execute</code> is equivalent to successively call <code>computeFirstLevelResults</code> and then <code>executeFor</code> with that result.
035 */
036public interface TwoStepsExecutingExtractionComponent extends ExtractionComponent
037{
038    /**
039     * Computes first level results for preparing multiple extraction executions
040     * @param context context of the extraction component
041     * @return The first level content results
042     * @throws Exception if an error occurs
043     */
044    public Iterable<Content> computeFirstLevelResults(ExtractionExecutionContext context) throws Exception;
045    
046    /**
047     * Execute the extraction of the component for the given first level results
048     * @param contentHandler result document
049     * @param subsetResults A subset of the first level content results previously returned by {@link #computeFirstLevelResults(ExtractionExecutionContext)}
050     * @param context context of the extraction component
051     * @throws Exception if an error occurs
052     */
053    public void executeFor(ContentHandler contentHandler, Iterable<Content> subsetResults, ExtractionExecutionContext context) throws Exception;
054    
055    @Override
056    default void execute(ContentHandler contentHandler, ExtractionExecutionContext context) throws Exception
057    {
058        Iterable<Content> firstLevelResults = computeFirstLevelResults(context);
059        executeFor(contentHandler, firstLevelResults, context);
060    }
061}