001/* 002 * Copyright 2014 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.export.indesign; 017 018import java.io.File; 019import java.io.FileFilter; 020import java.io.IOException; 021import java.io.InputStream; 022import java.util.HashMap; 023import java.util.Map; 024 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.logger.AbstractLogEnabled; 030import org.apache.avalon.framework.service.ServiceException; 031import org.apache.avalon.framework.service.ServiceManager; 032import org.apache.avalon.framework.service.Serviceable; 033import org.apache.commons.collections.MapUtils; 034import org.apache.excalibur.source.Source; 035import org.apache.excalibur.source.SourceResolver; 036import org.apache.excalibur.source.impl.FileSource; 037 038import org.ametys.runtime.i18n.I18nizableText; 039 040/** 041 * Helper storing mappings of xsl stylesheets (used in InDesign transformations) names with their labels. 042 */ 043public class IndesignTransformationHelper extends AbstractLogEnabled implements Component, Serviceable 044{ 045 /** The Indesign Transformation Helper's role */ 046 public static final String ROLE = IndesignTransformationHelper.class.getName(); 047 048 /** The path of the single program transformation stylesheets */ 049 private static final String __XSLT_DIRECTORY_URI = "context://WEB-INF/stylesheets/indesign"; 050 051 /** The path of the catalog transformation stylesheets */ 052 private static final String __GLOBAL_XSLT_DIRECTORY_URI = "context://WEB-INF/stylesheets/indesign/catalogue"; 053 054 private SourceResolver _srcResolver; 055 056 @Override 057 public void service(ServiceManager manager) throws ServiceException 058 { 059 _srcResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE); 060 } 061 062 /** 063 * Get available XSLT files for single program InDesign export 064 * @return the mapping of xsl names with their labels 065 */ 066 public Map<String, I18nizableText> getIndesignXslt() 067 { 068 try 069 { 070 return _parseXSLTFiles(__XSLT_DIRECTORY_URI); 071 } 072 catch (IOException e) 073 { 074 getLogger().error("Failed to get XSLT for indesign transformation", e); 075 } 076 077 return MapUtils.EMPTY_MAP; 078 } 079 080 /** 081 * Get available XSLT files for ODF catalog InDesign export 082 * @return the mapping of xsl names with their labels 083 */ 084 public Map<String, I18nizableText> getIndesignGlobalXslt() 085 { 086 try 087 { 088 return _parseXSLTFiles(__GLOBAL_XSLT_DIRECTORY_URI); 089 } 090 catch (IOException e) 091 { 092 getLogger().error("Failed to get XSLT for ODF catalog indesign transformation", e); 093 } 094 095 return MapUtils.EMPTY_MAP; 096 } 097 098 /** 099 * Get the xslt data from the given directory 100 * @param rootURI The directory where to find xsl files 101 * @return the data under the form of a Map 102 * @throws IOException if error occurred while parsing files 103 */ 104 private Map<String, I18nizableText> _parseXSLTFiles(String rootURI) throws IOException 105 { 106 Map<String, I18nizableText> xsltFiles = new HashMap<> (); 107 108 FileSource rootSrc = null; 109 try 110 { 111 rootSrc = (FileSource) _srcResolver.resolveURI(rootURI); 112 if (rootSrc.exists()) 113 { 114 File rootDir = rootSrc.getFile(); 115 File[] xslFiles = rootDir.listFiles(new FileFilter() 116 { 117 public boolean accept(File file) 118 { 119 String lowerCasedFileName = file.getName().toLowerCase(); 120 return file.isFile() && lowerCasedFileName.endsWith(".xsl"); 121 } 122 }); 123 124 // Generate the map 125 for (File xslFile : xslFiles) 126 { 127 I18nizableText label = _parseLabel(rootURI, xslFile.getName()); 128 xsltFiles.put(xslFile.getName(), label); 129 } 130 } 131 } 132 finally 133 { 134 if (rootSrc != null) 135 { 136 _srcResolver.release(rootSrc); 137 } 138 } 139 140 return xsltFiles; 141 } 142 143 private I18nizableText _parseLabel(String rootURI, String value) 144 { 145 String valueWithNoExtension = value.substring(0, value.length() - 4); 146 String url = rootURI + "/" + valueWithNoExtension + ".xml"; 147 148 Source source = null; 149 try 150 { 151 source = _srcResolver.resolveURI(url); 152 if (source.exists()) 153 { 154 try (InputStream inputStream = source.getInputStream()) 155 { 156 Configuration conf = new DefaultConfigurationBuilder().build(inputStream); 157 158 Configuration node = conf.getChild("label"); 159 I18nizableText text = _parseI18nizableText(node, "application"); 160 return text; 161 } 162 } 163 } 164 catch (Exception e) 165 { 166 // Nothing 167 } 168 finally 169 { 170 _srcResolver.release(source); 171 } 172 173 int i = valueWithNoExtension.lastIndexOf('/'); 174 String shortFilename = valueWithNoExtension.substring(i + 1); 175 return new I18nizableText(shortFilename); 176 } 177 178 private I18nizableText _parseI18nizableText(Configuration textConfig, String defaultCatalogue) throws ConfigurationException 179 { 180 boolean i18nSupported = textConfig.getAttributeAsBoolean("i18n", false); 181 String text = textConfig.getValue(); 182 183 if (i18nSupported) 184 { 185 String catalogue = textConfig.getAttribute("catalogue", null); 186 187 if (catalogue == null) 188 { 189 catalogue = defaultCatalogue; 190 } 191 192 return new I18nizableText(catalogue, text); 193 } 194 else 195 { 196 return new I18nizableText(text); 197 } 198 } 199}