blob: 00aad44265798336ceb06ff6d149cc896bf2a73b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/
/* $Id$ */
package org.apache.fop.pdf;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
/**
* A class to generate the File Identifier of a PDF document (the ID entry of the file
* trailer dictionary).
*/
abstract class FileIDGenerator {
abstract byte[] getOriginalFileID();
abstract byte[] getUpdatedFileID();
private static final class RandomFileIDGenerator extends FileIDGenerator {
private byte[] fileID;
private RandomFileIDGenerator() {
Random random = new Random();
fileID = new byte[16];
random.nextBytes(fileID);
}
@Override
byte[] getOriginalFileID() {
return fileID;
}
@Override
byte[] getUpdatedFileID() {
return fileID;
}
}
private static final class DigestFileIDGenerator extends FileIDGenerator {
private byte[] fileID;
private final PDFDocument document;
private final MessageDigest digest;
DigestFileIDGenerator(PDFDocument document) throws NoSuchAlgorithmException {
this.document = document;
this.digest = MessageDigest.getInstance("MD5");
}
@Override
byte[] getOriginalFileID() {
if (fileID == null) {
generateFileID();
}
return fileID;
}
@Override
byte[] getUpdatedFileID() {
return getOriginalFileID();
}
private void generateFileID() {
DateFormat df = new SimpleDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS");
digest.update(PDFDocument.encode(df.format(new Date())));
// Ignoring the filename here for simplicity even though it's recommended
// by the PDF spec
digest.update(PDFDocument.encode(String.valueOf(document.getCurrentFileSize())));
digest.update(document.getInfo().toPDF());
fileID = digest.digest();
}
}
/**
* Use this method when the file ID is needed before the document is finalized. The
* digest method recommended by the PDF Reference is based, among other things, on the
* file size.
*
* @return an instance that generates a random sequence of bytes for the File
* Identifier
*/
static FileIDGenerator getRandomFileIDGenerator() {
return new RandomFileIDGenerator();
}
/**
* Returns an instance that generates a file ID using the digest method recommended by
* the PDF Reference. To properly follow the Reference, the size of the document must
* no longer change after this method is called.
*
* @param document the document whose File Identifier must be generated
* @return the generator
* @throws NoSuchAlgorithmException if the MD5 Digest algorithm is not available
*/
static FileIDGenerator getDigestFileIDGenerator(PDFDocument document)
throws NoSuchAlgorithmException {
return new DigestFileIDGenerator(document);
}
}