Java tutorial
/******************************************************************************* * Copyright (C) 2011 Atlas of Living Australia * All Rights Reserved. * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. ******************************************************************************/ package au.org.ala.delta.io; import au.org.ala.delta.DeltaContext.OutputFormat; import au.org.ala.delta.directives.validation.DirectiveError; import au.org.ala.delta.directives.validation.DirectiveException; import au.org.ala.delta.model.Attribute; import au.org.ala.delta.model.Item; import au.org.ala.delta.model.MutableDeltaDataSet; import au.org.ala.delta.model.format.AttributeFormatter; import au.org.ala.delta.model.format.Formatter.AngleBracketHandlingMode; import au.org.ala.delta.model.format.Formatter.CommentStrippingMode; import au.org.ala.delta.rtf.RTFUtils; import au.org.ala.delta.translation.PrintFile; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import java.io.File; import java.io.PrintStream; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** * Manages CONFOR output files. */ public class OutputFileSelector extends OutputFileManager { enum ConforOutputFileType { PRINT_FILE("PRINT"), INDEX_FILE("INDEX"), KEY_OUTPUT_FILE("KEY"), INTKEY_OUTPUT_FILE( "INTKEY"), DIST_OUTPUT_FILE("DIST"); String _name; private ConforOutputFileType(String name) { _name = name; } public String getName() { return _name; } } public static final int DEFAULT_PRINT_WIDTH = 80; public static final int DEFAULT_PAGE_LENGTH = 0; private int _characterForOutputFiles = 0; private Map<String, String> _itemOutputFiles = new HashMap<String, String>(); private Set<Integer> _newFileItems = new HashSet<Integer>(); private MutableDeltaDataSet _dataSet; private String _subjectForOutputFiles; private String _imageDirectory; private PrintStream _printStream; private PrintFile _printFile; private String _printFileName; private int _outputFileIndex; private PrintFile _indexFile; /** output when a new print file is created */ private String _printFileHeaderText; /** Output at the end of the print file */ private String _printFileFooterText; /** Number of characters on a line of text written to the print file */ private int _printWidth; /** * The number of lines output on each page of the print file. A value of 0 * indicates that no paging should be done for the print file. */ private int _printPageLength; private List<OutputFile> _archivedFiles; private Map<ConforOutputFileType, OutputFile> _currentFiles; public OutputFileSelector(MutableDeltaDataSet dataSet) { init(dataSet); } public OutputFileSelector(MutableDeltaDataSet dataSet, PrintStream out, PrintStream err) { super(out, err); init(dataSet); } private void init(MutableDeltaDataSet dataSet) { _dataSet = dataSet; _printWidth = DEFAULT_PRINT_WIDTH; _outputWidth = DEFAULT_PRINT_WIDTH; _printPageLength = DEFAULT_PAGE_LENGTH; _outputFileIndex = 1; _archivedFiles = new ArrayList<OutputFileManager.OutputFile>(); _currentFiles = new HashMap<OutputFileSelector.ConforOutputFileType, OutputFileManager.OutputFile>(); } /** * Returns the filename of the file that the translated output from the * supplied item should be written to. This is used both during natural * language translation to determine the output file and by the intkey * translation to write the file name for the item to the intkey items file. * * @param itemNumber * the item to determine the output file for. * @return the name of the file the translated output for the supplied item * should go to. */ public String getItemOutputFile(int itemNumber) { String outputFile = ""; // This basically says use the current output file if a new one is // not specified for this item. (to mimic CONFOR behaviour). while (itemNumber >= 1 && StringUtils.isEmpty(outputFile)) { if (_characterForOutputFiles == 0) { String description = itemDescriptionFor(itemNumber); outputFile = _itemOutputFiles.get(description); } else { Attribute attribute = _dataSet.getAttribute(itemNumber, _characterForOutputFiles); if (attribute != null) { outputFile = outputFileFromAttribute(attribute); } } itemNumber--; } outputFile = prependOutputDirectory(outputFile); return addExtension(outputFile); } protected String outputFileFromAttribute(Attribute attribute) { String outputFile; AttributeFormatter formatter = new AttributeFormatter(false, true, CommentStrippingMode.RETAIN, AngleBracketHandlingMode.REMOVE, false, null); outputFile = formatter.formatAttribute(attribute); if (outputFile.contains(" ")) { outputFile = outputFile.substring(0, outputFile.indexOf(" ")); } return outputFile; } /** * Determines and adds an appropriate filename extension to an output file * based on the type of translation being performed. If the filename already * includes a '.', no extension will be appended. * * @param outputFile * the output file. * @return the output file with an extension added. */ private String addExtension(String outputFile) { if (StringUtils.isEmpty(outputFile)) { return ""; } StringBuilder output = new StringBuilder(outputFile); if (outputFile.indexOf('.') < 0) { switch (_outputFormat) { case RTF: output.append(".rtf"); break; case HTML: output.append(".htm"); break; default: output.append(".prt"); break; } } return output.toString(); } public void setSubjectForOutputFiles(String subjectForOutputFiles) { _subjectForOutputFiles = subjectForOutputFiles; } public String getSubjectForOutputFiles() { return _subjectForOutputFiles; } public void setItemOutputFile(String itemDescription, String fileName) { _itemOutputFiles.put(RTFUtils.stripFormatting(itemDescription), fileName); } public Iterator<String> itemOutputFileDescriptions() { return _itemOutputFiles.keySet().iterator(); } private String itemDescriptionFor(int itemNumber) { Item item = _dataSet.getItem(itemNumber); String description = RTFUtils.stripFormatting(item.getDescription()); return description; } protected String getFilePath(ConforOutputFileType fileType) throws DirectiveException { OutputFile file = _currentFiles.get(fileType); if (file == null) { throw DirectiveError.asException(DirectiveError.Error.MISSING_OUTPUT_FILE, 0, fileType.getName()); } return makeAbsolute(file.getFileName()); } protected void addAndArchive(ConforOutputFileType fileType, String fileName) { BinaryOutputFile file = new BinaryOutputFile(fileName); if (_currentFiles.containsKey(fileType)) { _archivedFiles.add(_currentFiles.get(fileType)); } _currentFiles.put(fileType, file); } public String getIntkeyOutputFilePath() throws DirectiveException { return getFilePath(ConforOutputFileType.INTKEY_OUTPUT_FILE); } public void setIntkeyOutputFile(String intkeyOut) { addAndArchive(ConforOutputFileType.INTKEY_OUTPUT_FILE, intkeyOut); } public String getKeyOutputFilePath() throws DirectiveException { return getFilePath(ConforOutputFileType.KEY_OUTPUT_FILE); } public void setKeyOutputFile(String keyOut) { addAndArchive(ConforOutputFileType.KEY_OUTPUT_FILE, keyOut); } public void setDistOutputFile(String outputFile) { addAndArchive(ConforOutputFileType.DIST_OUTPUT_FILE, outputFile); } public String getDistOutputFilePath() throws DirectiveException { return getFilePath(ConforOutputFileType.DIST_OUTPUT_FILE); } public void setCharacterForOutputFiles(int character) { _characterForOutputFiles = character; } public void setOutputFormat(OutputFormat outputFormat) { _outputFormat = outputFormat; } public void addNewFileAtItem(int itemNumber) { _newFileItems.add(itemNumber); } public boolean getNewFileAtItem(int itemNumber) { return _newFileItems.contains(itemNumber); } /** * When typesetting marks are being used, some are required to be output * when a new print file is created. The string supplied to this method will * be output to the print file whenever a new file is created. * * @param headerText */ public void setPrintFileHeader(String headerText) { _printFileHeaderText = headerText; if (_printFile != null) { _printFile.setNewFileHeader(headerText); } } /** * When typesetting marks are being used, some are required to be output * when before a file is closed. The string supplied to this method will be * outputn at the end of the print file. * * @param footer * the file footer. */ public void setPrintFileFooter(String footer) { _printFileFooterText = footer; if (_printFile != null) { _printFile.setFileFooter(footer); } } public void setPrintWidth(int printWidth) { _printWidth = printWidth; if (_printFile != null) { _printFile.setPrintWidth(printWidth); } } public void setPrintPageLength(int pageLength) { _printPageLength = pageLength; if (_printFile != null) { _printFile.setPageLength(pageLength); } } public void setPrintFileName(String filename) throws Exception { _printFileName = filename; recreatePrintFile(); } void recreatePrintFile() throws Exception { closeExistingPrintStream(); TextOutputFile printFile = (TextOutputFile) _currentFiles.get(ConforOutputFileType.PRINT_FILE); if (printFile != null) { _archivedFiles.add(printFile); } printFile = new TextOutputFile(_printFileName); _currentFiles.put(ConforOutputFileType.PRINT_FILE, printFile); _printStream = printFile.getPrintStream(); if (StringUtils.isNotBlank(_printFileHeaderText)) { _printStream.println(_printFileHeaderText); } if (_printFile == null) { _printFile = new PrintFile(_printStream, _printWidth, _printPageLength); } else { _printFile.setPrintStream(_printStream); } _printFile.setNewFileHeader(_printFileHeaderText); _printFile.setFileFooter(_printFileFooterText); } public void setPrintStream(PrintStream stream) { _printStream = stream; if (_printFile == null) { _printFile = new PrintFile(stream, _printWidth, _printPageLength); } else { _printFile.setPrintStream(stream); } } public PrintFile getPrintFile() { return _printFile; } /** * Currently used by the IndexWriter if unable to determine a file name for * an Item (e.g. if there is no directives that specifiy item file names). * * @return the nane of the current print file, including the output * directory, if specified. */ public String getPrintFileName() { return prependOutputDirectory(_printFileName); } public boolean createNewFileIfRequired(Item item) { boolean newFile = false; int itemNum = item.getItemNumber(); String fileName = getItemOutputFile(itemNum); if (StringUtils.isEmpty(fileName)) { if (_newFileItems.contains(itemNum)) { fileName = _printFileName + _outputFileIndex; _outputFileIndex++; } } if (StringUtils.isNotEmpty(fileName)) { newFile = true; try { setPrintFileName(fileName); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Unable to update print file!"); } } return newFile; } public void setIndexOutputFile(String fileName) throws Exception { TextOutputFile indexFile = new TextOutputFile(fileName); _indexFile = new PrintFile(indexFile.getPrintStream(), _printWidth, _printPageLength); _currentFiles.put(ConforOutputFileType.INDEX_FILE, indexFile); } public String getIndexOutputFilePath() throws Exception { OutputFile indexFile = _currentFiles.get(ConforOutputFileType.INDEX_FILE); return indexFile != null ? new File(indexFile.getFileName()).getParentFile().getPath() : ""; } public PrintFile getIndexFile() { return _indexFile; } public void setImageDirectory(String directoryName) { _imageDirectory = FilenameUtils.separatorsToSystem(directoryName); } public String getImageDirectory() { if (_imageDirectory == null) { _imageDirectory = ""; } return _imageDirectory; } protected void closeExistingPrintStream() { if (_printStream != null && _printStream != _defaultOut && _printStream != _defaultErr) { if (_printFile != null) { _printFile.closePrintStream(); } else { IOUtils.closeQuietly(_printStream); } } } @Override public void setOutputDirectory(String directory) throws Exception { super.setOutputDirectory(directory); if (_printFileName != null) { recreatePrintFile(); } } @Override public List<File> getOutputFiles() { List<File> files = new ArrayList<File>(super.getOutputFiles()); for (OutputFile file : _archivedFiles) { files.add(file.toFile()); } for (OutputFile file : _currentFiles.values()) { files.add(file.toFile()); } return files; } @Override public void closeAll() { super.closeAll(); if (_printFile != null) { _printFile.close(); } if (_printStream != null && _printStream != System.out && _printStream != System.err) { IOUtils.closeQuietly(_printStream); } if (_indexFile != null) { _indexFile.close(); } } }