001/* 002 * Copyright 2020 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.ose.export.impl.odf; 017 018import java.util.List; 019import java.util.Optional; 020import java.util.Set; 021 022import org.apache.avalon.framework.component.Component; 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.avalon.framework.service.Serviceable; 026 027import org.ametys.cms.repository.Content; 028import org.ametys.odf.ProgramItem; 029import org.ametys.odf.enumeration.OdfReferenceTableEntry; 030import org.ametys.odf.orgunit.OrgUnit; 031import org.ametys.odf.ose.db.ParameterizableQuery; 032import org.ametys.odf.ose.export.utils.ElementRetriever; 033import org.ametys.odf.program.Container; 034import org.ametys.plugins.odfpilotage.cost.entity.CostComputationData; 035import org.ametys.runtime.plugin.component.AbstractLogEnabled; 036 037/** 038 * Exporter for program elements. 039 * @param <T> The type of the element to export, should extend {@link Content} and {@link ProgramItem} 040 */ 041public abstract class AbstractProgramElementExporter<T extends Content & ProgramItem> extends AbstractLogEnabled implements Component, Serviceable 042{ 043 /** The retriever of elements from ODF */ 044 protected ElementRetriever _elementRetriever; 045 046 @Override 047 public void service(ServiceManager manager) throws ServiceException 048 { 049 _elementRetriever = (ElementRetriever) manager.lookup(ElementRetriever.ROLE); 050 } 051 052 /** 053 * Get queries to export the given program element. 054 * @param programElement The program element to export 055 * @param oseCatalog The OSE catalog 056 * @param costData the result of cost computation of the catalog 057 * @return A {@link List} of {@link ParameterizableQuery} to export the program element, it can be empty if there is a problem (see logs) 058 */ 059 public List<ParameterizableQuery> getQueries(T programElement, Long oseCatalog, CostComputationData costData) 060 { 061 // Structure : Remonter parent par parent pour obtenir le ou les structures rattachées (sur abstractProgram) 062 Set<OrgUnit> orgUnits = _elementRetriever.retrieveOrgUnits(programElement); 063 064 // Get the step holder (étape porteuse en français dans le texte) 065 Set<Container> stepsHolder = _elementRetriever.retrieveStepsHolder(programElement); 066 067 // Get the period type on the current program element and parents 068 Set<OdfReferenceTableEntry> periodTypes = _elementRetriever.retrievePeriodTypes(programElement); 069 070 if (stepsHolder.size() != 1 || orgUnits.size() != 1) 071 { 072 LogUtils.programElementImpossibilityStepsOrOrgunits(getLogger(), programElement, stepsHolder, orgUnits); 073 return List.of(); 074 } 075 076 Container stepHolder = _getFirstStepHolder(stepsHolder); 077 Set<Container> steps = _elementRetriever.retrieveSteps(programElement); 078 // step holder is not among steps => do not export the program element 079 if (!steps.contains(stepHolder)) 080 { 081 LogUtils.programElementDebugIsNotContainedInSteps(getLogger(), programElement, stepHolder, steps); 082 return List.of(); 083 } 084 085 ProgramElementData data = new ProgramElementData(); 086 Optional.of(periodTypes) 087 .map(this::_getFirstRefTableCode) 088 .ifPresentOrElse( 089 data::setPeriodType, 090 () -> LogUtils.programElementWarningPeriodTypes(getLogger(), programElement, periodTypes) 091 ); 092 data.setStepHolder(stepHolder.getCode()); 093 data.setOrgUnit(_getFirstOrgUnitCode(orgUnits)); 094 data.setSteps(steps); 095 096 return _getQueries(programElement, data, oseCatalog, costData); 097 } 098 099 /** 100 * Get the queries to create the program element in the OSE database. 101 * @param programElement The program element 102 * @param data The calculated data attached to the program element 103 * @param oseCatalog The OSE catalog 104 * @param costData the result of cost computation of the catalog 105 * @return The list of queries 106 */ 107 protected abstract List<ParameterizableQuery> _getQueries(T programElement, ProgramElementData data, Long oseCatalog, CostComputationData costData); 108 109 private Container _getFirstStepHolder(Set<Container> stepsHolder) 110 { 111 return stepsHolder 112 .stream() 113 .findFirst() 114 .get(); 115 } 116 117 private String _getFirstOrgUnitCode(Set<OrgUnit> orgUnits) 118 { 119 return orgUnits 120 .stream() 121 .findFirst() 122 .map(OrgUnit::getUAICode) 123 .get(); 124 } 125 126 private String _getFirstRefTableCode(Set<OdfReferenceTableEntry> entries) 127 { 128 return entries 129 .stream() 130 .findFirst() 131 .map(OdfReferenceTableEntry::getCode) 132 .orElse(null); 133 } 134 135 /** 136 * An object to represent common computed data on the program element like orgunit, step holder, etc. 137 */ 138 protected static class ProgramElementData 139 { 140 private String _orgUnitCode; 141 private String _stepHolderCode; 142 private Set<Container> _steps; 143 private String _periodTypeCode; 144 145 /** 146 * Set the orgunit code of the program element. 147 * @param orgUnitCode The code of the orgunit 148 */ 149 public void setOrgUnit(String orgUnitCode) 150 { 151 _orgUnitCode = orgUnitCode; 152 } 153 154 /** 155 * Set the step holder code of the program element. 156 * @param stepHolderCode The code of the step holder 157 */ 158 public void setStepHolder(String stepHolderCode) 159 { 160 _stepHolderCode = stepHolderCode; 161 } 162 163 /** 164 * Set the period type code of the program element. 165 * @param periodTypeCode The code of the period type 166 */ 167 public void setPeriodType(String periodTypeCode) 168 { 169 _periodTypeCode = periodTypeCode; 170 } 171 172 /** 173 * Set the steps attached to the program element. 174 * @param steps The steps 175 */ 176 public void setSteps(Set<Container> steps) 177 { 178 _steps = steps; 179 } 180 181 /** 182 * Get the orgunit code of the program element. 183 * @return The code of the orgunit 184 */ 185 public String getOrgUnit() 186 { 187 return _orgUnitCode; 188 } 189 190 /** 191 * Get the step holder code of the program element. 192 * @return The code of the step holder 193 */ 194 public String getStepHolder() 195 { 196 return _stepHolderCode; 197 } 198 199 /** 200 * Get the period type code of the program element. 201 * @return The code of the period type 202 */ 203 public String getPeriodType() 204 { 205 return _periodTypeCode; 206 } 207 208 /** 209 * Get the steps attached to the program element. 210 * @return The steps 211 */ 212 public Set<Container> getSteps() 213 { 214 return _steps; 215 } 216 } 217}