001/* 002 * Copyright 2022 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; 017 018import java.lang.reflect.Array; 019import java.util.Arrays; 020import java.util.List; 021import java.util.Optional; 022import java.util.stream.Collectors; 023 024import org.apache.avalon.framework.configuration.Configurable; 025import org.apache.avalon.framework.configuration.Configuration; 026import org.apache.avalon.framework.configuration.ConfigurationException; 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.avalon.framework.service.Serviceable; 030import org.apache.commons.lang3.StringUtils; 031 032import org.ametys.cms.contenttype.ContentType; 033import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 034import org.ametys.cms.contenttype.MetadataType; 035import org.ametys.cms.contenttype.indexing.CustomIndexingField; 036import org.ametys.cms.data.ContentValue; 037import org.ametys.cms.repository.Content; 038import org.ametys.cms.repository.ContentAttributeTypeExtensionPoint; 039import org.ametys.odf.ODFHelper; 040import org.ametys.runtime.i18n.I18nizableText; 041import org.ametys.runtime.model.ModelItem; 042import org.ametys.runtime.model.type.ElementType; 043import org.ametys.runtime.plugin.component.AbstractLogEnabled; 044 045/** 046 * Indexing field for the order of degree 047 */ 048public class SubProgramParentProgramIndexingField extends AbstractLogEnabled implements CustomIndexingField, Configurable, Serviceable 049{ 050 /** The ODF Helper */ 051 protected ODFHelper _odfHelper; 052 053 /** The Content Type Extension Point */ 054 protected ContentTypeExtensionPoint _ctypeEP; 055 056 /** The Content Attribute Type Extension Point */ 057 protected ContentAttributeTypeExtensionPoint _contentAttributeTypeEP; 058 059 /** The field name */ 060 private String _name; 061 /** The label field */ 062 private I18nizableText _label; 063 /** The description field */ 064 private I18nizableText _description; 065 /** The program attribute name to index for subProgram */ 066 private String _programAttributeName; 067 /** The program attribute type to index for subProgram */ 068 private String _programAttributeType; 069 070 public void service(ServiceManager manager) throws ServiceException 071 { 072 _contentAttributeTypeEP = (ContentAttributeTypeExtensionPoint) manager.lookup(ContentAttributeTypeExtensionPoint.ROLE); 073 _ctypeEP = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE); 074 _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE); 075 } 076 077 public void configure(Configuration configuration) throws ConfigurationException 078 { 079 _name = configuration.getAttribute("name"); 080 _label = I18nizableText.parseI18nizableText(configuration.getChild("label"), "plugin.odf"); 081 _description = I18nizableText.parseI18nizableText(configuration.getChild("description"), "plugin.odf"); 082 083 _programAttributeType = configuration.getAttribute("type"); 084 if (StringUtils.isBlank(_programAttributeType)) 085 { 086 throw new ConfigurationException("Attribute 'type' is mandatory for " + SubProgramParentProgramIndexingField.class.getName()); 087 } 088 089 _programAttributeName = configuration.getChild("program-attribute-name").getValue(); 090 if (StringUtils.isBlank(_programAttributeName)) 091 { 092 throw new ConfigurationException("Child 'program-attribute-name' is mandatory for " + SubProgramParentProgramIndexingField.class.getName()); 093 } 094 } 095 096 public String getName() 097 { 098 return _name; 099 } 100 101 public I18nizableText getLabel() 102 { 103 return _label; 104 } 105 106 public I18nizableText getDescription() 107 { 108 return _description; 109 } 110 111 public MetadataType getType() 112 { 113 return MetadataType.valueOf(_programAttributeType.toUpperCase()); 114 } 115 116 public Object[] getValues(Content content) 117 { 118 if (content instanceof SubProgram) 119 { 120 SubProgram subProgram = (SubProgram) content; 121 List<Object> values = _odfHelper.getParentPrograms(subProgram) 122 .stream() 123 .map(this::_getValues) 124 .flatMap(List::stream) 125 .collect(Collectors.toList()); 126 127 if (getType() == MetadataType.CONTENT) 128 { 129 List<String> collect = values.stream() 130 .filter(ContentValue.class::isInstance) 131 .map(ContentValue.class::cast) 132 .map(ContentValue::getContentIfExists) 133 .filter(Optional::isPresent) 134 .map(o -> o.get().getId()) 135 .collect(Collectors.toList()); 136 137 return !collect.isEmpty() ? collect.toArray(new String[collect.size()]) : new String[0]; 138 } 139 else 140 { 141 ContentType programCType = _ctypeEP.getExtension(ProgramFactory.PROGRAM_CONTENT_TYPE); 142 ModelItem modelItem = programCType.getModelItem(_programAttributeName); 143 ElementType attributeType = (ElementType) _contentAttributeTypeEP.getExtension(modelItem.getType().getId()); 144 145 return !values.isEmpty() ? values.toArray((Object[]) Array.newInstance(attributeType.getManagedClass(), values.size())) : (Object[]) Array.newInstance(attributeType.getManagedClass(), 0); 146 } 147 } 148 149 return new Object[0]; 150 } 151 152 private List<Object> _getValues(Program program) 153 { 154 if (program.isMultiple(_programAttributeName)) 155 { 156 Object[] values = program.getValue(_programAttributeName); 157 158 return values != null ? Arrays.asList(values) : List.of(); 159 } 160 else 161 { 162 Object value = program.getValue(_programAttributeName); 163 return value != null ? List.of(value) : List.of(); 164 } 165 } 166}