001/* 002 * Copyright 2025 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.odforientation; 017 018import java.io.IOException; 019import java.util.Collections; 020import java.util.List; 021import java.util.Locale; 022import java.util.Optional; 023 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.cocoon.ProcessingException; 027import org.apache.cocoon.environment.ObjectModelHelper; 028import org.apache.cocoon.environment.Request; 029import org.apache.cocoon.generation.ServiceableGenerator; 030import org.apache.cocoon.xml.AttributesImpl; 031import org.apache.cocoon.xml.XMLUtils; 032import org.apache.commons.lang3.LocaleUtils; 033import org.apache.commons.lang3.StringUtils; 034import org.xml.sax.SAXException; 035 036import org.ametys.cms.contenttype.ContentTypesHelper; 037import org.ametys.cms.repository.ContentTypeExpression; 038import org.ametys.cms.search.advanced.AbstractTreeNode; 039import org.ametys.cms.search.advanced.TreeLeaf; 040import org.ametys.core.util.LambdaUtils; 041import org.ametys.odf.enumeration.OdfReferenceTableEntry; 042import org.ametys.odf.enumeration.OdfReferenceTableHelper; 043import org.ametys.odf.enumeration.OdfReferenceTableHelper.SortField; 044import org.ametys.odf.orgunit.OrgUnit; 045import org.ametys.odf.orgunit.OrgUnitFactory; 046import org.ametys.odf.orgunit.RootOrgUnitProvider; 047import org.ametys.plugins.repository.AmetysObjectIterable; 048import org.ametys.plugins.repository.AmetysObjectResolver; 049import org.ametys.plugins.repository.query.QueryHelper; 050import org.ametys.plugins.repository.query.expression.Expression; 051import org.ametys.plugins.repository.query.expression.Expression.Operator; 052import org.ametys.runtime.model.View; 053import org.ametys.runtime.model.type.DataContext; 054import org.ametys.web.frontoffice.search.SearchService; 055import org.ametys.web.frontoffice.search.instance.SearchServiceInstance; 056import org.ametys.web.frontoffice.search.instance.SearchServiceInstanceManager; 057import org.ametys.web.frontoffice.search.metamodel.impl.ContentReferencingSearchServiceCriterionDefinition; 058import org.ametys.web.repository.page.Page; 059import org.ametys.web.repository.page.Page.PageType; 060import org.ametys.web.repository.page.ZoneItem; 061import org.ametys.web.repository.page.ZoneItem.ZoneType; 062 063/** 064 * Generates the exhaustive list of orgunits 065 */ 066public class OdfReferenceTableItemsGenerator extends ServiceableGenerator 067{ 068 private AmetysObjectResolver _resolver; 069 private RootOrgUnitProvider _rootOrgUnitProvider; 070 private ContentTypesHelper _cTypeHelper; 071 private SearchServiceInstanceManager _searchServiceInstanceManager; 072 private OdfReferenceTableHelper _odfReferenceTableHelper; 073 074 @Override 075 public void service(ServiceManager serviceManager) throws ServiceException 076 { 077 super.service(serviceManager); 078 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 079 _rootOrgUnitProvider = (RootOrgUnitProvider) serviceManager.lookup(RootOrgUnitProvider.ROLE); 080 _cTypeHelper = (ContentTypesHelper) serviceManager.lookup(ContentTypesHelper.ROLE); 081 _searchServiceInstanceManager = (SearchServiceInstanceManager) serviceManager.lookup(SearchServiceInstanceManager.ROLE); 082 _odfReferenceTableHelper = (OdfReferenceTableHelper) serviceManager.lookup(OdfReferenceTableHelper.ROLE); 083 } 084 085 @Override 086 public void generate() throws IOException, SAXException, ProcessingException 087 { 088 Request request = ObjectModelHelper.getRequest(objectModel); 089 090 String lang = parameters.getParameter("lang", (String) request.getAttribute("sitemapLanguage")); 091 Locale defaultLocale = LocaleUtils.toLocale(lang); 092 093 ZoneItem zoneItem = (ZoneItem) request.getAttribute(ZoneItem.class.getName()); 094 095 String refTableId = zoneItem.getServiceParameters().getValue("refTableId"); 096 097 contentHandler.startDocument(); 098 099 XMLUtils.startElement(contentHandler, "items"); 100 101 List<OdfReferenceTableEntry> items = _odfReferenceTableHelper.getItems(refTableId, false, new SortField("order", true)); 102 103 items.stream().forEach(LambdaUtils.wrapConsumer(e -> { 104 105 AttributesImpl attrs = new AttributesImpl(); 106 attrs.addCDATAAttribute("id", e.getId()); 107 attrs.addCDATAAttribute("code", e.getCode()); 108 109 XMLUtils.createElement(contentHandler, "item", attrs, e.getLabel(lang)); 110 })); 111 112 _saxSearchForm(zoneItem, refTableId); 113 114 XMLUtils.endElement(contentHandler, "items"); 115 116 contentHandler.endDocument(); 117 } 118 119 private void _saxSearchForm(ZoneItem zoneItem, String refTableId) throws SAXException 120 { 121 String criterionInputName = _getRefTableCriterionInputName(zoneItem, refTableId); 122 if (criterionInputName != null) 123 { 124 XMLUtils.startElement(contentHandler, "search-form"); 125 XMLUtils.createElement(contentHandler, "criterion", criterionInputName); 126 XMLUtils.endElement(contentHandler, "search-form"); 127 } 128 } 129 130 private String _getRefTableCriterionInputName(ZoneItem zoneItem, String refTableId) 131 { 132 String searchPageId = zoneItem.getServiceParameters().getValue("search-page"); 133 if (StringUtils.isNotEmpty(searchPageId)) 134 { 135 Page page = _resolver.resolveById(searchPageId); 136 if (page.getType() == PageType.CONTAINER) 137 { 138 Optional< ? extends ZoneItem> searchZoneItem = page.getZones().stream() 139 .flatMap(z -> z.getZoneItems().stream()) 140 .filter(zi -> zi.getType() == ZoneType.SERVICE) 141 .filter(zi -> zi.getServiceId().equals(SearchService.ROLE)) 142 .findFirst(); 143 144 if (searchZoneItem.isPresent()) 145 { 146 SearchServiceInstance serviceInstance = _searchServiceInstanceManager.get(searchZoneItem.get().getId()); 147 return serviceInstance.getCriterionTree() 148 .map(AbstractTreeNode::getFlatLeaves) 149 .orElseGet(Collections::emptyList) 150 .stream() 151 .map(TreeLeaf::getValue) 152 .filter(c -> c.getCriterionDefinition() instanceof ContentReferencingSearchServiceCriterionDefinition && ((ContentReferencingSearchServiceCriterionDefinition) c.getCriterionDefinition()).getContentTypeId().equals(refTableId)) 153 .findFirst() 154 .map(c -> c.getName()) 155 .orElseGet(null); 156 } 157 } 158 } 159 160 getLogger().warn("No criteria found related to selected reference table '" + refTableId + "'"); 161 return null; 162 } 163 164}