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.contentio.synchronize.search; 017 018import java.util.HashMap; 019import java.util.HashSet; 020import java.util.List; 021import java.util.Locale; 022import java.util.Map; 023import java.util.Set; 024 025import org.apache.avalon.framework.component.Component; 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.slf4j.Logger; 031 032import org.ametys.cms.repository.Content; 033import org.ametys.cms.repository.ModifiableDefaultContent; 034import org.ametys.core.ui.Callable; 035import org.ametys.core.util.AvalonLoggerAdapter; 036import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollection; 037import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollectionDAO; 038import org.ametys.plugins.repository.AmetysObjectResolver; 039 040import com.google.common.collect.ImmutableList; 041import com.google.common.collect.ImmutableMap; 042 043/** 044 * Helper for SCC callables. 045 */ 046public class SCCSearchToolHelper extends AbstractLogEnabled implements Component, Serviceable 047{ 048 /** SCC DAO */ 049 protected SynchronizableContentsCollectionDAO _synchronizableContentsCollectionDAO; 050 051 /** The Ametys resolver */ 052 protected AmetysObjectResolver _resolver; 053 054 @Override 055 public void service(ServiceManager manager) throws ServiceException 056 { 057 _synchronizableContentsCollectionDAO = (SynchronizableContentsCollectionDAO) manager.lookup(SynchronizableContentsCollectionDAO.ROLE); 058 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 059 } 060 061 /** 062 * Get the {@link SCCSearchModelConfiguration} from the collectionId. 063 * @param collectionId Collection ID 064 * @return The {@link SCCSearchModelConfiguration} 065 */ 066 @Callable 067 public Map<String, Object> getSearchModelConfiguration(String collectionId) 068 { 069 SynchronizableContentsCollection collection = _synchronizableContentsCollectionDAO.getSynchronizableContentsCollection(collectionId); 070 SCCSearchModelConfiguration searchModelConfiguration = collection.getSearchModelConfiguration(); 071 return searchModelConfiguration.toJSON(); 072 } 073 074 /** 075 * Import the content specified by the id in the specified collection. 076 * @param collectionId Collection ID 077 * @param id Synchonization ID of the content 078 * @param additionalParameters Additional parameters 079 * @return Imported contents 080 */ 081 @Callable 082 public Map<String, Object> importContent(String collectionId, String id, Map<String, Object> additionalParameters) 083 { 084 Logger logger = new AvalonLoggerAdapter(getLogger()); 085 086 Map<String, Object> result = new HashMap<>(); 087 088 try 089 { 090 Locale defaultLocale = additionalParameters.containsKey("language") ? new Locale((String) additionalParameters.get("language")) : null; 091 Set<Map<String, String>> contentsList = new HashSet<>(); 092 093 SynchronizableContentsCollection collection = _synchronizableContentsCollectionDAO.getSynchronizableContentsCollection(collectionId); 094 Content existingContent = collection.getContent(null, id); 095 if (existingContent == null) 096 { 097 List<ModifiableDefaultContent> contents = collection.importContent(id, additionalParameters, logger); 098 for (ModifiableDefaultContent content : contents) 099 { 100 Map<String, String> contentMap = new HashMap<>(); 101 contentMap.put("id", content.getId()); 102 contentMap.put("title", content.getTitle(defaultLocale)); 103 contentMap.put("lang", content.getLanguage()); 104 contentsList.add(contentMap); 105 } 106 result.put("contents", contentsList); 107 result.put("total", contents.size()); 108 } 109 else 110 { 111 result.put("contents", ImmutableList.of(ImmutableMap.of("id", existingContent.getId(), "title", existingContent.getTitle(defaultLocale), "lang", existingContent.getLanguage()))); 112 result.put("error", "alreadyImported"); 113 } 114 } 115 catch (Exception e) 116 { 117 String errorMessage = "An exception occured during import of the content '" + id + "' on SCC '" + collectionId + "'"; 118 logger.error(errorMessage, e); 119 throw new IllegalStateException(errorMessage); 120 } 121 122 return result; 123 } 124 125 /** 126 * Synchronize the content on the given collection with the given synchronization code. 127 * @param collectionId Collection ID 128 * @param contentId Content ID 129 * @param syncCode Synchronization code 130 * @return true if an error occured 131 */ 132 @Callable 133 public boolean synchronizeContent(String collectionId, String contentId, String syncCode) 134 { 135 Logger logger = new AvalonLoggerAdapter(getLogger()); 136 137 ModifiableDefaultContent content = _resolver.resolveById(contentId); 138 boolean hasErrors = false; 139 140 try 141 { 142 SynchronizableContentsCollection collection = _synchronizableContentsCollectionDAO.getSynchronizableContentsCollection(collectionId); 143 144 Map<String, Object> searchParameters = new HashMap<>(); 145 searchParameters.put(collection.getIdField(), syncCode); 146 147 if (collection.getTotalCount(searchParameters, logger) > 0) 148 { 149 collection.updateSyncInformations(content, syncCode, logger); 150 collection.synchronizeContent(content, logger); 151 } 152 else 153 { 154 logger.warn("In the collection '{}', there is not content matching with the synchronization code '{}'.", collectionId, syncCode); 155 hasErrors = true; 156 } 157 } 158 catch (Exception e) 159 { 160 logger.error("An error occured while synchronizing the content '{}' with the synchronization code '{}' from the '{}' collection.", contentId, syncCode, collectionId, e); 161 hasErrors = true; 162 } 163 164 return hasErrors; 165 } 166 167 /** 168 * Get the value of the synchronization field. 169 * @param collectionId Collection ID 170 * @param contentId Content ID 171 * @return The value of the synchronization field 172 */ 173 @Callable 174 public String getSyncCode(String contentId, String collectionId) 175 { 176 SynchronizableContentsCollection collection = _synchronizableContentsCollectionDAO.getSynchronizableContentsCollection(collectionId); 177 Content content = _resolver.resolveById(contentId); 178 179 String syncCode = null; 180 if (content.getMetadataHolder().hasMetadata(collection.getIdField())) 181 { 182 syncCode = content.getMetadataHolder().getString(collection.getIdField()); 183 } 184 return syncCode; 185 } 186}