/** * */ package net.sourceforge.dita4publishers.word2dita; import java.io.File; import java.net.URI; import java.util.Date; import net.sourceforge.dita4publishers.api.ditabos.DitaBoundedObjectSet; import net.sourceforge.dita4publishers.impl.bos.BosConstructionOptions; import net.sourceforge.dita4publishers.impl.ditabos.DitaBosHelper; import net.sourceforge.dita4publishers.tools.common.MapBosProcessorBase; import net.sourceforge.dita4publishers.tools.common.MapBosProcessorOptions; import net.sourceforge.dita4publishers.util.DomUtil; import net.sourceforge.dita4publishers.util.TimingUtils; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; /** * */ public class Word2DitaValidator extends MapBosProcessorBase { public static Log log = LogFactory.getLog(Word2DitaValidator.class); /** * Path and filename of the Word document from which the map was generated. */ public static final String WORD_DOC_OPTION_ONE_CHAR = "d"; /** * @param cmdline */ public Word2DitaValidator(CommandLine cmdline) { this.commandLine = cmdline; } /** * @param args */ public static void main(String[] args) { Options cmdlineOptions = configureOptions(); CommandLineParser parser = new PosixParser(); CommandLine cmdline = null; try { // parse the command line arguments cmdline = parser.parse(cmdlineOptions, args ); } catch( ParseException exp ) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp(Word2DitaValidator.class.getSimpleName(), cmdlineOptions); System.exit(-1); } if (!cmdline.hasOption(INPUT_OPTION_ONE_CHAR) || !cmdline.hasOption(WORD_DOC_OPTION_ONE_CHAR)) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp(Word2DitaValidator.class.getSimpleName(), cmdlineOptions); System.exit(-1); } Word2DitaValidator app = new Word2DitaValidator(cmdline); try { app.run(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } /** * */ private void run() { String mapFilepath = commandLine.getOptionValue("i"); File mapFile = new File(mapFilepath).getAbsoluteFile(); checkExistsAndCanReadSystemExit(mapFile); Word2DitaValidatorOptions procOptions = new Word2DitaValidatorOptions(); handleCommonBosProcessorOptions(procOptions); String originalWordFilePath = commandLine.getOptionValue(WORD_DOC_OPTION_ONE_CHAR); File originalWordFile = new File(originalWordFilePath); checkExistsAndCanReadSystemExit(originalWordFile); File outputWordFile = null; String outputFilepath = null; if (commandLine.hasOption(OUTPUT_OPTION_ONE_CHAR)) { outputFilepath = commandLine.getOptionValue(OUTPUT_OPTION_ONE_CHAR); outputWordFile = new File(outputFilepath).getAbsoluteFile(); } else { outputWordFile = originalWordFile; } checkCanWriteSystemExit(outputWordFile); procOptions.setOriginalWordFile(originalWordFile); procOptions.setOutputWordFile(outputWordFile); procOptions.setLog(log); BosConstructionOptions bosOptions = setupBosOptions(procOptions); URI rootDocUri = mapFile.toURI(); try { Document rootMap = DomUtil.getDomForUri(rootDocUri, bosOptions); procOptions.setRootDocument(rootMap); } catch (Exception e) { System.err.println("Exception parsing input DITA document: " + e.getClass().getSimpleName() + " - " + e.getMessage()); System.exit(-1); } validateMap(mapFile, procOptions, bosOptions); } /** * @param mapFile * @param procOptions */ public void validateMap(File mapFile, MapBosProcessorOptions procOptions, BosConstructionOptions bosOptions) { Document rootMap = null; try { Date startTime = TimingUtils.getNowTime(); DitaBoundedObjectSet mapBos = DitaBosHelper.calculateMapBos(bosOptions,log, rootMap); if (!procOptions.isQuiet()) System.err.println("Map BOS construction took " + TimingUtils.reportElapsedTime(startTime)); // Do validation and comment writing here. } catch (Exception e) { e.printStackTrace(); } finally { // Do final stuff here. } } /** * @param outputWordFile */ public static void checkCanWriteSystemExit(File file) { try { checkCanWrite(file); } catch(Exception e) { System.err.println(e.getMessage()); System.exit(-1); } } /** * Throws a runtime exception if the file exists but is not writable, can't create the parent dirs, * or the parent dir exists but is not writable. * @param file */ private static void checkCanWrite(File file) { if (file.exists()) { if (!file.canWrite()) { throw new RuntimeException("File " + file.getAbsolutePath() + " exists but cannot be written to."); } } else { File parent = file.getParentFile(); if (!parent.exists()) { if (!parent.mkdirs()) { throw new RuntimeException("Failed to created parent directories for file " + file.getAbsolutePath() + "."); } } if (parent.exists()) { if (!parent.canWrite()) { throw new RuntimeException("Cannot write to directory that will contain file " + file.getAbsolutePath() + "."); } } else { // Should never get here but you never know. throw new RuntimeException("Failed to created parent directories for file " + file.getAbsolutePath() + "."); } } } /** * @return */ private static Options configureOptions() { Options options = configureOptionsBase(); options.addOption(WORD_DOC_OPTION_ONE_CHAR, "docx", true, "(Original Word doc) The Word document from which the DITA map was generated."); Option opt = options.getOption(WORD_DOC_OPTION_ONE_CHAR); opt.setRequired(true); options.getOption(INPUT_OPTION_ONE_CHAR).setDescription("(Input map or topic) Root map or single topic to be validated."); options.getOption(OUTPUT_OPTION_ONE_CHAR).setDescription("(Annotated Word doc) Word document that will contain validation messages as comments." + " If not set, original Word doc will be updated with the messages."); options.getOption(OUTPUT_OPTION_ONE_CHAR).setRequired(false); // Will be same as input Word doc if not specified. return options; } }