001/* 002 * Copyright 2024 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.odf.program.properties; 017 018import java.util.Arrays; 019import java.util.List; 020import java.util.Optional; 021import java.util.Set; 022import java.util.stream.Collectors; 023 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026 027import org.ametys.cms.data.ContentValue; 028import org.ametys.cms.data.type.indexing.IndexableElementType; 029import org.ametys.cms.model.CMSDataContext; 030import org.ametys.cms.model.properties.AbstractContentProperty; 031import org.ametys.cms.repository.Content; 032import org.ametys.cms.repository.ModifiableContent; 033import org.ametys.cms.search.model.CriterionDefinitionAwareElementDefinition; 034import org.ametys.cms.search.model.CriterionDefinitionHelper; 035import org.ametys.cms.search.model.IndexationAwareElementDefinition; 036import org.ametys.cms.search.model.IndexationAwareElementDefinitionHelper; 037import org.ametys.odf.ODFHelper; 038import org.ametys.odf.ProgramItem; 039import org.ametys.odf.orgunit.OrgUnitFactory; 040 041/** 042 * Property to get the nearest orgunits linked to a program item. 043 * This property seeks the orgunits in the parents when it's not defined in the given program item. 044 * It stop to the first parents who have orgunits 045 */ 046public class NearestOrgUnitsProperty extends AbstractContentProperty<Content> implements CriterionDefinitionAwareElementDefinition<ContentValue>, IndexationAwareElementDefinition<ContentValue, Content> 047{ 048 /** The ODF Helper */ 049 protected ODFHelper _odfHelper; 050 /** The criterion definition helper */ 051 protected CriterionDefinitionHelper _criterionDefinitionHelper; 052 /** The indexation aware element definition helper */ 053 protected IndexationAwareElementDefinitionHelper _indexationAwareElementDefinitionHelper; 054 055 @Override 056 public void service(ServiceManager manager) throws ServiceException 057 { 058 super.service(manager); 059 _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE); 060 _criterionDefinitionHelper = (CriterionDefinitionHelper) manager.lookup(CriterionDefinitionHelper.ROLE); 061 _indexationAwareElementDefinitionHelper = (IndexationAwareElementDefinitionHelper) manager.lookup(IndexationAwareElementDefinitionHelper.ROLE); 062 } 063 064 @Override 065 protected Set<? extends ModifiableContent> _getLinkedContents(Content content) 066 { 067 if (content instanceof ProgramItem programItem) 068 { 069 return _getSelfAndParentOrgUnits(programItem); 070 } 071 return null; 072 } 073 074 private Set<ModifiableContent> _getSelfAndParentOrgUnits(ProgramItem programItem) 075 { 076 Set<ModifiableContent> orgUnits = Arrays.stream(((Content) programItem).getValue(ProgramItem.ORG_UNITS_REFERENCES, false, new ContentValue[0])) 077 .map(ContentValue::getContentIfExists) 078 .flatMap(Optional::stream) 079 .collect(Collectors.toSet()); 080 081 // If the current program item has an orgUnit, dont search in the parent 082 if (orgUnits.isEmpty()) 083 { 084 List<ProgramItem> parents = _odfHelper.getParentProgramItems(programItem); 085 for (ProgramItem parent : parents) 086 { 087 orgUnits.addAll(_getSelfAndParentOrgUnits(parent)); 088 } 089 } 090 091 return orgUnits; 092 } 093 094 @Override 095 public String getDefaultCriterionWidget() 096 { 097 return "edition.select-orgunit"; 098 } 099 100 @Override 101 public boolean isMultiple() 102 { 103 return true; 104 } 105 106 public String getContentTypeId() 107 { 108 return OrgUnitFactory.ORGUNIT_CONTENT_TYPE; 109 } 110 111 public IndexableElementType getDefaultCriterionType() 112 { 113 CMSDataContext context = CMSDataContext.newInstance() 114 .withModelItem(this); 115 116 String typeId = getType().getDefaultCriterionTypeId(context); 117 return _criterionDefinitionHelper.getCriterionDefinitionType(typeId); 118 } 119 120 public String getSolrSortFieldName() 121 { 122 return _indexationAwareElementDefinitionHelper.getDefaultSolrSortFieldName(this); 123 } 124}