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.execution; 017 018import java.io.File; 019import java.util.ArrayList; 020import java.util.HashMap; 021import java.util.List; 022import java.util.Map; 023 024import org.apache.avalon.framework.component.Component; 025import org.apache.avalon.framework.configuration.Configuration; 026import org.apache.avalon.framework.configuration.ConfigurationException; 027import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 028import org.apache.avalon.framework.context.Context; 029import org.apache.avalon.framework.context.ContextException; 030import org.apache.avalon.framework.context.Contextualizable; 031import org.apache.avalon.framework.logger.AbstractLogEnabled; 032import org.apache.avalon.framework.service.ServiceException; 033import org.apache.avalon.framework.service.ServiceManager; 034import org.apache.avalon.framework.service.Serviceable; 035import org.apache.cocoon.components.LifecycleHelper; 036 037import org.ametys.plugins.extraction.ExtractionConstants; 038import org.ametys.plugins.extraction.component.CountExtractionComponent; 039import org.ametys.plugins.extraction.component.ExtractionComponent; 040import org.ametys.plugins.extraction.component.MappingQueryExtractionComponent; 041import org.ametys.plugins.extraction.component.QueryExtractionComponent; 042import org.ametys.plugins.extraction.component.ThesaurusExtractionComponent; 043 044/** 045 * This class reads the extraction definition file 046 */ 047public class ExtractionDefinitionReader extends AbstractLogEnabled implements Component, Contextualizable, Serviceable 048{ 049 /** The component role. */ 050 public static final String ROLE = ExtractionDefinitionReader.class.getName(); 051 052 private Context _context; 053 private ServiceManager _serviceManager; 054 055 public void contextualize(Context context) throws ContextException 056 { 057 _context = context; 058 } 059 060 public void service(ServiceManager manager) throws ServiceException 061 { 062 _serviceManager = manager; 063 } 064 065 /** 066 * Read the extraction definition file 067 * @param file extraction definition file 068 * @return the extraction components parsed in the definition file 069 * @throws Exception if an error occurs 070 */ 071 public Extraction readExtractionDefinitionFile(File file) throws Exception 072 { 073 long startTime = -1; 074 if (getLogger().isDebugEnabled()) 075 { 076 startTime = System.currentTimeMillis(); 077 getLogger().debug("Reading definition file"); 078 } 079 080 assert file != null; 081 Configuration configuration = new DefaultConfigurationBuilder().buildFromFile(file); 082 083 Extraction extraction = new Extraction(); 084 085 _readExtractionDescription(configuration, extraction); 086 _readVariablesDefinition(configuration, extraction); 087 _readExtractionDefinitionFile(configuration, extraction); 088 089 if (getLogger().isDebugEnabled()) 090 { 091 long endTime = System.currentTimeMillis(); 092 getLogger().debug("Read definition file in " + (endTime - startTime) + "ms"); 093 } 094 095 return extraction; 096 } 097 098 /** 099 * Read the extraction definition file 100 * @param file extraction definition file 101 * @return the extraction components parsed in the definition file 102 * @throws Exception if an error occurs 103 */ 104 public Extraction readVariablesDefinitionsInExtractionDefinitionFile(File file) throws Exception 105 { 106 assert file != null; 107 108 Configuration configuration = new DefaultConfigurationBuilder().buildFromFile(file); 109 Extraction extraction = new Extraction(); 110 _readVariablesDefinition(configuration, extraction); 111 112 return extraction; 113 } 114 115 private void _readExtractionDescription(Configuration configuration, Extraction extraction) 116 { 117 String descriptionId = configuration.getChild(ExtractionConstants.DESCRIPTION_TAG) 118 .getAttribute(ExtractionConstants.DESCRIPTION_IDENTIFIER_ATTRIBUTE_NAME, null); 119 extraction.setDescriptionId(descriptionId); 120 } 121 122 private void _readVariablesDefinition(Configuration configuration, Extraction extraction) throws ConfigurationException 123 { 124 for (Configuration child : configuration.getChildren()) 125 { 126 switch (child.getName()) 127 { 128 case ExtractionConstants.OPTIONAL_COLUMNS_TAG: 129 extraction.setDisplayOptionalColumnsNames(getDisplayOptionalColumnNames(child)); 130 break; 131 case ExtractionConstants.CLAUSES_VARIABLES_TAG: 132 extraction.setQueryVariablesNamesAndContentTypes(getQueryVariablesNamesAndContentTypes(child)); 133 break; 134 default: 135 // Do nothing, we only check variables definitions 136 } 137 } 138 } 139 140 private void _readExtractionDefinitionFile(Configuration configuration, Extraction extraction) throws Exception 141 { 142 for (Configuration child : configuration.getChildren()) 143 { 144 switch (child.getName()) 145 { 146 case ExtractionConstants.QUERY_COMPONENT_TAG: 147 case ExtractionConstants.THESAURUS_COMPONENT_TAG: 148 case ExtractionConstants.COUNT_COMPONENT_TAG: 149 case ExtractionConstants.MAPPING_QUERY_COMPONENT_TAG: 150 ExtractionComponent component = _processExtractionComponent(child); 151 extraction.addExtractionComponent(component); 152 break; 153 default: 154 // Do nothing 155 } 156 } 157 } 158 159 private List<String> getDisplayOptionalColumnNames(Configuration configuration) throws ConfigurationException 160 { 161 List<String> names = new ArrayList<>(); 162 for (Configuration nameConfiguration : configuration.getChildren("name")) 163 { 164 names.add(nameConfiguration.getValue()); 165 } 166 return names; 167 } 168 169 private Map<String, String> getQueryVariablesNamesAndContentTypes(Configuration configuration) 170 { 171 Map<String, String> variables = new HashMap<>(); 172 for (Configuration variable : configuration.getChildren("variable")) 173 { 174 String name = variable.getAttribute("name", null); 175 String contentType = variable.getAttribute("contentType", null); 176 if (null == name || null == contentType) 177 { 178 throw new IllegalArgumentException("Query variables are not well defined. A query variable is defined by a name and a content type."); 179 } 180 variables.put(name, contentType); 181 } 182 return variables; 183 } 184 185 private ExtractionComponent _processExtractionComponent(Configuration componentConfiguration) throws Exception 186 { 187 ExtractionComponent component = null; 188 switch (componentConfiguration.getName()) 189 { 190 case "query": 191 component = new QueryExtractionComponent(); 192 break; 193 case "count": 194 component = new CountExtractionComponent(); 195 break; 196 case "thesaurus": 197 component = new ThesaurusExtractionComponent(); 198 break; 199 case "mapping-query": 200 component = new MappingQueryExtractionComponent(); 201 break; 202 default: 203 // do nothing 204 break; 205 } 206 207 if (component != null) 208 { 209 LifecycleHelper.setupComponent(component, getLogger(), _context, _serviceManager, componentConfiguration); 210 for (Configuration child : componentConfiguration.getChildren()) 211 { 212 ExtractionComponent subComponent = _processExtractionComponent(child); 213 if (null != subComponent) 214 { 215 component.addSubComponent(subComponent); 216 } 217 } 218 } 219 return component; 220 } 221}