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.cdmfr; 017 018import java.io.IOException; 019import java.io.InputStream; 020import java.util.Set; 021import java.util.stream.Stream; 022 023import org.apache.avalon.framework.activity.Initializable; 024import org.apache.avalon.framework.component.Component; 025import org.apache.avalon.framework.context.Context; 026import org.apache.avalon.framework.context.ContextException; 027import org.apache.avalon.framework.context.Contextualizable; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.avalon.framework.service.Serviceable; 031import org.apache.cocoon.components.ContextHelper; 032import org.apache.excalibur.source.Source; 033import org.apache.excalibur.source.SourceResolver; 034 035import org.ametys.odf.ODFHelper; 036import org.ametys.odf.program.Program; 037import org.ametys.runtime.config.Config; 038import org.ametys.runtime.plugin.component.AbstractLogEnabled; 039 040/** 041 * Processor to process CDM-fr files. 042 * - Filter programs if need 043 * - Iterate on programs 044 * - Generate the CDM-fr file 045 * - Process on the CDM-fr file 046 */ 047public abstract class AbstractCDMfrProcessor extends AbstractLogEnabled implements Component, Serviceable, Initializable, Contextualizable 048{ 049 /** The source resolver */ 050 protected SourceResolver _sourceResolver; 051 052 /** The ODF helper */ 053 protected ODFHelper _odfHelper; 054 055 /** the Avalon context */ 056 protected Context _context; 057 058 private boolean _isActive; 059 060 public void service(ServiceManager manager) throws ServiceException 061 { 062 _sourceResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE); 063 _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE); 064 } 065 066 public void initialize() throws Exception 067 { 068 _isActive = Config.getInstance().getValue(getConfigActiveParam()); 069 } 070 071 public void contextualize(Context context) throws ContextException 072 { 073 _context = context; 074 } 075 076 /** 077 * Get the configuration parameter name to determine if the process is active. 078 * @return The configuration parameter name 079 */ 080 protected abstract String getConfigActiveParam(); 081 082 /** 083 * <code>true</code> if the process is active 084 * @return <code>true</code> if the process is active 085 */ 086 public boolean isActive() 087 { 088 return _isActive; 089 } 090 091 /** 092 * Process the CDM-fr of the given programs. 093 * @param programs The programs to process 094 */ 095 public void processPrograms(Set<Program> programs) 096 { 097 // Check if the process is active 098 if (isActive()) 099 { 100 // Filter programs if needed and iterate on it 101 filterPrograms(programs.stream()).forEach( 102 program -> 103 { 104 // Get the CDM-fr content and process the program 105 Source cdmfrSource = null; 106 try 107 { 108 cdmfrSource = _getCDMfrContent(program); 109 try (InputStream is = cdmfrSource != null ? cdmfrSource.getInputStream() : null) 110 { 111 processProgram(program, is); 112 } 113 } 114 catch (IOException e) 115 { 116 getLogger().error(getErrorMessage(), e); 117 } 118 finally 119 { 120 if (cdmfrSource != null) 121 { 122 _sourceResolver.release(cdmfrSource); 123 } 124 } 125 } 126 ); 127 } 128 } 129 130 /** 131 * Process the program and its CDM-fr input stream. 132 * @param program The program 133 * @param cdmfrContent The CDM-fr content as {@link InputStream} 134 * @throws IOException if an exception occurs 135 */ 136 protected abstract void processProgram(Program program, InputStream cdmfrContent) throws IOException; 137 138 /** 139 * Get the error message if process fails. 140 * @return the error message 141 */ 142 protected abstract String getErrorMessage(); 143 144 /** 145 * Filter programs if needed. 146 * @param programs The programs to filter 147 * @return The filtered programs 148 */ 149 protected Stream<Program> filterPrograms(Stream<Program> programs) 150 { 151 // Default implementation does not filter anything 152 return programs; 153 } 154 155 /** 156 * Get the CDM-fr of the current program. 157 * @param program The program to export as CDM-fr 158 * @return The {@link InputStream} with the CDM-fr content 159 * @throws IOException if an exception occurs 160 */ 161 protected Source _getCDMfrContent(Program program) throws IOException 162 { 163 ContextHelper.getRequest(_context).setAttribute(ExportToCDMfrGenerator.CHECK_RIGHTS_ATTRIBUTE_NAME, false); 164 165 // Build the URI to export program as CDM-fr 166 StringBuilder sb = new StringBuilder("cocoon://_plugins/odf/export-cdmfr.xml"); 167 sb.append("?id=").append(program.getId()); 168 sb.append("&").append(ExportCDMfrHelper.REQUEST_PARAM_VALID_LABEL).append("=true"); 169 if (isCDMfrForAmetys()) 170 { 171 sb.append("&").append(ExportCDMfrHelper.REQUEST_PARAM_EXPORT_FOR_AMETYS).append("=true"); 172 } 173 174 // Generate CDM-fr file 175 return _sourceResolver.resolveURI(sb.toString()); 176 } 177 178 /** 179 * <code>true</code> to generate CDM-fr for another Ametys, <code>false</code> otherwise. 180 * @return <code>true</code> to generate CDM-fr for another Ametys instance 181 */ 182 protected abstract boolean isCDMfrForAmetys(); 183}