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 /** External fields */ 066 protected Set<String> _extFields; 067 068 @Override 069 public void service(ServiceManager smanager) throws ServiceException 070 { 071 super.service(smanager); 072 _jsonUtils = (JSONUtils) smanager.lookup(JSONUtils.ROLE); 073 } 074 075 @Override 076 public String getIdField() 077 { 078 return (String) getParameterValues().get(__PARAM_FIELD_ID); 079 } 080 081 /** 082 * Get the id of data source 083 * @return The id of data source 084 */ 085 public String getDataSourceId() 086 { 087 return (String) getParameterValues().get(__PARAM_DATASOURCE_ID); 088 } 089 090 @Override 091 protected void configureDataSource(Configuration configuration) throws ConfigurationException 092 { 093 _mapping = new HashMap<>(); 094 _columnsAndCriteria = new TreeSet<>(); 095 _syncFields = new HashSet<>(); 096 _extFields = new HashSet<>(); 097 String mappingAsString = (String) getParameterValues().get(__PARAM_MAPPING); 098 if (StringUtils.isNotEmpty(mappingAsString)) 099 { 100 List<Object> mappingAsList = _jsonUtils.convertJsonToList(mappingAsString); 101 for (Object object : mappingAsList) 102 { 103 @SuppressWarnings("unchecked") 104 Map<String, Object> field = (Map<String, Object>) object; 105 String metadataRef = (String) field.get(__PARAM_MAPPING_METADATA_REF); 106 String[] mappingAttributes = ((String) field.get(__PARAM_MAPPING_ATTRIBUTE)).split(","); 107 List<String> attributes = Stream.of(mappingAttributes) 108 .map(String::trim) 109 .collect(Collectors.toList()); 110 111 _mapping.put(metadataRef, attributes); 112 for (String attribute : attributes) 113 { 114 _columnsAndCriteria.add(attribute); 115 } 116 117 boolean isSynchronized = field.containsKey(__PARAM_MAPPING_SYNCHRO) ? (Boolean) field.get(__PARAM_MAPPING_SYNCHRO) : false; 118 if (isSynchronized) 119 { 120 _syncFields.add(metadataRef); 121 } 122 else 123 { 124 _extFields.add(metadataRef); 125 } 126 } 127 } 128 } 129 130 @Override 131 protected void configureSearchModel() 132 { 133 for (String columnOrCriteria : _columnsAndCriteria) 134 { 135 _searchModelConfiguration.addCriterion(columnOrCriteria); 136 _searchModelConfiguration.addColumn(columnOrCriteria); 137 } 138 } 139 140 @Override 141 public Set<String> getExternalOnlyFields(Map<String, Object> additionalParameters) 142 { 143 return _extFields; 144 } 145 146 @Override 147 public Set<String> getLocalAndExternalFields(Map<String, Object> additionalParameters) 148 { 149 return _syncFields; 150 } 151 152 /** 153 * Get the field mapping 154 * @return The mapping 155 */ 156 public Map<String, List<String>> getMapping() 157 { 158 return _mapping; 159 } 160 161 @Override 162 protected Map<String, Object> putIdParameter(String idValue) 163 { 164 Map<String, Object> parameters = new HashMap<>(); 165 166 List<String> remoteKeys = getMapping().get(getIdField()); 167 if (remoteKeys != null && remoteKeys.size() > 0) 168 { 169 parameters.put(remoteKeys.get(0), idValue); 170 } 171 return parameters; 172 } 173 174 @Override 175 protected Map<String, Map<String, List<Object>>> getRemoteValues(Map<String, Object> parameters, Logger logger) 176 { 177 Map<String, Map<String, Object>> results = internalSearch(parameters, 0, Integer.MAX_VALUE, null, logger); 178 return _sccHelper.organizeRemoteValuesByMetadata(results, getMapping()); 179 } 180}