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.HashSet; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025 026import org.apache.avalon.framework.component.Component; 027import org.apache.avalon.framework.configuration.Configuration; 028import org.apache.avalon.framework.configuration.ConfigurationException; 029import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 030import org.apache.avalon.framework.context.Context; 031import org.apache.avalon.framework.context.ContextException; 032import org.apache.avalon.framework.context.Contextualizable; 033import org.apache.avalon.framework.logger.AbstractLogEnabled; 034import org.apache.avalon.framework.service.ServiceException; 035import org.apache.avalon.framework.service.ServiceManager; 036import org.apache.avalon.framework.service.Serviceable; 037import org.apache.cocoon.components.LifecycleHelper; 038 039import org.ametys.core.group.GroupIdentity; 040import org.ametys.core.user.UserIdentity; 041import org.ametys.plugins.core.user.UserHelper; 042import org.ametys.plugins.extraction.ExtractionConstants; 043import org.ametys.plugins.extraction.component.CountExtractionComponent; 044import org.ametys.plugins.extraction.component.ExtractionComponent; 045import org.ametys.plugins.extraction.component.MappingQueryExtractionComponent; 046import org.ametys.plugins.extraction.component.QueryExtractionComponent; 047import org.ametys.plugins.extraction.component.ThesaurusExtractionComponent; 048import org.ametys.plugins.extraction.execution.Extraction.ExtractionProfile; 049import org.ametys.plugins.extraction.execution.Extraction.Visibility; 050 051/** 052 * This class reads the extraction definition file 053 */ 054public class ExtractionDefinitionReader extends AbstractLogEnabled implements Component, Contextualizable, Serviceable 055{ 056 /** The component role. */ 057 public static final String ROLE = ExtractionDefinitionReader.class.getName(); 058 059 private Context _context; 060 private ServiceManager _serviceManager; 061 private UserHelper _userHelper; 062 063 public void contextualize(Context context) throws ContextException 064 { 065 _context = context; 066 } 067 068 public void service(ServiceManager manager) throws ServiceException 069 { 070 _serviceManager = manager; 071 _userHelper = (UserHelper) manager.lookup(UserHelper.ROLE); 072 } 073 074 /** 075 * Read the extraction definition file 076 * @param file extraction definition file 077 * @return the extraction components parsed in the definition file 078 * @throws Exception if an error occurs 079 */ 080 public Extraction readExtractionDefinitionFile(File file) throws Exception 081 { 082 long startTime = -1; 083 if (getLogger().isDebugEnabled()) 084 { 085 startTime = System.currentTimeMillis(); 086 getLogger().debug("Reading definition file"); 087 } 088 089 assert file != null; 090 Configuration configuration = new DefaultConfigurationBuilder().buildFromFile(file); 091 092 Extraction extraction = new Extraction(); 093 094 _readExtractionDescription(configuration, extraction); 095 _readExtractionRights(configuration, extraction); 096 _readVariablesDefinition(configuration, extraction); 097 _readExtractionDefinitionFile(configuration, extraction); 098 099 if (getLogger().isDebugEnabled()) 100 { 101 long endTime = System.currentTimeMillis(); 102 getLogger().debug("Read definition file in " + (endTime - startTime) + "ms"); 103 } 104 105 return extraction; 106 } 107 108 /** 109 * Read the extraction definition file 110 * @param file extraction definition file 111 * @return the extraction components parsed in the definition file 112 * @throws Exception if an error occurs 113 */ 114 public Extraction readVariablesDefinitionsInExtractionDefinitionFile(File file) throws Exception 115 { 116 assert file != null; 117 118 Configuration configuration = new DefaultConfigurationBuilder().buildFromFile(file); 119 Extraction extraction = new Extraction(); 120 _readVariablesDefinition(configuration, extraction); 121 122 return extraction; 123 } 124 125 private void _readExtractionDescription(Configuration configuration, Extraction extraction) 126 { 127 String descriptionId = configuration.getChild(ExtractionConstants.DESCRIPTION_TAG) 128 .getAttribute(ExtractionConstants.DESCRIPTION_IDENTIFIER_ATTRIBUTE_NAME, null); 129 extraction.setDescriptionId(descriptionId); 130 } 131 132 private void _readExtractionRights(Configuration configuration, Extraction extraction) throws ConfigurationException 133 { 134 Configuration visibility = configuration.getChild(ExtractionConstants.VISIBILITY_TAG); 135 extraction.setVisibility(Visibility.valueOf(visibility.getValue(Visibility.PUBLIC.toString()).toUpperCase())); 136 137 Configuration author = configuration.getChild(ExtractionConstants.AUTHOR_TAG, false); 138 if (author != null) 139 { 140 extraction.setAuthor(_userHelper.xml2userIdentity(author)); 141 } 142 143 Configuration readAccessRight = configuration.getChild(ExtractionConstants.READ_ACCESS_TAG); 144 Set<GroupIdentity> readAccessGroupIdentities = _getGroupsFromConfiguration(readAccessRight); 145 extraction.setGrantedGroups(ExtractionProfile.READ_ACCESS, readAccessGroupIdentities); 146 Set<UserIdentity> readAccessUserIdentities = _getUsersFromConfiguration(readAccessRight); 147 extraction.setGrantedUsers(ExtractionProfile.READ_ACCESS, readAccessUserIdentities); 148 149 Configuration writeAccessRight = configuration.getChild(ExtractionConstants.WRITE_ACCESS_TAG); 150 Set<GroupIdentity> writeAccessGroupIdentities = _getGroupsFromConfiguration(writeAccessRight); 151 extraction.setGrantedGroups(ExtractionProfile.WRITE_ACCESS, writeAccessGroupIdentities); 152 Set<UserIdentity> writeAccessUserIdentities = _getUsersFromConfiguration(writeAccessRight); 153 extraction.setGrantedUsers(ExtractionProfile.WRITE_ACCESS, writeAccessUserIdentities); 154 } 155 156 private Set<GroupIdentity> _getGroupsFromConfiguration(Configuration right) throws ConfigurationException 157 { 158 Set<GroupIdentity> groupIdentities = new HashSet<>(); 159 160 Configuration groups = right.getChild(ExtractionConstants.GROUPS_TAG); 161 for (Configuration group : groups.getChildren(ExtractionConstants.GROUP_TAG)) 162 { 163 GroupIdentity groupIdentity = new GroupIdentity(group.getAttribute("id"), group.getAttribute("groupDirectory")); 164 groupIdentities.add(groupIdentity); 165 } 166 167 return groupIdentities; 168 } 169 170 private Set<UserIdentity> _getUsersFromConfiguration(Configuration right) throws ConfigurationException 171 { 172 Set<UserIdentity> userIdentities = new HashSet<>(); 173 174 Configuration users = right.getChild(ExtractionConstants.USERS_TAG); 175 for (Configuration user : users.getChildren(ExtractionConstants.USER_TAG)) 176 { 177 UserIdentity userIdentity = _userHelper.xml2userIdentity(user); 178 userIdentities.add(userIdentity); 179 } 180 181 return userIdentities; 182 } 183 184 private void _readVariablesDefinition(Configuration configuration, Extraction extraction) throws ConfigurationException 185 { 186 for (Configuration child : configuration.getChildren()) 187 { 188 switch (child.getName()) 189 { 190 case ExtractionConstants.OPTIONAL_COLUMNS_TAG: 191 extraction.setDisplayOptionalColumnsNames(getDisplayOptionalColumnNames(child)); 192 break; 193 case ExtractionConstants.CLAUSES_VARIABLES_TAG: 194 extraction.setQueryVariablesNamesAndContentTypes(getQueryVariablesNamesAndContentTypes(child)); 195 break; 196 default: 197 // Do nothing, we only check variables definitions 198 } 199 } 200 } 201 202 private void _readExtractionDefinitionFile(Configuration configuration, Extraction extraction) throws Exception 203 { 204 for (Configuration child : configuration.getChildren()) 205 { 206 switch (child.getName()) 207 { 208 case ExtractionConstants.QUERY_COMPONENT_TAG: 209 case ExtractionConstants.THESAURUS_COMPONENT_TAG: 210 case ExtractionConstants.COUNT_COMPONENT_TAG: 211 case ExtractionConstants.MAPPING_QUERY_COMPONENT_TAG: 212 ExtractionComponent component = _processExtractionComponent(child); 213 extraction.addExtractionComponent(component); 214 break; 215 default: 216 // Do nothing 217 } 218 } 219 } 220 221 private List<String> getDisplayOptionalColumnNames(Configuration configuration) throws ConfigurationException 222 { 223 List<String> names = new ArrayList<>(); 224 for (Configuration nameConfiguration : configuration.getChildren("name")) 225 { 226 names.add(nameConfiguration.getValue()); 227 } 228 return names; 229 } 230 231 private Map<String, String> getQueryVariablesNamesAndContentTypes(Configuration configuration) 232 { 233 Map<String, String> variables = new HashMap<>(); 234 for (Configuration variable : configuration.getChildren("variable")) 235 { 236 String name = variable.getAttribute("name", null); 237 String contentType = variable.getAttribute("contentType", null); 238 if (null == name || null == contentType) 239 { 240 throw new IllegalArgumentException("Query variables are not well defined. A query variable is defined by a name and a content type."); 241 } 242 variables.put(name, contentType); 243 } 244 return variables; 245 } 246 247 private ExtractionComponent _processExtractionComponent(Configuration componentConfiguration) throws Exception 248 { 249 ExtractionComponent component = null; 250 switch (componentConfiguration.getName()) 251 { 252 case "query": 253 component = new QueryExtractionComponent(); 254 break; 255 case "count": 256 component = new CountExtractionComponent(); 257 break; 258 case "thesaurus": 259 component = new ThesaurusExtractionComponent(); 260 break; 261 case "mapping-query": 262 component = new MappingQueryExtractionComponent(); 263 break; 264 default: 265 // do nothing 266 break; 267 } 268 269 if (component != null) 270 { 271 LifecycleHelper.setupComponent(component, getLogger(), _context, _serviceManager, componentConfiguration); 272 for (Configuration child : componentConfiguration.getChildren()) 273 { 274 ExtractionComponent subComponent = _processExtractionComponent(child); 275 if (null != subComponent) 276 { 277 component.addSubComponent(subComponent); 278 } 279 } 280 } 281 return component; 282 } 283}