001/*
002 *  Copyright 2017 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 java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import org.apache.avalon.framework.configuration.Configurable;
024import org.apache.avalon.framework.configuration.Configuration;
025import org.apache.avalon.framework.configuration.ConfigurationException;
026import org.apache.avalon.framework.logger.AbstractLogEnabled;
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.avalon.framework.service.Serviceable;
030import org.xml.sax.ContentHandler;
031
032import org.ametys.cms.contenttype.ContentTypeExtensionPoint;
033import org.ametys.cms.contenttype.ContentTypesHelper;
034import org.ametys.plugins.extraction.execution.ExtractionExecutionContext;
035import org.ametys.plugins.extraction.execution.ExtractionExecutionContextHierarchyElement;
036import org.ametys.plugins.thesaurus.ThesaurusDAO;
037
038/**
039 * This class represents an extraction component
040 */
041public abstract class AbstractExtractionComponent extends AbstractLogEnabled implements ExtractionComponent, Serviceable, Configurable
042{
043    /** Hierarchy level separator for join expression */
044    protected static final String JOIN_HIERARCHY_SEPARATOR = "/";
045    
046    /** Hierarchy level element representation for join expression */
047    protected static final String JOIN_HIERARCHY_ELEMENT = "..";
048    
049    /** Metadata path separator used in extraction definition */
050    protected static final String EXTRACTION_ITEM_PATH_SEPARATOR = "\\.";
051    
052    /** The list of sub components */
053    protected List<ExtractionComponent> _subComponents = new ArrayList<>();
054    
055    /** the tag name */
056    protected String _tagName;
057    
058    /** Helper for content types */
059    protected ContentTypesHelper _contentTypesHelper;
060    
061    /** Content types extension point */
062    protected ContentTypeExtensionPoint _contentTypeExtensionPoint;
063    
064    /** Thesaurus DAO */
065    protected ThesaurusDAO _thesaurusDAO;
066    
067    public void service(ServiceManager serviceManager) throws ServiceException
068    {
069        _contentTypeExtensionPoint = (ContentTypeExtensionPoint) serviceManager.lookup(ContentTypeExtensionPoint.ROLE);
070        _contentTypesHelper = (ContentTypesHelper) serviceManager.lookup(ContentTypesHelper.ROLE);
071        _thesaurusDAO = (ThesaurusDAO) serviceManager.lookup(ThesaurusDAO.ROLE);
072    }
073    
074    public void configure(Configuration configuration) throws ConfigurationException
075    {
076        _tagName = configuration.getAttribute("tagName", getDefaultTagName());
077    }
078
079    /**
080     * Retrieves the default tag name
081     * @return the default tag name
082     */
083    protected abstract String getDefaultTagName();
084    
085    public void prepareComponentExecution(ExtractionExecutionContext context) throws Exception
086    {
087        for (ExtractionComponent subComponent : _subComponents)
088        {
089            subComponent.prepareComponentExecution(context);
090        }
091    }
092    
093    public final void execute(ContentHandler contentHandler, ExtractionExecutionContext context) throws Exception
094    {
095        long startTime = -1;
096        if (getLogger().isDebugEnabled())
097        {
098            startTime = System.currentTimeMillis();
099            getLogger().debug(getLogsPrefix() + "executing component.");
100        }
101        
102        executeComponent(contentHandler, context);
103        
104        if (getLogger().isDebugEnabled())
105        {
106            long endTime = System.currentTimeMillis();
107            getLogger().debug(getLogsPrefix() + "executed component in " + (endTime - startTime) + "ms");
108        }
109    }
110    
111    /**
112     * Execute the extraction of the component
113     * @param contentHandler result document
114     * @param context context of the extraction component
115     * @throws Exception if an error occurs
116     */
117    protected abstract void executeComponent(ContentHandler contentHandler, ExtractionExecutionContext context) throws Exception;
118
119    /**
120     * Execute the sub components
121     * @param contentHandler result document
122     * @param context context of the extraction component
123     * @param currentContextHierarchyElement the current context
124     * @throws Exception if an error occurs
125     */
126    public void executeSubComponents(ContentHandler contentHandler, ExtractionExecutionContext context, ExtractionExecutionContextHierarchyElement currentContextHierarchyElement) throws Exception
127    {
128        ExtractionExecutionContext newContext = new ExtractionExecutionContext(context);
129        
130        List<ExtractionExecutionContextHierarchyElement> subComponentsContextElements = new ArrayList<>();
131        subComponentsContextElements.addAll(context.getHierarchyElements());
132        subComponentsContextElements.add(currentContextHierarchyElement);
133        newContext.setHierarchyElements(subComponentsContextElements);
134        
135        for (ExtractionComponent subComponent : _subComponents)
136        {
137            subComponent.execute(contentHandler, newContext);
138        }
139    }
140    
141    public void addSubComponent(ExtractionComponent subComponent)
142    {
143        _subComponents.add(subComponent);
144    }
145
146    public List<ExtractionComponent> getSubComponents()
147    {
148        return _subComponents;
149    }
150    
151    public Map<String, Object> getComponentDetailsForTree()
152    {
153        Map<String, Object> details = new HashMap<>();
154        details.put("text", this.getTagName());
155        
156        Map<String, Object> data = new HashMap<>();
157        data.put("componentTagName", this.getTagName());
158        details.put("data", data);
159        
160        return details;
161    }
162
163    /**
164     * Retrieves the prefix to use in exceptions thrown by this component
165     * @return the prefix for exceptions
166     */
167    protected abstract String getLogsPrefix();
168    
169    /**
170     * Retrieves the component tag name
171     * @return the tag name
172     */
173    public String getTagName()
174    {
175        return _tagName;
176    }
177
178    /**
179     * Sets the component tag name
180     * @param tagName The tag name to set
181     */
182    public void setTagName(String tagName)
183    {
184        _tagName = tagName;
185    }
186}