001/* 002 * Copyright 2016 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.contentio.synchronize.impl; 017 018import java.util.HashMap; 019import java.util.HashSet; 020import java.util.List; 021import java.util.Map; 022import java.util.Set; 023import java.util.TreeSet; 024import java.util.stream.Collectors; 025import java.util.stream.Stream; 026 027import org.apache.avalon.framework.configuration.Configuration; 028import org.apache.avalon.framework.configuration.ConfigurationException; 029import org.apache.avalon.framework.service.ServiceException; 030import org.apache.avalon.framework.service.ServiceManager; 031import org.apache.commons.lang.StringUtils; 032import org.slf4j.Logger; 033 034import org.ametys.core.util.JSONUtils; 035import org.ametys.plugins.contentio.synchronize.AbstractSimpleSynchronizableContentsCollection; 036import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollection; 037 038/** 039 * Abstract implementation of {@link SynchronizableContentsCollection} to be synchronized with a data source 040 */ 041public abstract class AbstractDataSourceSynchronizableContentsCollection extends AbstractSimpleSynchronizableContentsCollection 042{ 043 /** Name of parameter holding the data source id */ 044 protected static final String __PARAM_DATASOURCE_ID = "datasourceId"; 045 /** Name of parameter holding the data source id */ 046 protected static final String __PARAM_FIELD_ID = "idField"; 047 /** Name of parameter holding the fields mapping */ 048 protected static final String __PARAM_MAPPING = "mapping"; 049 /** Name of parameter into mapping holding the synchronized property */ 050 protected static final String __PARAM_MAPPING_SYNCHRO = "synchro"; 051 /** Name of parameter into mapping holding the path of metadata */ 052 protected static final String __PARAM_MAPPING_METADATA_REF = "metadata-ref"; 053 /** Name of parameter into mapping holding the remote attribute */ 054 protected static final String __PARAM_MAPPING_ATTRIBUTE = "attribute"; 055 056 /** The JSON Utils */ 057 protected JSONUtils _jsonUtils; 058 059 /** Mapping of the metadata with source data */ 060 protected Map<String, List<String>> _mapping; 061 /** Columns and criteria for search */ 062 protected Set<String> _columnsAndCriteria; 063 /** Synchronized fields */ 064 protected Set<String> _syncFields; 065 066 @Override 067 public void service(ServiceManager smanager) throws ServiceException 068 { 069 super.service(smanager); 070 _jsonUtils = (JSONUtils) smanager.lookup(JSONUtils.ROLE); 071 } 072 073 @Override 074 public String getIdField() 075 { 076 return (String) getParameterValues().get(__PARAM_FIELD_ID); 077 } 078 079 /** 080 * Get the id of data source 081 * @return The id of data source 082 */ 083 public String getDataSourceId() 084 { 085 return (String) getParameterValues().get(__PARAM_DATASOURCE_ID); 086 } 087 088 @Override 089 protected void configureDataSource(Configuration configuration) throws ConfigurationException 090 { 091 _mapping = new HashMap<>(); 092 _columnsAndCriteria = new TreeSet<>(); 093 _syncFields = new HashSet<>(); 094 String mappingAsString = (String) getParameterValues().get(__PARAM_MAPPING); 095 if (StringUtils.isNotEmpty(mappingAsString)) 096 { 097 List<Object> mappingAsList = _jsonUtils.convertJsonToList(mappingAsString); 098 for (Object object : mappingAsList) 099 { 100 @SuppressWarnings("unchecked") 101 Map<String, Object> field = (Map<String, Object>) object; 102 String metadataRef = (String) field.get(__PARAM_MAPPING_METADATA_REF); 103 String[] mappingAttributes = ((String) field.get(__PARAM_MAPPING_ATTRIBUTE)).split(","); 104 List<String> attributes = Stream.of(mappingAttributes) 105 .map(String::trim) 106 .collect(Collectors.toList()); 107 108 _mapping.put(metadataRef, attributes); 109 for (String attribute : attributes) 110 { 111 _columnsAndCriteria.add(attribute); 112 } 113 114 boolean isSynchronized = field.containsKey(__PARAM_MAPPING_SYNCHRO) ? (Boolean) field.get(__PARAM_MAPPING_SYNCHRO) : false; 115 if (isSynchronized) 116 { 117 _syncFields.add(metadataRef); 118 } 119 } 120 } 121 } 122 123 @Override 124 protected void configureSearchModel() 125 { 126 for (String columnOrCriteria : _columnsAndCriteria) 127 { 128 _searchModelConfiguration.addCriterion(columnOrCriteria); 129 _searchModelConfiguration.addColumn(columnOrCriteria); 130 } 131 } 132 133 @Override 134 public Set<String> getLocalAndExternalFields(Map<String, Object> additionalParameters) 135 { 136 return _syncFields; 137 } 138 139 /** 140 * Get the field mapping 141 * @return The mapping 142 */ 143 public Map<String, List<String>> getMapping() 144 { 145 return _mapping; 146 } 147 148 @Override 149 protected Map<String, Object> putIdParameter(String idValue) 150 { 151 Map<String, Object> parameters = new HashMap<>(); 152 153 List<String> remoteKeys = getMapping().get(getIdField()); 154 if (remoteKeys != null && remoteKeys.size() > 0) 155 { 156 parameters.put(remoteKeys.get(0), idValue); 157 } 158 return parameters; 159 } 160 161 @Override 162 protected Map<String, Map<String, List<Object>>> getRemoteValues(Map<String, Object> searchParameters, Logger logger) 163 { 164 Map<String, Map<String, Object>> results = internalSearch(searchParameters, 0, Integer.MAX_VALUE, null, logger); 165 return _sccHelper.organizeRemoteValuesByAttribute(results, getMapping()); 166 } 167}