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