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.Iterator; 020import java.util.LinkedList; 021import java.util.List; 022import java.util.Map; 023 024import org.apache.avalon.framework.parameters.Parameters; 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027import org.apache.cocoon.acting.ServiceableAction; 028import org.apache.cocoon.environment.ObjectModelHelper; 029import org.apache.cocoon.environment.Redirector; 030import org.apache.cocoon.environment.Request; 031import org.apache.cocoon.environment.SourceResolver; 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034 035import org.ametys.core.cocoon.JSonReader; 036import org.ametys.core.util.JSONUtils; 037import org.ametys.core.util.ServerCommHelper; 038import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollection; 039import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollectionDAO; 040 041/** 042 * Action to search in a SCC. 043 */ 044public class SCCSearchAction extends ServiceableAction 045{ 046 /** Field imported to display in SCCSearchTool */ 047 protected static final String FIELD_IMPORTED = "imported"; 048 049 /** SCC DAO */ 050 protected SynchronizableContentsCollectionDAO _synchronizableContentsCollectionDAO; 051 /** ServerComm Helper */ 052 protected ServerCommHelper _serverCommHelper; 053 /** JSON Utils */ 054 protected JSONUtils _jsonUtils; 055 056 private Logger _logger = LoggerFactory.getLogger(SCCSearchAction.class); 057 058 @Override 059 public void service(ServiceManager smanager) throws ServiceException 060 { 061 super.service(smanager); 062 _synchronizableContentsCollectionDAO = (SynchronizableContentsCollectionDAO) smanager.lookup(SynchronizableContentsCollectionDAO.ROLE); 063 _serverCommHelper = (ServerCommHelper) smanager.lookup(ServerCommHelper.ROLE); 064 _jsonUtils = (JSONUtils) smanager.lookup(JSONUtils.ROLE); 065 } 066 067 @SuppressWarnings("unchecked") 068 @Override 069 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 070 { 071 // Get JS parameters 072 Map<String, Object> jsParameters = _serverCommHelper.getJsParameters(); 073 074 // Mask imported 075 Map<String, Object> searchParams = (Map<String, Object>) jsParameters.get("values"); 076 boolean maskImported = searchParams.containsKey(SCCSearchModelConfiguration.CRITERIA_MASK_IMPORTED) && Boolean.valueOf(searchParams.get(SCCSearchModelConfiguration.CRITERIA_MASK_IMPORTED).toString()); 077 searchParams.remove(SCCSearchModelConfiguration.CRITERIA_MASK_IMPORTED); 078 079 // Get the collection for search 080 String collectionId = (String) jsParameters.get("collectionId"); 081 SynchronizableContentsCollection collection = _synchronizableContentsCollectionDAO.getSynchronizableContentsCollection(collectionId); 082 083 // Search 084 Integer offset = _getIntValue(jsParameters, "start", 0); 085 Integer limit = _getIntValue(jsParameters, "limit", Integer.MAX_VALUE); 086 087 // Construct the JSON object 088 Map<String, Object> objectToRead = new HashMap<>(); 089 090 // Different treatment if we need to mask imported or not (one is optimized) 091 if (maskImported) 092 { 093 Map<String, Map<String, Object>> results = collection.search(searchParams, 0, Integer.MAX_VALUE, _getSortList(jsParameters.get("sort")), _logger); 094 Iterator<String> resultKeys = results.keySet().iterator(); 095 096 // Skip offset 097 int currentOffset = 0; 098 while (currentOffset < offset && resultKeys.hasNext()) 099 { 100 if (collection.getContent(null, resultKeys.next()) == null) 101 { 102 currentOffset++; 103 } 104 } 105 106 // Get the contents to the limit 107 List<Map<String, Object>> finalResults = new LinkedList<>(); 108 int currentLimit = 0; 109 while (currentLimit < limit && resultKeys.hasNext()) 110 { 111 String idValue = resultKeys.next(); 112 Map<String, Object> contentResults = results.get(idValue); 113 if (collection.getContent(null, idValue) == null) 114 { 115 // Add to results 116 contentResults.put(FIELD_IMPORTED, false); 117 finalResults.add(contentResults); 118 currentLimit++; 119 } 120 } 121 122 objectToRead.put("items", finalResults); 123 // FIXME CONTENTIO-87 124 objectToRead.put("total", collection.getTotalCount(searchParams, _logger)); 125 } 126 else 127 { 128 Map<String, Map<String, Object>> results = collection.search(searchParams, offset, limit, _getSortList(jsParameters.get("sort")), _logger); 129 130 for (String idValue : results.keySet()) 131 { 132 Map<String, Object> contentResults = results.get(idValue); 133 contentResults.put(FIELD_IMPORTED, collection.getContent(null, idValue) != null); 134 results.put(idValue, contentResults); 135 } 136 137 objectToRead.put("items", results.values()); 138 objectToRead.put("total", collection.getTotalCount(searchParams, _logger)); 139 } 140 141 // Add JSON to the request to be parsed 142 Request request = ObjectModelHelper.getRequest(objectModel); 143 request.setAttribute(JSonReader.OBJECT_TO_READ, objectToRead); 144 145 return EMPTY_MAP; 146 } 147 148 private int _getIntValue(Map<String, Object> values, String key, int defaultValue) 149 { 150 if (values.containsKey(key)) 151 { 152 return Integer.valueOf(values.get(key).toString()).intValue(); 153 } 154 155 return defaultValue; 156 } 157 158 private List<Object> _getSortList(Object sortValues) 159 { 160 if (sortValues != null) 161 { 162 return _jsonUtils.convertJsonToList(sortValues.toString()); 163 } 164 165 return null; 166 } 167}