001/* 002 * Copyright 2017 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.odfsync.apogee.scc.operator; 017 018import java.io.IOException; 019import java.io.InputStream; 020import java.util.HashMap; 021import java.util.Map; 022import java.util.Optional; 023 024import org.apache.avalon.framework.activity.Initializable; 025import org.apache.avalon.framework.component.Component; 026import org.apache.avalon.framework.configuration.Configuration; 027import org.apache.avalon.framework.configuration.ConfigurationException; 028import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 029import org.apache.avalon.framework.service.ServiceException; 030import org.apache.avalon.framework.service.ServiceManager; 031import org.apache.avalon.framework.service.Serviceable; 032import org.apache.excalibur.source.Source; 033import org.apache.excalibur.source.SourceResolver; 034import org.xml.sax.SAXException; 035 036import org.ametys.odf.enumeration.OdfReferenceTableEntry; 037import org.ametys.odf.enumeration.OdfReferenceTableHelper; 038import org.ametys.runtime.plugin.component.AbstractLogEnabled; 039 040/** 041 * Get mapped values from Apogée to Ametys. 042 */ 043public class ApogeeSynchronizingContentOperatorHelper extends AbstractLogEnabled implements Component, Serviceable, Initializable 044{ 045 /** The Avalon Role */ 046 public static final String ROLE = ApogeeSynchronizingContentOperatorHelper.class.getName(); 047 048 /** The source resolver */ 049 protected SourceResolver _srcResolver; 050 051 /** The ODF TableRef Helper */ 052 protected OdfReferenceTableHelper _odfRefTableHelper; 053 054 /** Mappings Apogee code - Ametys code */ 055 private Map<String, Map<String, String>> _codeMappings; 056 057 @Override 058 public void service(ServiceManager manager) throws ServiceException 059 { 060 _srcResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE); 061 _odfRefTableHelper = (OdfReferenceTableHelper) manager.lookup(OdfReferenceTableHelper.ROLE); 062 } 063 064 @Override 065 public void initialize() throws Exception 066 { 067 _codeMappings = new HashMap<>(); 068 } 069 070 /** 071 * Get the id of content associated with this Apogee code 072 * @param contentTypeId The content type id 073 * @param apogeeCode The code into Apogee 074 * @return The id of content or null if no match found 075 */ 076 public String getReferenceTableEntryId(String contentTypeId, String apogeeCode) 077 { 078 return Optional.ofNullable(apogeeCode) 079 .map(code -> _odfRefTableHelper.getItemFromApogee(contentTypeId, code)) // First check if we find the content from code Apogee 080 .or(() -> _getReferenceTableEntryFromMapping(apogeeCode, contentTypeId)) // Then check if we find the content from XML mapping 081 .map(OdfReferenceTableEntry::getId) 082 .orElse(null); 083 } 084 085 private Optional<OdfReferenceTableEntry> _getReferenceTableEntryFromMapping(String apogeeCode, String contentTypeId) 086 { 087 return Optional.ofNullable(apogeeCode) 088 .map(code -> _getConvertedCode(code, contentTypeId)) 089 .map(code -> _odfRefTableHelper.getItemFromCode(contentTypeId, code)); 090 } 091 092 private String _getConvertedCode(String apogeeCode, String contentTypeId) 093 { 094 String shortContentTypeId = contentTypeId.substring(contentTypeId.lastIndexOf(".") + 1); 095 return _codeMappings 096 .computeIfAbsent(shortContentTypeId, this::_readMapping) 097 .getOrDefault(apogeeCode, apogeeCode); 098 } 099 100 private Map<String, String> _readMapping(String contentTypeId) 101 { 102 Map<String, String> mapping = new HashMap<>(); 103 String uri = "context://WEB-INF/param/odf/apogee/code/" + contentTypeId.toLowerCase() + "_conversion.xml"; 104 Source source = null; 105 try 106 { 107 source = _srcResolver.resolveURI(uri); 108 if (source.exists()) 109 { 110 try (InputStream is = source.getInputStream()) 111 { 112 Configuration configuration = new DefaultConfigurationBuilder().build(is); 113 for (Configuration itemConf : configuration.getChildren()) 114 { 115 String apogeeCode = itemConf.getAttribute("code"); 116 String ametysCode = itemConf.getValue(); 117 118 mapping.put(apogeeCode, ametysCode); 119 } 120 } 121 } 122 else 123 { 124 getLogger().info("Apogée conversion file '{}' not found", uri); 125 } 126 } 127 catch (IOException | ConfigurationException | SAXException e) 128 { 129 getLogger().error("Unable to read the Apogee mapping file '{}' for content type '{}'", uri, contentTypeId, e); 130 } 131 finally 132 { 133 _srcResolver.release(source); 134 } 135 return mapping; 136 } 137}