Image copy and transform checks added for html and pdf cases.

This commit is contained in:
Salman Qureshi
2012-09-15 03:57:11 +05:00
parent 336ff4800f
commit 042372089c
6 changed files with 468 additions and 308 deletions

View File

@@ -476,11 +476,11 @@ public abstract class WebHelpMojo extends AbstractWebhelpMojo {
map.put("security", this.security);
map.put("canonicalUrlBase", this.canonicalUrlBase);
map.put("replacementsFile", this.replacementsFile);
//This is where the images will be copied in the target. This is a POM configuration.
map.put("imageCopyDir", this.imageCopyDir);
map.put("failOnValidationError", this.failOnValidationError);
map.put("project.build.directory", this.projectBuildDirectory);
map.put("inputSrcFile", inputFilename);
map.put("outputType", "html");
// Profiling attrs:
map.put("profileOs", this.profileOs);
@@ -521,13 +521,22 @@ public abstract class WebHelpMojo extends AbstractWebhelpMojo {
//getLog().info("~~~~~~~~inputFilename file has incompatible format: "+inputFilename);
}
}
//targetExtQueryFile can tell us where the html will be built. Comparing this with the imageCopyDir path
//we can figure out the relative path of the images to the html output. So passing the path to the content dir to the pipeline.
String targetExtQueryFile = (String) map.get("targetExtQueryFile");
int pos = targetExtQueryFile.lastIndexOf(File.separator);
targetExtQueryFile = targetExtQueryFile.substring(0, pos);
map.put("targetHtmlContentDir", baseDir+File.separator+targetExtQueryFile);
//makePdf is a POM configuration for generate-webhelp goal to control the execution of
//automatic building of pdf output
if(makePdf!=null && makePdf.equalsIgnoreCase("true")) {
getLog().info("\n************************************* START: Automatically generating PDF for WEBHELP *************************************");
//Target directory for Webhelp points to ${basepath}/target/docbkx/webhelp. So get parent.
File baseDir = getTargetDirectory().getParentFile();
//The point FO/PDF file output to be generated at ${basepath}/target/docbkx/pdf.
//The point FO/PDF file output to be generated at ${basepath}/target/docbkx/autopdf.
File targetDir = new File(baseDir.getAbsolutePath()+"/autopdf");
//Create a new instance of PDFBuilder class and set config variables.
PDFBuilder pdfBuilder = new PDFBuilder();
@@ -539,7 +548,16 @@ public abstract class WebHelpMojo extends AbstractWebhelpMojo {
pdfBuilder.setIncludes(getIncludes());
pdfBuilder.setEntities(getEntities());
pdfBuilder.setSourceFilePath(getSourceDirectory()+"/os-compute-devguide.xml");
String srcFilename = this.projectBuildDirectory+"/docbkx/"+sourceFile.getName();
File tempHandle = new File(srcFilename);
if(tempHandle.exists()) {
System.out.println("***********************"+ srcFilename);
pdfBuilder.setSourceFilePath(srcFilename);
} else {
System.out.println("***********************"+ getSourceDirectory()+File.separator+inputFilename);
pdfBuilder.setSourceFilePath(getSourceDirectory()+File.separator+inputFilename);
}
pdfBuilder.setProjectBuildDirectory(baseDir.getAbsolutePath());
//setup fonts and images
pdfBuilder.preProcess();
@@ -566,7 +584,11 @@ public abstract class WebHelpMojo extends AbstractWebhelpMojo {
getLog().info("************************************* END: Automatically generating PDF for WEBHELP *************************************\n");
}
map.put("webhelp", "true");
//this parameter will be used the copy and transform image step to decide whether to just check the existence of an image (for pdf)
//or to check existence, transform and copy image as well (for html)
map.put("outputType", "html");
return CalabashHelper.createSource(source, pathToPipelineFile, map);

View File

@@ -25,6 +25,7 @@ import com.xmlcalabash.util.ProcessMatchingNodes;
public class CopyAndTransformXProcStep extends DefaultStep {
private static final QName _target = new QName("target");
private static final QName _targetHtmlContentDir = new QName("targetHtmlContentDir");
private static final QName _inputFileName = new QName("inputFileName");
private static final QName _outputType = new QName("outputType");
private static final QName _fail_on_error = new QName("fail-on-error");
@@ -68,7 +69,7 @@ public class CopyAndTransformXProcStep extends DefaultStep {
super.run();
System.out.println("Entering CopyAndTransformXProcStep!!! ");
XdmNode updatedDoc = makeReplacements (source.read());
XdmNode updatedDoc = processInlineImages (source.read());
result.write(updatedDoc);
System.out.println("Leaving CopyAndTransformXProcStep!!! ");
@@ -81,6 +82,14 @@ public class CopyAndTransformXProcStep extends DefaultStep {
return uri;
}
private URI getTargetHtmlContentDirectoryURI() {
RuntimeValue target = getOption(_targetHtmlContentDir);
URI uri = target.getBaseURI().resolve(target.getString());
File ttt = new File(uri);
System.out.println(ttt.getAbsolutePath());
return uri;
}
private String getInputDocbookName() {
return getOption(_inputFileName, "Unknown");
@@ -91,26 +100,22 @@ public class CopyAndTransformXProcStep extends DefaultStep {
}
private XdmNode makeReplacements(XdmNode doc) {
CopyTransformImage xpathRepl = new CopyTransformImage("//*:imagedata/@fileref",getTargetDirectoryURI(), getInputDocbookName(), getOutputType(), step.getNode());
//CopyTransformImage xpathRepl = new CopyTransformImage("//*:imagedata/@fileref[not(. = ../following-sibling::imagedata/@fileref)]");
private XdmNode processInlineImages(XdmNode doc) {
CopyTransformImage xpathRepl =
new CopyTransformImage( "//*:imagedata/@fileref",
getTargetDirectoryURI(),
getTargetHtmlContentDirectoryURI(),
getInputDocbookName(),
getOutputType(),
step.getNode());
matcher = new ProcessMatch(runtime, xpathRepl);
xpathRepl.setMatcher(matcher);
matcher.match(doc, new RuntimeValue(xpathRepl.getXPath()));
doc = matcher.getResult();
/*
System.out.println("\n\n\n****************************************************************");
System.out.println(doc.toString());
System.out.println("****************************************************************\n\n\n");
doc.toString().replaceAll(Pattern.quote("file:///Users/somethingthatistotallywrong.svg"), "file:///Users/salmanqureshi/Projects/Rackspace/Dev/compute-api-final/openstack-compute-api-2/target/docbkx/webhelp/api/openstack/2/figures/Arrow_east.svg");
*/
return doc;
}
}

View File

@@ -1,22 +1,30 @@
package com.rackspace.cloud.api.docs.calabash.extensions;
import com.xmlcalabash.core.XProcException;
import com.xmlcalabash.model.RuntimeValue;
import com.xmlcalabash.util.ProcessMatch;
import com.xmlcalabash.util.ProcessMatchingNodes;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XdmNode;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.commons.io.FilenameUtils;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugin.logging.SystemStreamLog;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashSet;
import java.util.Set;
import com.xmlcalabash.core.XProcException;
import com.xmlcalabash.util.ProcessMatch;
import com.xmlcalabash.util.ProcessMatchingNodes;
/**
* Created with IntelliJ IDEA.
@@ -27,265 +35,287 @@ import java.util.Set;
*/
public class CopyTransformImage implements ProcessMatchingNodes {
private String xpath;
private Set<Replacement> imageSet = new HashSet<Replacement>();
private ProcessMatch matcher;
private String xpath;
private Map<String, String> imageMap = new HashMap<String, String>();
private ProcessMatch matcher;
private URI targetDirectoryUri;
private String inputDocbookName;
private String outputType;
private XdmNode stepNode;
private static final int bufferSize = 8192;
private URI targetDirectoryUri;
private URI targetHtmlContentDirectoryUri;
private String inputDocbookName;
private String outputType;
private XdmNode stepNode;
private static final int bufferSize = 8192;
private Log log = null;
private Log log = null;
public Log getLog() {
if (log == null) {
log = new SystemStreamLog();
}
return log;
}
public Log getLog() {
if (log == null) {
log = new SystemStreamLog();
}
return log;
}
public CopyTransformImage(String _xpath, URI _targetDirectory, String _inputDocbookName, String _outputType, XdmNode _step) {
this.xpath = _xpath;
this.targetDirectoryUri = _targetDirectory;
this.inputDocbookName = _inputDocbookName;
this.outputType = _outputType;
this.stepNode = _step;
}
public CopyTransformImage(String _xpath, URI _targetDirectory, URI _targetHtmlContentDirectoryUri, String _inputDocbookName, String _outputType, XdmNode _step) {
this.xpath = _xpath;
this.targetDirectoryUri = _targetDirectory;
this.targetHtmlContentDirectoryUri = _targetHtmlContentDirectoryUri;
this.inputDocbookName = _inputDocbookName;
this.outputType = _outputType;
this.stepNode = _step;
}
public String getXPath() {
return xpath;
}
public String getXPath() {
return xpath;
}
public Set<Replacement> getImageSet(){
return imageSet;
}
public void setMatcher (ProcessMatch matcher) {
this.matcher = matcher;
}
public void setMatcher (ProcessMatch matcher) {
this.matcher = matcher;
}
private File getHandleToImageFile(URI sourceImageUri) {
File file = null;
file = new File(sourceImageUri.getPath());
if (!file.exists()) {
getLog().error("DocBook File: '" + inputDocbookName + "' - File: '" + sourceImageUri.getPath() + "' - Problem: File does not exist!");
//throw new XProcException(stepNode, "Cannot copy: file does not exist: " + file.getAbsolutePath());
}
private File getSourceImageFile(URI sourceImageUri) {
File file = null;
if (file.isDirectory()) {
getLog().error("DocBook File: '" + inputDocbookName + "' - File: '" + sourceImageUri.getPath() + "' - Problem: File is a directory!");
//throw new XProcException(stepNode, "Cannot copy: file is a directory: " + file.getAbsolutePath());
}
if (!"file".equals(sourceImageUri.getScheme())) {
getLog().error("DocBook File: '" + inputDocbookName + "' - File: '" + sourceImageUri.getPath() + "' - Problem: Only 'file' scheme URIs are supported by this step!");
throw new XProcException(stepNode, "Only file: scheme URIs are supported by the copy step.");
} else {
String executionPath = System.getProperty("user.dir") + File.separator;
file = new File(executionPath + sourceImageUri.getPath());
}
return file;
}
return file;
}
private File performFileCopyAndTransformation(URI uri, String inputFileName, File file) {
private void checkIfFileExists(URI uri, String inputFileName, File file) {
if (!file.exists()) {
getLog().error("DocBook File: '" + inputFileName + "' - File: '" + uri.getPath() + "' - Problem: File does not exist!");
throw new XProcException(stepNode, "Cannot copy: file does not exist: " + file.getAbsolutePath());
}
File target;
if (file.isDirectory()) {
getLog().error("DocBook File: '" + inputFileName + "' - File: '" + uri.getPath() + "' - Problem: File is a directory!");
throw new XProcException(stepNode, "Cannot copy: file is a directory: " + file.getAbsolutePath());
}
}
target = new File(uri.getPath());
if(!target.exists()) {
if (target.mkdir() || target.mkdirs()) {
//do nothing
}
}
private void performFileCopy(URI uri, String inputFileName, File file) {
if (target.isDirectory()) {
target = new File(target, file.getName());
if (target.isDirectory()) {
getLog().error("DocBook File: '" + inputFileName + "' - File: '" + target.getPath() + "' - Problem: File is a directory!");
throw new XProcException("Cannot copy: target file is a directory: " + target.getAbsolutePath());
}
}
getLog().info("#################################### Enter performFileCopy: " + inputFileName);
try {
FileInputStream src = new FileInputStream(file);
FileOutputStream dst = new FileOutputStream(target);
byte[] buffer = new byte[bufferSize];
int read = src.read(buffer, 0, bufferSize);
while (read >= 0) {
dst.write(buffer, 0, read);
read = src.read(buffer, 0, bufferSize);
}
src.close();
dst.close();
//transform SVG file
String name = file.getName();
int pos = name.lastIndexOf('.');
String ext = name.substring(pos + 1);
File target;
if (ext.equalsIgnoreCase("svg")) {
TransformSVGToPNG t = new TransformSVGToPNG();
String convertedFileUri = t.transform(target.getParent() + File.separator, name);
if (convertedFileUri==null || convertedFileUri.isEmpty()) {
getLog().error("DocBook File: '" + inputFileName + "' - File: '" + uri.getPath() + "' - Problem: Could not transform SVG to PNG!");
//getLog().error("Could not transform SVG file to PNG:" + name);
}
}
} catch (FileNotFoundException fnfe) {
throw new XProcException(fnfe);
} catch (IOException ioe) {
throw new XProcException(ioe);
}
if (!"file".equals(uri.getScheme())) {
getLog().error("DocBook File: '" + inputFileName + "' - File: '" + uri.getPath() + "' - Problem: Only 'file' scheme URIs are supported by this step!");
throw new XProcException("Only file: scheme URIs are supported by the copy step.");
} else {
target = new File(uri.getPath());
if (target.mkdir()) {
}
if (target.mkdirs()) {
}
}
return target;
}
if (target.isDirectory()) {
target = new File(target, file.getName());
if (target.isDirectory()) {
getLog().error("DocBook File: '" + inputFileName + "' - File: '" + uri.getPath() + "' - Problem: File is a directory!");
throw new XProcException("Cannot copy: target is a directory: " + target.getAbsolutePath());
}
}
private String processSelectedImage(XdmNode node) {
String value = node.getStringValue();
if(imageMap.containsKey(value)) {
//System.out.println("\n\n*********** already processed **************** "+imageMap.get(value));
return imageMap.get(value);
}
try {
FileInputStream src = new FileInputStream(file);
FileOutputStream dst = new FileOutputStream(target);
byte[] buffer = new byte[bufferSize];
int read = src.read(buffer, 0, bufferSize);
while (read >= 0) {
dst.write(buffer, 0, read);
read = src.read(buffer, 0, bufferSize);
}
src.close();
dst.close();
//transform SVG file
String name = file.getName();
int pos = name.lastIndexOf('.');
String ext = name.substring(pos + 1);
boolean isSVG = false;
if(value.contains(".svg") || value.contains(".SVG")) {
isSVG = true;
}
getLog().info("#################################### Enter svg transformation for image: " + inputFileName);
//System.out.println("\n\n*********** processing **************** "+value);
//if the file hasn't been processed before then ....
URI sourceImageUri = null;
try {
if(isSVG) {
String executionPath = System.getProperty("user.dir") + File.separator;
sourceImageUri = new URI(executionPath+"src/"+value);
} else {
String filePath = FilenameUtils.normalize("file://"+targetHtmlContentDirectoryUri.getPath() + File.separator + value);
sourceImageUri = new URI(filePath);
}
} catch (URISyntaxException e) {
throw new XProcException(stepNode, "Unable to get handle to image file",e);
}
if(sourceImageUri != null) {
try {
//TODO: Need to handle Case Sensitive file name checking.
//TODO: NTH: Do not print error message while getting handle. For non-SVG images we are checking first in the target and then in the source directory.
//The error message should be printed after we have made sure that it is not present in both directories.
File sourceImageFile = getHandleToImageFile(sourceImageUri);
if (ext.equalsIgnoreCase("svg")) {
getLog().info("#################################### Start Enter svg transformation for image: " + inputFileName);
if(outputType.equals("pdf")) {
//no further processing required. Already checked if the image exists or not in the above get Image call.
//System.out.println("*********** found **************** "+sourceImageFile.getAbsolutePath());
imageMap.put(value, sourceImageFile.getAbsolutePath());
}
else if(outputType.equals("html")) {
//if the output type is html then we need to decide steps based on the image extension
//if the image is an SVG then transform and save a png in the html target directory
//if the image is a PNG then make a huge assumption that an SVG was specified in the Docbook before the png
//and we need to check in the target directory that it is present.
if(sourceImageFile == null && !isSVG) {
TransformSVGToPNG t = new TransformSVGToPNG();
boolean check = t.transform(target.getParent() + File.separator, name);
if (!check) {
getLog().error("DocBook File: '" + inputFileName + "' - File: '" + uri.getPath() + "' - Problem: Could not transform SVG to PNG!");
//getLog().error("Could not transform SVG file to PNG:" + name);
}
getLog().info("#################################### End Enter svg transformation for image: " + inputFileName);
}
//Send another call to the getHandleToImageFile but this time check relative to the html content folder.
try {
String executionPath = System.getProperty("user.dir") + File.separator;
sourceImageUri = new URI(executionPath+"src/"+value);
} catch (URISyntaxException e) {
throw new XProcException(stepNode, "Unable to get handle to image file",e);
}
sourceImageFile = getHandleToImageFile(sourceImageUri);
if(sourceImageFile != null) {
} catch (FileNotFoundException fnfe) {
throw new XProcException(fnfe);
} catch (IOException ioe) {
throw new XProcException(ioe);
}
File copiedFile = performFileCopyAndTransformation(targetDirectoryUri, inputDocbookName, sourceImageFile);
String correctRelativePathToImage = RelativePath.getRelativePath(new File(targetHtmlContentDirectoryUri), copiedFile);
imageMap.put(value, correctRelativePathToImage);
} else {
//File not found in source and target folders.
}
} else if(sourceImageFile != null && !isSVG) {
String correctRelativePathToImage = RelativePath.getRelativePath( new File(targetHtmlContentDirectoryUri), sourceImageFile);
imageMap.put(value, correctRelativePathToImage);
} else if(sourceImageFile != null && isSVG) {
//There really isn't any need to copy the SVG for html output but it is being done right now. We only care about transforming it to a PNG.
File copiedFile = performFileCopyAndTransformation(targetDirectoryUri, inputDocbookName, sourceImageFile);
String correctRelativePathToImage = RelativePath.getRelativePath( new File(targetHtmlContentDirectoryUri), copiedFile);
imageMap.put(value, correctRelativePathToImage);
}
}
} catch (XProcException x) {
//getLog().error(x.getMessage());
//do nothing
}
}
}
return imageMap.get(value);
}
private String computeReplacement(XdmNode node) {
String value = node.getStringValue();
Replacement repl = new Replacement(value, "");
if(imageSet.add(repl)) {
URI sourceImageUri = null;
try {
sourceImageUri = new URI("file://./src/"+value);
} catch (URISyntaxException e) {
throw new XProcException(stepNode, "Unable to get handle to image file",e);
}
if(sourceImageUri != null) {
File sourceImageFile = getSourceImageFile(sourceImageUri);
if(outputType.equals("pdf")) {
//check if image exists.
try {
checkIfFileExists(sourceImageUri, inputDocbookName, sourceImageFile);
} catch (XProcException x) {
//getLog().error(x.getMessage());
//do nothing
}
} else if(outputType.equals("html")) {
//check if image exists.
//transform image if it is an SVG
//update image path for PNG images only
@Override
public boolean processStartDocument(XdmNode node) throws SaxonApiException {
return true;//process children
}
try {
checkIfFileExists(sourceImageUri, inputDocbookName, sourceImageFile);
performFileCopy(targetDirectoryUri, inputDocbookName, sourceImageFile);
} catch (XProcException x) {
//getLog().error(x.getMessage());
//do nothing
}
}
}
//value = "file:///Users/salmanqureshi/Projects/Rackspace/Dev/compute-api-final/openstack-compute-api-2/target/docbkx/webhelp/api/openstack/2/figures/Arrow_east.svg";
value = "file:///Users/somethingthatistotallywrong.svg";
}
@Override
public void processEndDocument(XdmNode node) throws SaxonApiException {
//do nothing
}
return value;
}
@Override
public boolean processStartElement(XdmNode node) throws SaxonApiException {
return true;//process children
}
@Override
public boolean processStartDocument(XdmNode node) throws SaxonApiException {
return true;//process children
}
@Override
public void processAttribute(XdmNode node) throws SaxonApiException {
String newValue = processSelectedImage(node);
matcher.addAttribute(node, newValue);
}
@Override
public void processEndDocument(XdmNode node) throws SaxonApiException {
//do nothing
}
@Override
public void processEndElement(XdmNode node) throws SaxonApiException { }
@Override
public boolean processStartElement(XdmNode node) throws SaxonApiException {
return true;//process children
}
@Override
public void processText(XdmNode node) throws SaxonApiException {
String newValue = processSelectedImage(node);
matcher.addText(newValue);
}
@Override
public void processAttribute(XdmNode node) throws SaxonApiException {
String newValue = computeReplacement(node);
matcher.addAttribute(node, newValue);
}
@Override
public void processComment(XdmNode node) throws SaxonApiException {
String newValue = processSelectedImage(node);
matcher.addText(newValue);}
@Override
public void processEndElement(XdmNode node) throws SaxonApiException { }
@Override
public void processPI(XdmNode node) throws SaxonApiException {
String newValue = processSelectedImage(node);
matcher.addText(newValue);
}
@Override
public void processText(XdmNode node) throws SaxonApiException {
String newValue = computeReplacement(node);
matcher.addText(newValue);
}
private class TransformSVGToPNG {
@Override
public void processComment(XdmNode node) throws SaxonApiException {
String newValue = computeReplacement(node);
matcher.addText(newValue);}
String substringBeforeLast(String str, String separator) {
if (isEmpty(str) || isEmpty(separator)) {
return str;
}
int pos = str.lastIndexOf(separator);
if (pos == -1) {
return str;
}
return str.substring(0, pos);
}
@Override
public void processPI(XdmNode node) throws SaxonApiException {
String newValue = computeReplacement(node);
matcher.addText(newValue);
}
private class TransformSVGToPNG {
String substringBeforeLast(String str, String separator) {
if (isEmpty(str) || isEmpty(separator)) {
return str;
}
int pos = str.lastIndexOf(separator);
if (pos == -1) {
return str;
}
return str.substring(0, pos);
}
boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
boolean transform(String directory, String fileName) {
//String fileName = "/Users/salmanqureshi/Projects/Rackspace/Dev/batik-1.7/examples/batikYin.svg";
PNGTranscoder t = new PNGTranscoder();
String transform(String directory, String fileName) {
PNGTranscoder t = new PNGTranscoder();
// Set the transcoding hints.
//t.addTranscodingHint(PNGTranscoder., value)
try {
String svgURI = new File(directory, fileName).toURI().toString();
TranscoderInput input = new TranscoderInput(svgURI);
// Set the transcoding hints.
//t.addTranscodingHint(PNGTranscoder., value)
try {
String svgURI = new File(directory, fileName).toURI().toString();
TranscoderInput input = new TranscoderInput(svgURI);
// Create the transcoder output.
String pngFileName = directory + substringBeforeLast(fileName, ".svg") + ".png";
// Create the transcoder output.
String pngFileName = directory + substringBeforeLast(fileName, ".svg") + ".png";
File pngFile = new File(pngFileName);
pngFile.createNewFile();
OutputStream ostream = new FileOutputStream(pngFile);
TranscoderOutput output = new TranscoderOutput(ostream);
OutputStream ostream = new FileOutputStream(pngFileName);
TranscoderOutput output = new TranscoderOutput(ostream);
// Save the image.
t.transcode(input, output);
// Flush and close the stream.
ostream.flush();
ostream.close();
// Save the image.
t.transcode(input, output);
return pngFileName;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// Flush and close the stream.
ostream.flush();
ostream.close();
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
}
}

View File

@@ -0,0 +1,109 @@
package com.rackspace.cloud.api.docs.calabash.extensions;
import java.io.*;
import java.util.*;
/**
* this class provides functions used to generate a relative path
* from two absolute paths
* @author David M. Howard
*/
public class RelativePath {
/**
* break a path down into individual elements and add to a list.
* example : if a path is /a/b/c/d.txt, the breakdown will be [d.txt,c,b,a]
* @param f input file
* @return a List collection with the individual elements of the path in
reverse order
*/
private static List getPathList(File f) {
List l = new ArrayList();
File r;
try {
r = f.getCanonicalFile();
while(r != null) {
l.add(r.getName());
r = r.getParentFile();
}
}
catch (IOException e) {
e.printStackTrace();
l = null;
}
return l;
}
/**
* figure out a string representing the relative path of
* 'f' with respect to 'r'
* @param r home path
* @param f path of file
*/
private static String matchPathLists(List r,List f) {
int i;
int j;
String s;
// start at the beginning of the lists
// iterate while both lists are equal
s = "";
i = r.size()-1;
j = f.size()-1;
// first eliminate common root
while((i >= 0)&&(j >= 0)&&(r.get(i).equals(f.get(j)))) {
i--;
j--;
}
// for each remaining level in the home path, add a ..
for(;i>=0;i--) {
s += ".." + File.separator;
}
// for each level in the file path, add the path
for(;j>=1;j--) {
s += f.get(j) + File.separator;
}
// file name
s += f.get(j);
return s;
}
/**
* get relative path of File 'f' with respect to 'home' directory
* example : home = /a/b/c
* f = /a/d/e/x.txt
* s = getRelativePath(home,f) = ../../d/e/x.txt
* @param home base path, should be a directory, not a file, or it doesn't
make sense
* @param f file to generate path for
* @return path from home to f as a string
*/
public static String getRelativePath(File home,File f){
File r;
List homelist;
List filelist;
String s;
homelist = getPathList(home);
filelist = getPathList(f);
s = matchPathLists(homelist,filelist);
return s;
}
/**
* test the function
*/
public static void main(String args[]) {
if (args.length != 2) {
System.out.println("RelativePath <home> <file>");
return;
}
System.out.println("home = " + args[0]);
System.out.println("file = " + args[1]);
System.out.println("path = " + getRelativePath(new File(args[0]),new
File(args[1])));
}
}

View File

@@ -260,9 +260,6 @@
class-name="com.rackspace.cloud.api.docs.calabash.extensions.ReplaceTextXProcStep" />
<implementation type="cx:copy-transform"
class-name="com.rackspace.cloud.api.docs.calabash.extensions.CopyAndTransform" />
<implementation type="cx:copy-transform-xproc"
class-name="com.rackspace.cloud.api.docs.calabash.extensions.CopyAndTransformXProcStep" />
</xproc-config>

View File

@@ -672,54 +672,6 @@
</p:declare-step>
<p:declare-step
xmlns:l="http://xproc.org/library"
xmlns:c="http://www.w3.org/ns/xproc-step"
xml:id="copy-and-transform-images"
type="l:copy-and-transform-images"
name="copy-and-transform-images-step">
<p:input port="source" primary="true" sequence="true"/>
<p:output port="result" primary="true"/>
<p:input port="parameters" kind="parameter"/>
<ut:parameters name="params"/>
<p:sink/>
<p:identity>
<p:input port="source">
<p:pipe step="copy-and-transform-images-step" port="source"/>
</p:input>
</p:identity>
<p:group name="loop-grp">
<p:output port="result" primary="true" sequence="true">
<p:pipe step="copy-and-transform-images-step" port="source"/>
</p:output>
<p:output port="secondary" primary="false" sequence="true">
<p:pipe step="loop" port="result"/>
</p:output>
<p:variable name="paramOutputType" select="//c:param[@name = 'outputType']/@value">
<p:pipe step="params" port="parameters"/>
</p:variable>
<p:variable name="project.build.directory" select="//c:param[@name = 'project.build.directory']/@value">
<p:pipe step="params" port="parameters"/>
</p:variable>
<p:variable name="inputSrcFile" select="//c:param[@name = 'inputSrcFile']/@value">
<p:pipe step="params" port="parameters"/>
</p:variable>
<p:variable name="image.copy.dir" select="//c:param[@name = 'imageCopyDir']/@value">
<p:pipe step="params" port="parameters"/>
</p:variable>
<cx:copy-transform-xproc name="loop">
<p:with-option name="target" select="concat('file://',$project.build.directory,'/',$image.copy.dir)"/>
<p:with-option name="inputFileName" select="concat($inputSrcFile,'')"/>
<p:with-option name="outputType" select="concat($paramOutputType,'')"/>
</cx:copy-transform-xproc>
</p:group>
</p:declare-step>
<p:declare-step
xmlns:l="http://xproc.org/library"
xmlns:c="http://www.w3.org/ns/xproc-step"
@@ -832,24 +784,69 @@
</p:declare-step>
<!-- Search and replace calabash extension -->
<p:declare-step type="cx:copy-transform"
xml:id="copy-transform">
<p:output port="result" primary="false"/>
<p:option name="href" required="true" cx:type="xsd:anyURI"/>
<p:option name="target" required="true" cx:type="xsd:anyURI"/>
<p:option name="inputFileName" cx:type="xsd:string"/>
<p:option name="outputType" cx:type="xsd:string"/>
<p:option name="fail-on-error" select="'true'" cx:type="xsd:boolean"/>
</p:declare-step>
<p:declare-step
xmlns:l="http://xproc.org/library"
xmlns:c="http://www.w3.org/ns/xproc-step"
xml:id="copy-and-transform-images"
type="l:copy-and-transform-images"
name="copy-and-transform-images-step">
<p:input port="source" primary="true" sequence="true"/>
<p:output port="result" primary="true"/>
<p:input port="parameters" kind="parameter"/>
<ut:parameters name="params"/>
<p:sink/>
<!-- Search and replace calabash extension -->
<p:identity>
<p:input port="source">
<p:pipe step="copy-and-transform-images-step" port="source"/>
</p:input>
</p:identity>
<p:group name="loop-grp">
<p:output port="result" primary="true" sequence="true">
<p:pipe step="copy-and-transform-images-step" port="source"/>
</p:output>
<p:output port="secondary" primary="false" sequence="true">
<p:pipe step="loop" port="result"/>
</p:output>
<!-- output type can be pdf of html -->
<p:variable name="output.type" select="//c:param[@name = 'outputType']/@value">
<p:pipe step="params" port="parameters"/>
</p:variable>
<p:variable name="project.build.directory" select="//c:param[@name = 'project.build.directory']/@value">
<p:pipe step="params" port="parameters"/>
</p:variable>
<p:variable name="input.docbook.file" select="//c:param[@name = 'inputSrcFile']/@value">
<p:pipe step="params" port="parameters"/>
</p:variable>
<p:variable name="image.copy.dir" select="//c:param[@name = 'imageCopyDir']/@value">
<p:pipe step="params" port="parameters"/>
</p:variable>
<!-- this param is passed by WebhelpMojo and contains the path where final html output will be written.
Comparing this path with the image copy dir param, we can find the relative path of the images to html -->
<p:variable name="target.html.content.dir" select="//c:param[@name = 'targetHtmlContentDir']/@value">
<p:pipe step="params" port="parameters"/>
</p:variable>
<cx:copy-transform name="loop">
<p:with-option name="target" select="concat('file://',$project.build.directory,'/',$image.copy.dir)"/>
<p:with-option name="targetHtmlContentDir" select="concat('file://',$target.html.content.dir)"/>
<p:with-option name="inputFileName" select="concat($input.docbook.file,'')"/>
<p:with-option name="outputType" select="concat($output.type,'')"/>
</cx:copy-transform>
</p:group>
</p:declare-step>
<!-- copy and transform images calabash extension -->
<p:declare-step
type="cx:copy-transform-xproc"
xml:id="copy-transform-xproc">
type="cx:copy-transform"
xml:id="copy-transform">
<p:input port="source" primary="true" sequence="true"/>
<p:output port="result" primary="false"/>
<p:option name="target" required="true" cx:type="xsd:anyURI"/>
<p:option name="targetHtmlContentDir" required="false" cx:type="xsd:anyURI"/>
<p:option name="inputFileName" cx:type="xsd:string"/>
<p:option name="outputType" cx:type="xsd:string"/>
<p:option name="fail-on-error" select="'true'" cx:type="xsd:boolean"/>