diff options
Diffstat (limited to 'src/net/sf/antcontrib/cpptasks/TargetHistoryTable.java')
-rw-r--r-- | src/net/sf/antcontrib/cpptasks/TargetHistoryTable.java | 430 |
1 files changed, 0 insertions, 430 deletions
diff --git a/src/net/sf/antcontrib/cpptasks/TargetHistoryTable.java b/src/net/sf/antcontrib/cpptasks/TargetHistoryTable.java deleted file mode 100644 index bdab94c..0000000 --- a/src/net/sf/antcontrib/cpptasks/TargetHistoryTable.java +++ /dev/null @@ -1,430 +0,0 @@ -/* - * - * Copyright 2002-2004 The Ant-Contrib project - * - * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package net.sf.antcontrib.cpptasks; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import net.sf.antcontrib.cpptasks.compiler.ProcessorConfiguration; - -import org.apache.tools.ant.BuildException; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; -/** - * A history of the compiler and linker settings used to build the files in the - * same directory as the history. - * - * @author Curt Arnold - */ -public final class TargetHistoryTable { - /** - * This class handles populates the TargetHistory hashtable in response to - * SAX parse events - */ - private class TargetHistoryTableHandler extends DefaultHandler { - private final File baseDir; - private String config; - private final Hashtable history; - private String output; - private long outputLastModified; - private final Vector sources = new Vector(); - /** - * Constructor - * - * @param history - * hashtable of TargetHistory keyed by output name - * @param outputFiles - * existing files in output directory - */ - private TargetHistoryTableHandler(Hashtable history, File baseDir) { - this.history = history; - config = null; - output = null; - this.baseDir = baseDir; - } - public void endElement(String namespaceURI, String localName, - String qName) throws SAXException { - // - // if </target> then - // create TargetHistory object and add to hashtable - // if corresponding output file exists and - // has the same timestamp - // - if (qName.equals("target")) { - if (config != null && output != null) { - File existingFile = new File(baseDir, output); - // - // if the corresponding files doesn't exist or has a - // different - // modification time, then discard this record - if (existingFile.exists()) { - // - // would have expected exact time stamps - // but have observed slight differences - // in return value for multiple evaluations of - // lastModified(). Check if times are within - // a second - long existingLastModified = existingFile.lastModified(); - if (!CUtil.isSignificantlyBefore(existingLastModified, outputLastModified) - && !CUtil.isSignificantlyAfter(existingLastModified, outputLastModified)) { - SourceHistory[] sourcesArray = new SourceHistory[sources - .size()]; - sources.copyInto(sourcesArray); - TargetHistory targetHistory = new TargetHistory( - config, output, outputLastModified, - sourcesArray); - history.put(output, targetHistory); - } - } - } - output = null; - sources.setSize(0); - } else { - // - // reset config so targets not within a processor element - // don't pick up a previous processors signature - // - if (qName.equals("processor")) { - config = null; - } - } - } - /** - * startElement handler - */ - public void startElement(String namespaceURI, String localName, - String qName, Attributes atts) throws SAXException { - // - // if sourceElement - // - if (qName.equals("source")) { - String sourceFile = atts.getValue("file"); - long sourceLastModified = Long.parseLong(atts - .getValue("lastModified"), 16); - sources.addElement(new SourceHistory(sourceFile, - sourceLastModified)); - } else { - // - // if <target> element, - // grab file name and lastModified values - // TargetHistory object will be created in endElement - // - if (qName.equals("target")) { - sources.setSize(0); - output = atts.getValue("file"); - outputLastModified = Long.parseLong(atts - .getValue("lastModified"), 16); - } else { - // - // if <processor> element, - // grab signature attribute - // - if (qName.equals("processor")) { - config = atts.getValue("signature"); - } - } - } - } - } - /** Flag indicating whether the cache should be written back to file. */ - private boolean dirty; - /** - * a hashtable of TargetHistory's keyed by output file name - */ - private final Hashtable history = new Hashtable(); - /** The file the cache was loaded from. */ - private/* final */File historyFile; - private/* final */File outputDir; - private String outputDirPath; - /** - * Creates a target history table from history.xml in the output directory, - * if it exists. Otherwise, initializes the history table empty. - * - * @param task - * task used for logging history load errors - * @param outputDir - * output directory for task - */ - public TargetHistoryTable(CCTask task, File outputDir) - throws BuildException { - if (outputDir == null) { - throw new NullPointerException("outputDir"); - } - if (!outputDir.isDirectory()) { - throw new BuildException("Output directory is not a directory"); - } - if (!outputDir.exists()) { - throw new BuildException("Output directory does not exist"); - } - this.outputDir = outputDir; - try { - outputDirPath = outputDir.getCanonicalPath(); - } catch (IOException ex) { - outputDirPath = outputDir.toString(); - } - // - // load any existing history from file - // suppressing any records whose corresponding - // file does not exist, is zero-length or - // last modified dates differ - historyFile = new File(outputDir, "history.xml"); - if (historyFile.exists()) { - SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setValidating(false); - try { - SAXParser parser = factory.newSAXParser(); - parser.parse(historyFile, new TargetHistoryTableHandler( - history, outputDir)); - } catch (Exception ex) { - // - // a failure on loading this history is not critical - // but should be logged - task.log("Error reading history.xml: " + ex.toString()); - } - } else { - // - // create empty history file for identifying new files by last - // modified - // timestamp comperation (to compare with - // System.currentTimeMillis() don't work on Unix, because it - // maesure timestamps only in seconds). - // - try { - FileOutputStream outputStream = new FileOutputStream( - historyFile); - byte[] historyElement = new byte[]{0x3C, 0x68, 0x69, 0x73, - 0x74, 0x6F, 0x72, 0x79, 0x2F, 0x3E}; - outputStream.write(historyElement); - outputStream.close(); - } catch (IOException ex) { - throw new BuildException("Can't create history file", ex); - } - } - } - public void commit() throws IOException { - // - // if not dirty, no need to update file - // - if (dirty) { - // - // build (small) hashtable of config id's in history - // - Hashtable configs = new Hashtable(20); - Enumeration elements = history.elements(); - while (elements.hasMoreElements()) { - TargetHistory targetHistory = (TargetHistory) elements - .nextElement(); - String configId = targetHistory.getProcessorConfiguration(); - if (configs.get(configId) == null) { - configs.put(configId, configId); - } - } - FileOutputStream outStream = new FileOutputStream(historyFile); - OutputStreamWriter outWriter; - // - // early VM's don't support UTF-8 encoding - // try and fallback to the default encoding - // otherwise - String encodingName = "UTF-8"; - try { - outWriter = new OutputStreamWriter(outStream, "UTF-8"); - } catch (UnsupportedEncodingException ex) { - outWriter = new OutputStreamWriter(outStream); - encodingName = outWriter.getEncoding(); - } - BufferedWriter writer = new BufferedWriter(outWriter); - writer.write("<?xml version='1.0' encoding='"); - writer.write(encodingName); - writer.write("'?>\n"); - writer.write("<history>\n"); - StringBuffer buf = new StringBuffer(200); - Enumeration configEnum = configs.elements(); - while (configEnum.hasMoreElements()) { - String configId = (String) configEnum.nextElement(); - buf.setLength(0); - buf.append(" <processor signature=\""); - buf.append(CUtil.xmlAttribEncode(configId)); - buf.append("\">\n"); - writer.write(buf.toString()); - elements = history.elements(); - while (elements.hasMoreElements()) { - TargetHistory targetHistory = (TargetHistory) elements - .nextElement(); - if (targetHistory.getProcessorConfiguration().equals( - configId)) { - buf.setLength(0); - buf.append(" <target file=\""); - buf.append(CUtil.xmlAttribEncode(targetHistory - .getOutput())); - buf.append("\" lastModified=\""); - buf.append(Long.toHexString(targetHistory - .getOutputLastModified())); - buf.append("\">\n"); - writer.write(buf.toString()); - SourceHistory[] sourceHistories = targetHistory - .getSources(); - for (int i = 0; i < sourceHistories.length; i++) { - buf.setLength(0); - buf.append(" <source file=\""); - buf.append(CUtil.xmlAttribEncode(sourceHistories[i] - .getRelativePath())); - buf.append("\" lastModified=\""); - buf.append(Long.toHexString(sourceHistories[i] - .getLastModified())); - buf.append("\"/>\n"); - writer.write(buf.toString()); - } - writer.write(" </target>\n"); - } - } - writer.write(" </processor>\n"); - } - writer.write("</history>\n"); - writer.close(); - dirty = false; - } - } - public TargetHistory get(String configId, String outputName) { - TargetHistory targetHistory = (TargetHistory) history.get(outputName); - if (targetHistory != null) { - if (!targetHistory.getProcessorConfiguration().equals(configId)) { - targetHistory = null; - } - } - return targetHistory; - } - public void markForRebuild(Hashtable targetInfos) { - Enumeration targetInfoEnum = targetInfos.elements(); - while (targetInfoEnum.hasMoreElements()) { - markForRebuild((TargetInfo) targetInfoEnum.nextElement()); - } - } - public void markForRebuild(TargetInfo targetInfo) { - // - // if it must already be rebuilt, no need to check further - // - if (!targetInfo.getRebuild()) { - TargetHistory history = get(targetInfo.getConfiguration() - .toString(), targetInfo.getOutput().getName()); - if (history == null) { - targetInfo.mustRebuild(); - } else { - SourceHistory[] sourceHistories = history.getSources(); - File[] sources = targetInfo.getSources(); - if (sourceHistories.length != sources.length) { - targetInfo.mustRebuild(); - } else { - Hashtable sourceMap = new Hashtable(sources.length); - for (int i = 0; i < sources.length; i++) { - try { - sourceMap.put(sources[i].getCanonicalPath(), sources[i]); - } catch(IOException ex) { - sourceMap.put(sources[i].getAbsolutePath(), sources[i]); - } - } - for (int i = 0; i < sourceHistories.length; i++) { - // - // relative file name, must absolutize it on output - // directory - // - String absPath = sourceHistories[i].getAbsolutePath(outputDir); - File match = (File) sourceMap.get(absPath); - if (match != null) { - try { - match = (File) sourceMap.get(new File(absPath).getCanonicalPath()); - } catch(IOException ex) { - targetInfo.mustRebuild(); - break; - } - } - if (match == null || match.lastModified() != sourceHistories[i].getLastModified()) { - targetInfo.mustRebuild(); - break; - } - } - } - } - } - } - public void update(ProcessorConfiguration config, String[] sources, VersionInfo versionInfo) { - String configId = config.getIdentifier(); - String[] onesource = new String[1]; - String[] outputNames; - for (int i = 0; i < sources.length; i++) { - onesource[0] = sources[i]; - outputNames = config.getOutputFileNames(sources[i], versionInfo); - for (int j = 0; j < outputNames.length; j++) { - update(configId, outputNames[j], onesource); - } - } - } - private void update(String configId, String outputName, String[] sources) { - File outputFile = new File(outputDir, outputName); - // - // if output file doesn't exist or predates the start of the - // compile step (most likely a compilation error) then - // do not write add a history entry - // - if (outputFile.exists() && - !CUtil.isSignificantlyBefore(outputFile.lastModified(), historyFile.lastModified())) { - dirty = true; - history.remove(outputName); - SourceHistory[] sourceHistories = new SourceHistory[sources.length]; - for (int i = 0; i < sources.length; i++) { - File sourceFile = new File(sources[i]); - long lastModified = sourceFile.lastModified(); - String relativePath = CUtil.getRelativePath(outputDirPath, - sourceFile); - sourceHistories[i] = new SourceHistory(relativePath, - lastModified); - } - TargetHistory newHistory = new TargetHistory(configId, outputName, - outputFile.lastModified(), sourceHistories); - history.put(outputName, newHistory); - } - } - public void update(TargetInfo linkTarget) { - File outputFile = linkTarget.getOutput(); - String outputName = outputFile.getName(); - // - // if output file doesn't exist or predates the start of the - // compile or link step (most likely a compilation error) then - // do not write add a history entry - // - if (outputFile.exists() - && !CUtil.isSignificantlyBefore(outputFile.lastModified(),historyFile.lastModified())) { - dirty = true; - history.remove(outputName); - SourceHistory[] sourceHistories = linkTarget - .getSourceHistories(outputDirPath); - TargetHistory newHistory = new TargetHistory(linkTarget - .getConfiguration().getIdentifier(), outputName, outputFile - .lastModified(), sourceHistories); - history.put(outputName, newHistory); - } - } -} |