001package org.apache.maven.doxia.module.fo; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.BufferedOutputStream; 023import java.io.File; 024import java.io.FileOutputStream; 025import java.io.IOException; 026import java.io.OutputStream; 027import java.util.Date; 028 029import javax.xml.transform.Result; 030import javax.xml.transform.Transformer; 031import javax.xml.transform.TransformerConfigurationException; 032import javax.xml.transform.TransformerException; 033import javax.xml.transform.TransformerFactory; 034import javax.xml.transform.sax.SAXResult; 035import javax.xml.transform.stream.StreamSource; 036 037import org.apache.fop.apps.FOPException; 038import org.apache.fop.apps.FOUserAgent; 039import org.apache.fop.apps.Fop; 040import org.apache.fop.apps.FopFactory; 041import org.apache.fop.apps.MimeConstants; 042import org.apache.maven.doxia.document.DocumentModel; 043import org.codehaus.plexus.util.IOUtil; 044import org.codehaus.plexus.util.StringUtils; 045 046/** 047 * <code>FO Sink</code> utilities. 048 * 049 * @author ltheussl 050 * @version $Id$ 051 * @since 1.1 052 */ 053public class FoUtils 054{ 055 /** To reuse the FopFactory **/ 056 private static final FopFactory FOP_FACTORY = FopFactory.newInstance(); 057 058 /** To reuse the TransformerFactory **/ 059 private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance(); 060 061 /** 062 * Converts an FO file to a PDF file using FOP. 063 * 064 * @param fo the FO file, not null. 065 * @param pdf the target PDF file, not null. 066 * @param resourceDir The base directory for relative path resolution, could be null. 067 * If null, defaults to the parent directory of fo. 068 * @param documentModel the document model to add PDF metadatas like author, title and keywords, could be null. 069 * @throws javax.xml.transform.TransformerException In case of a conversion problem. 070 * @since 1.1.1 071 */ 072 public static void convertFO2PDF( File fo, File pdf, String resourceDir, DocumentModel documentModel ) 073 throws TransformerException 074 { 075 FOUserAgent foUserAgent = getDefaultUserAgent( fo, resourceDir ); 076 077 if ( documentModel != null && documentModel.getMeta() != null ) 078 { 079 // http://xmlgraphics.apache.org/fop/embedding.html#user-agent 080 String authors = documentModel.getMeta().getAllAuthorNames(); 081 if ( StringUtils.isNotEmpty( authors ) ) 082 { 083 foUserAgent.setAuthor( authors ); 084 } 085 if ( StringUtils.isNotEmpty( documentModel.getMeta().getTitle() ) ) 086 { 087 foUserAgent.setTitle( documentModel.getMeta().getTitle() ); 088 } 089 String keywords = documentModel.getMeta().getAllKeyWords(); 090 if ( StringUtils.isNotEmpty( keywords ) ) 091 { 092 foUserAgent.setKeywords( keywords ); 093 } 094 if ( StringUtils.isNotEmpty( documentModel.getMeta().getCreator() ) ) 095 { 096 foUserAgent.setCreator( documentModel.getMeta().getCreator() ); 097 } 098 if ( StringUtils.isNotEmpty( documentModel.getMeta().getGenerator() ) ) 099 { 100 foUserAgent.setProducer( documentModel.getMeta().getGenerator() ); 101 } 102 if ( documentModel.getMeta().getCreationDate() != null ) 103 { 104 foUserAgent.setCreationDate( documentModel.getMeta().getCreationDate() ); 105 } 106 } 107 108 if ( foUserAgent.getCreator() == null ) 109 { 110 foUserAgent.setCreator( System.getProperty( "user.name" ) ); 111 } 112 if ( foUserAgent.getCreationDate() == null ) 113 { 114 foUserAgent.setCreationDate( new Date() ); 115 } 116 117 convertFO2PDF( fo, pdf, resourceDir, foUserAgent ); 118 } 119 120 /** 121 * Converts an FO file to a PDF file using FOP. 122 * 123 * @param fo the FO file, not null. 124 * @param pdf the target PDF file, not null. 125 * @param resourceDir The base directory for relative path resolution, could be null. 126 * If null, defaults to the parent directory of fo. 127 * @param foUserAgent the FOUserAgent to use. 128 * May be null, in which case a default user agent will be used. 129 * @throws javax.xml.transform.TransformerException In case of a conversion problem. 130 * @since 1.1.1 131 */ 132 public static void convertFO2PDF( File fo, File pdf, String resourceDir, FOUserAgent foUserAgent ) 133 throws TransformerException 134 { 135 FOUserAgent userAgent = ( foUserAgent == null ? getDefaultUserAgent( fo, resourceDir ) : foUserAgent ); 136 137 OutputStream out = null; 138 try 139 { 140 try 141 { 142 out = new BufferedOutputStream( new FileOutputStream( pdf ) ); 143 } 144 catch ( IOException e ) 145 { 146 throw new TransformerException( e ); 147 } 148 149 Result res = null; 150 try 151 { 152 Fop fop = FOP_FACTORY.newFop( MimeConstants.MIME_PDF, userAgent, out ); 153 res = new SAXResult( fop.getDefaultHandler() ); 154 } 155 catch ( FOPException e ) 156 { 157 throw new TransformerException( e ); 158 } 159 160 Transformer transformer = null; 161 try 162 { 163 // identity transformer 164 transformer = TRANSFORMER_FACTORY.newTransformer(); 165 } 166 catch ( TransformerConfigurationException e ) 167 { 168 throw new TransformerException( e ); 169 } 170 171 transformer.transform( new StreamSource( fo ), res ); 172 } 173 finally 174 { 175 IOUtil.close( out ); 176 } 177 } 178 179 /** 180 * Converts an FO file to a PDF file using FOP. 181 * 182 * @param fo the FO file, not null. 183 * @param pdf the target PDF file, not null. 184 * @param resourceDir The base directory for relative path resolution, could be null. 185 * If null, defaults to the parent directory of fo. 186 * @throws javax.xml.transform.TransformerException In case of a conversion problem. 187 * @see #convertFO2PDF(File, File, String, DocumentModel) 188 */ 189 public static void convertFO2PDF( File fo, File pdf, String resourceDir ) 190 throws TransformerException 191 { 192 convertFO2PDF( fo, pdf, resourceDir, (DocumentModel) null ); 193 } 194 195 /** 196 * Returns a base URL to be used by the FOUserAgent. 197 * 198 * @param fo the FO file. 199 * @param resourceDir the resource directory. 200 * @return String. 201 */ 202 private static String getBaseURL( File fo, String resourceDir ) 203 { 204 String url = null; 205 206 if ( resourceDir == null ) 207 { 208 url = "file:///" + fo.getParent() + "/"; 209 } 210 else 211 { 212 url = "file:///" + resourceDir + "/"; 213 } 214 215 return url; 216 } 217 218 private static FOUserAgent getDefaultUserAgent( File fo, String resourceDir ) 219 { 220 FOUserAgent foUserAgent = FOP_FACTORY.newFOUserAgent(); 221 foUserAgent.setBaseURL( getBaseURL( fo, resourceDir ) ); 222 223 return foUserAgent; 224 } 225 226 private FoUtils() 227 { 228 // Utility class 229 } 230}