All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rackspace.cloud.api.docs.PDFMojo Maven / Gradle / Ivy

package com.rackspace.cloud.api.docs;

import com.agilejava.docbkx.maven.AbstractFoMojo;
import com.agilejava.docbkx.maven.PreprocessingFilter;
import com.agilejava.docbkx.maven.TransformerBuilder;
import com.rackspace.cloud.api.docs.CalabashHelper;
import com.rackspace.cloud.api.docs.FileUtils;
import com.rackspace.cloud.api.docs.GlossaryResolver;

import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.commons.io.IOUtils;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.apache.maven.plugin.MojoExecutionException;
import org.xml.sax.SAXException;
import org.xml.sax.InputSource;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.sax.SAXSource;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public abstract class PDFMojo extends AbstractFoMojo {
    private File imageDirectory;
    private File sourceDirectory;
    private File sourceDocBook;

    private File coverImageTemplate;
    private File coverImage;

    private static final String COVER_IMAGE_TEMPLATE_NAME = "cover.st";
    private static final String COVER_IMAGE_NAME = "cover.svg";

    private static final String COVER_XSL = "cloud/cover.xsl";

    /**
     * @parameter expression="${project.build.directory}"
     */
    private File projectBuildDirectory;

    /**
     * The greeting to display.
     *
     * @parameter expression="${generate-pdf.branding}" default-value="rackspace"
     */
    private String branding;


    /**
     * Display built for OpenStack logo?
     *
     * @parameter expression="${generate-pdf.builtForOpenStack}" default-value="0"
     */
    private String builtForOpenStack;

    /**
     * Path to an alternative cover logo.
     *
     * @parameter expression="${generate-pdf.coverLogoPath}" default-value=""
     */
    private String coverLogoPath;


    /**
     * Path to an alternative cover logo.
     *
     * @parameter expression="${generate-pdf.secondaryCoverLogoPath}" 
     */
    private String secondaryCoverLogoPath;


    /**
     * Distance from the left edge of the page at which the 
     * cover logo is displayed. 
     *
     * @parameter expression="${generate-pdf.coverLogoLeft}" default-value=""
     */
    private String coverLogoLeft;

    /**
     * Distance from the top of the page at which teh 
     * cover logo is displayed.
     *
     * @parameter expression="${generate-pdf.coverLogoTop}" default-value=""
     */
    private String coverLogoTop;

    /**
     * url to display under the cover logo. 
     *
     * @parameter expression="${generate-pdf.coverUrl}" default-value=""
     */
    private String coverUrl;

    /**
     * The color to use for the polygon on the cover
     *
     * @parameter expression="${generate-pdf.coverColor}" default-value=""
     */
    private String coverColor;

    /**
     * 
     *
     * @parameter expression="${generate-pdf.pageWidth}" default-value=""
     */
    private String pageWidth;

    /**
     * 
     *
     * @parameter expression="${generate-pdf.pageHeight}" default-value=""
     */
    private String pageHeight;

    /**
     * Should cover be omitted?
     *
     * @parameter expression="${generate-pdf.omitCover}" default-value=""
     */
    private String omitCover;

    /**
     * Double sided pdfs?
     *
     * @parameter expression="${generate-pdf.doubleSided}" default-value=""
     */
    private String doubleSided;


    /**
     * The greeting to display.
     *
     * @parameter expression="${generate-pdf.variablelistAsBlocks}" 
     */
    private String variablelistAsBlocks;

    
    /**
     * A parameter used to configure how many elements to trim from the URI in the documentation for a wadl method.
     *
     * @parameter expression="${generate-pdf.trim.wadl.uri.count}" default-value=""
     */
    private String trimWadlUriCount;

    /**
     * Controls how the path to the wadl is calculated. If 0 or not set, then 
     * The xslts look for the normalized wadl in /generated-resources/xml/xslt/.
     * Otherwise, in /generated-resources/xml/xslt/path/to/docbook-src, e.g.
     * /generated-resources/xml/xslt/src/docbkx/foo.wadl
     *
     * @parameter expression="${generate-pdf.compute.wadl.path.from.docbook.path}" default-value="0"
     */
    private String computeWadlPathFromDocbookPath;

    /**
     * @parameter 
     *     expression="${generate-pdf.canonicalUrlBase}"
     *     default-value=""
     */
    private String canonicalUrlBase;
    
    /**
     * @parameter 
     *     expression="${generate-pdf.replacementsFile}"
     *     default-value="replacements.config"
     */
    private String replacementsFile;

    /**
     * 
     * @parameter 
     *     expression="${generate-pdf.failOnValidationError}"
     *     default-value="yes"
     */
    private String failOnValidationError;
    
    /**
     * A parameter used to specify the security level (external, internal, reviewer, writeronly) of the document.
     *
     * @parameter 
     *     expression="${generate-pdf.security}" 
     */
    private String security;
     
    /**
    *
    * @parameter
    *     expression="${generate-pdf.strictImageValidation}"
    *     default-value=true
    */
    private boolean strictImageValidation;

   /**
     * 
     *
     * @parameter expression="${generate-pdf.draft.status}" default-value=""
     */
    private String draftStatus;

    /**
     * @parameter expression="${generate-pdf.statusBarText}"
     */
    private String statusBarText;
    
    /**
     * @parameter expression="${generate-pdf.bodyFont}"
     */
    private String bodyFont;

    /**
     * @parameter expression="${generate-pdf.monospaceFont}"
     */
    private String monospaceFont;
    
    /**
     * @parameter expression="${generate-pdf.localFontPath}"
     */
    private String localFontPath;

    protected void setImageDirectory (File imageDirectory) {
        this.imageDirectory = imageDirectory;
    }

    protected File getImageDirectory() {
        return this.imageDirectory;
    }

    protected String getNonDefaultStylesheetLocation() {
        return "cloud/fo/docbook.xsl";
    }


    public void preProcess() throws MojoExecutionException {
        super.preProcess();

        final File targetDirectory = getTargetDirectory();
        File imageParentDirectory  = targetDirectory.getParentFile();
        File xslParentDirectory  = targetDirectory.getParentFile();

        if (!targetDirectory.exists()) {
            FileUtils.mkdir(targetDirectory);
        }

        //
        // Extract all images into the image directory.
        //
        FileUtils.extractJaredDirectory("images",PDFMojo.class,imageParentDirectory);
        setImageDirectory (new File (imageParentDirectory, "images"));
        
        FileUtils.extractJaredDirectory("cloud/war",PDFMojo.class,xslParentDirectory);

        //
        // Extract all fonts into fonts directory
        //
        FileUtils.extractJaredDirectory("fonts",PDFMojo.class,imageParentDirectory);
    }


    //
    //  Really this is an exact copy of the parent impl, except I use
    //  my own version of loadFOPConfig.  Really, I should be able to
    //  overwrite that method.
    //
    public void postProcessResult(File result) throws MojoExecutionException {
        final FopFactory fopFactory = FopFactory.newInstance();
        final FOUserAgent userAgent = fopFactory.newFOUserAgent();

        // First transform the cover page
        transformCover();

        // FOUserAgent can be used to set PDF metadata
        Configuration configuration = loadFOPConfig();
        InputStream in = null;
        OutputStream out = null;

        try
            {
                String baseURL = sourceDirectory.toURI().toURL().toExternalForm();
                baseURL = baseURL.replace("file:/", "file:///");

                userAgent.setBaseURL(baseURL);
                System.err.println ("Absolute path is "+baseURL);

                in = openFileForInput(result);
                out = openFileForOutput(getOutputFile(result));
                fopFactory.setUserConfig(configuration);
                Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, out);

                // Setup JAXP using identity transformer
                TransformerFactory factory = TransformerFactory.newInstance();
                Transformer transformer = factory.newTransformer(); // identity transformer

                // Setup input stream
                Source src = new StreamSource(in);

                // Resulting SAX events (the generated FO) must be piped through to FOP
                Result res = new SAXResult(fop.getDefaultHandler());

                // Start XSLT transformation and FOP processing
                transformer.transform(src, res);
            }
        catch (FOPException e)
            {
                throw new MojoExecutionException("Failed to convert to PDF", e);
            }
        catch (TransformerConfigurationException e)
            {
                throw new MojoExecutionException("Failed to load JAXP configuration", e);
            }
        catch (TransformerException e)
            {
                throw new MojoExecutionException("Failed to transform to PDF", e);
            }
        catch (MalformedURLException e)
            {
                throw new MojoExecutionException("Failed to get FO basedir", e);
            }
        finally
            {
                IOUtils.closeQuietly(out);
                IOUtils.closeQuietly(in);
            }
    }

    protected InputStream openFileForInput(File file)
            throws MojoExecutionException {
        try {
            return new FileInputStream(file);
        } catch (FileNotFoundException fnfe) {
            throw new MojoExecutionException("Failed to open " + file
                    + " for input.");
        }
    }

    protected File getOutputFile(File inputFile) {
        return new File (inputFile.getAbsolutePath().replaceAll(".fo$",".pdf"));
    }

    protected OutputStream openFileForOutput(File file)
            throws MojoExecutionException {
        try {
          return new BufferedOutputStream(new FileOutputStream(file));
        } catch (FileNotFoundException fnfe) {
            throw new MojoExecutionException("Failed to open " + file
                    + " for output.");
        }
    }

    protected Configuration loadFOPConfig() throws MojoExecutionException {
        System.out.println ("At load config");
        String fontPath = (null != localFontPath && localFontPath != "")? localFontPath: (new File(getTargetDirectory().getParentFile(), "fonts")).getAbsolutePath();
        StringTemplateGroup templateGroup = new StringTemplateGroup("fonts", fontPath);
        StringTemplate template = templateGroup.getInstanceOf("fontconfig");
        DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
        template.setAttribute ("fontPath",fontPath);
        final String config = template.toString();
        if (getLog().isDebugEnabled()) {
            getLog().debug(config);
        }
        try {
            return builder.build(IOUtils.toInputStream(config));
        } catch (IOException ioe) {
            throw new MojoExecutionException("Failed to load FOP config.", ioe);
        } catch (SAXException saxe) {
            throw new MojoExecutionException("Failed to parse FOP config.",
                    saxe);
        } catch (ConfigurationException e) {
            throw new MojoExecutionException(
                    "Failed to do something Avalon requires....", e);
        }
   }

    protected TransformerBuilder createTransformerBuilder(URIResolver resolver) {
        return super.createTransformerBuilder (new GlossaryResolver(new DocBookResolver (resolver, getType()), getType()));
    }

    public void adjustTransformer(Transformer transformer, String sourceFilename, File targetFile) {
        GitHelper.addCommitProperties(transformer, projectBuildDirectory, 7, getLog());

        super.adjustTransformer(transformer, sourceFilename, targetFile);

	transformer.setParameter("branding", branding);
	transformer.setParameter("builtForOpenStack", builtForOpenStack);
	transformer.setParameter("coverLogoPath", coverLogoPath);
	if(null != secondaryCoverLogoPath){
	    transformer.setParameter("secondaryCoverLogoPath", secondaryCoverLogoPath);
	}
	transformer.setParameter("coverLogoLeft", coverLogoLeft);
	transformer.setParameter("coverLogoTop", coverLogoTop);
	transformer.setParameter("coverUrl", coverUrl);
	transformer.setParameter("coverColor", coverColor);

	if(null != pageWidth){ 	
	    transformer.setParameter("page.width", pageWidth); 
	}
	if(null != pageHeight){ 	
	    transformer.setParameter("page.height", pageHeight); 
	}
	if(null != omitCover){ 	
	    transformer.setParameter("omitCover", omitCover); 
	}
	if(null != doubleSided){ 	
	    transformer.setParameter("double.sided", doubleSided); 
	}


    String sysDraftStatus=System.getProperty("draft.status");
    if (getLog().isDebugEnabled()) {
	getLog().info("adjustTransformer():sysDraftStatus="+sysDraftStatus);
    }
    if(null!=sysDraftStatus && !sysDraftStatus.isEmpty()){
    	draftStatus=sysDraftStatus;
    }

	transformer.setParameter("draft.status", draftStatus);

	String sysStatusBarText=System.getProperty("statusBarText");
	if(null!=sysStatusBarText && !sysStatusBarText.isEmpty()){
	    statusBarText=sysStatusBarText;
	}
    if(statusBarText != null){
    	transformer.setParameter("statusBarText", statusBarText);
    }
    if(bodyFont != null){
    	transformer.setParameter("bodyFont", bodyFont);
    }
    if(monospaceFont != null){
    	transformer.setParameter("monospaceFont", monospaceFont);
    }
    
	transformer.setParameter("project.build.directory", projectBuildDirectory.toURI().toString());
    
	String sysSecurity=System.getProperty("security");
	if (getLog().isDebugEnabled()) {
	    getLog().info("adjustTransformer():sysSecurity="+sysSecurity);
	}
    if(null!=sysSecurity && !sysSecurity.isEmpty()){
    	security=sysSecurity;
    }
	if(security != null){
	    transformer.setParameter("security",security);
	}
	
   if(trimWadlUriCount != null){
	transformer.setParameter("trim.wadl.uri.count",trimWadlUriCount);
    }

        //
        //  Setup graphics paths
        //
        sourceDocBook = new File(sourceFilename);
        sourceDirectory = sourceDocBook.getParentFile();
        File imageDirectory = getImageDirectory();
        File calloutDirectory = new File (imageDirectory, "callouts");

	transformer.setParameter("docbook.infile",sourceDocBook.toURI().toString());
	transformer.setParameter("source.directory",sourceDirectory.toURI().toString());
	transformer.setParameter("compute.wadl.path.from.docbook.path",computeWadlPathFromDocbookPath);
	
        transformer.setParameter ("admon.graphics.path", imageDirectory.toURI().toString());
        transformer.setParameter ("callout.graphics.path", calloutDirectory.toURI().toString());

        //
        //  Setup the background image file
        //
        File cloudSub = new File (imageDirectory, "cloud");
        File ccSub    = new File (imageDirectory, "cc");
        coverImage = new File (cloudSub, COVER_IMAGE_NAME);
        coverImageTemplate = new File (cloudSub, COVER_IMAGE_TEMPLATE_NAME);

	coverImageTemplate = new File (cloudSub, "rackspace-cover.st");

        transformer.setParameter ("cloud.api.background.image", coverImage.toURI().toString());
        transformer.setParameter ("cloud.api.cc.image.dir", ccSub.toURI().toString());
    }

    protected void transformCover() throws MojoExecutionException {
        try {
            ClassLoader classLoader = Thread.currentThread()
                .getContextClassLoader();

            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(new StreamSource(classLoader.getResourceAsStream(COVER_XSL)));
	    if(coverColor != null){
		transformer.setParameter("coverColor", coverColor);
	    }

	    String sysDraftStatus=System.getProperty("draft.status");
	    if(null!=sysDraftStatus && !sysDraftStatus.isEmpty()){
	    	draftStatus=sysDraftStatus;
	    }
	    if(null!=draftStatus){
		transformer.setParameter("draft.status", draftStatus);
	    }

	    String sysStatusBarText=System.getProperty("statusBarText");
	    if(null!=sysStatusBarText && !sysStatusBarText.isEmpty()){
		statusBarText=sysStatusBarText;
	    }
	    if(null != statusBarText){
		transformer.setParameter("status.bar.text", statusBarText);
	    }
	    transformer.setParameter("branding", branding);

            //transformer.setParameter("docbook.infile",sourceDocBook.toURI().toString());
	    	String srcFilename = sourceDocBook.getName();
		if (getLog().isDebugEnabled()) {
		    getLog().info("SOURCE FOR COVER PAGE: "+this.projectBuildDirectory+"/docbkx/"+srcFilename);
		}
	    	transformer.setParameter("docbook.infile", new File(this.projectBuildDirectory, "docbkx/"+srcFilename).toURI().toString());
            transformer.transform (new StreamSource(coverImageTemplate), new StreamResult(coverImage));
        }
        catch (TransformerConfigurationException e)
            {
                throw new MojoExecutionException("Failed to load JAXP configuration", e);
            }
        catch (TransformerException e)
            {
                throw new MojoExecutionException("Failed to transform to cover", e);
            }
    }
    
    
    
    @Override
    protected Source createSource(String inputFilename, File sourceFile, PreprocessingFilter filter)
            throws MojoExecutionException {

        String pathToPipelineFile = "classpath:///pdf.xpl"; //use "classpath:///path" for this to work

	String sourceFileNameNormalized = sourceFile.toURI().toString();
	//from super
	final InputSource inputSource = new InputSource(sourceFileNameNormalized);
	Source source = new SAXSource(filter, inputSource);
        //Source source = super.createSource(inputFilename, sourceFile, filter);

        Map map=new HashMap();
	    String sysSecurity=System.getProperty("security");
	    getLog().info("adjustTransformer():sysSecurity="+sysSecurity);
	    if(null!=sysSecurity && !sysSecurity.isEmpty()){
	    	security=sysSecurity;
	    }

	map.put("targetDirectory", getTargetDirectory().getParentFile());
	map.put("targetHtmlContentDir", new File(getTargetDirectory(),  "/wadls/"));
        map.put("security", security);
        map.put("canonicalUrlBase", canonicalUrlBase);
        map.put("replacementsFile", replacementsFile);
        map.put("failOnValidationError", failOnValidationError);
        map.put("project.build.directory", this.projectBuildDirectory);
        map.put("inputSrcFile", inputFilename);
        map.put("outputType", "pdf");
        map.put("strictImageValidation", String.valueOf(this.strictImageValidation));
        map.put("status.bar.text", getProperty("statusBarText"));
        map.put("bodyFont", getProperty("bodyFont"));
        map.put("monospaceFont", getProperty("monospaceFont"));
        map.put("draft.status", getProperty("draftStatus"));
        
        // Profiling attrs:        
        map.put("profile.os", getProperty("profileOs"));
        map.put("profile.arch", getProperty("profileArch"));
        map.put("profile.condition", getProperty("profileCondition"));
        map.put("profile.audience", getProperty("profileAudience"));
        map.put("profile.conformance", getProperty("profileConformance"));
        map.put("profile.revision", getProperty("profileRevision"));
        map.put("profile.userlevel", getProperty("profileUserlevel"));
        map.put("profile.vendor", getProperty("profileVendor"));
        
        //String outputDir=System.getProperty("project.build.outputDirectory ");        
        return CalabashHelper.createSource(getLog(), source, pathToPipelineFile, map);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy