package org.jhove2.module.identify;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;
import uk.gov.nationalarchives.droid.ConfigFile;
import uk.gov.nationalarchives.droid.FileCollection;
import uk.gov.nationalarchives.droid.IdentificationFile;
import uk.gov.nationalarchives.droid.JHOVE2AnalysisControllerUtil;
import uk.gov.nationalarchives.droid.JHOVE2IAnalysisController;
import uk.gov.nationalarchives.droid.MessageDisplay;
import uk.gov.nationalarchives.droid.signatureFile.FFSignatureFile;
import uk.gov.nationalarchives.droid.signatureFile.FileFormat;
import uk.gov.nationalarchives.droid.xmlReader.PronomWebService;
/**
* This is a condensation and adaptation of {@link uk.gov.nationalarchives.droid.AnalysisController}
* Essentially, methods here have been copied from the altered version of that class included
* in the JHOVE2 distribution, with some additional accessor/mutator and convenience methods,
* and a few additional modification to suppress unwanted features.
*
* Please see the file DROID-LICENSE.txt in the JHOVE2 distribution for a complete statement
* of the BSD license rights governing the use of DROID source code.
*
* @author smorrissey
*
*/
public class DROIDAnalysisController implements JHOVE2IAnalysisController {
/**
* Contains a list of all format names from the current signature file
*/
public List<String> formatName = new ArrayList<String>();
/**
* Contains a list of all PUIDs from the current signature file
*/
public List<String> PUID = new ArrayList<String>();
/**
* Contains a list of all Mime Types from the current signature file
*/
public List<String> mimeType = new ArrayList<String>();
/**
* Contains a list of all format details (PUID, format name etc) from the current signature file
*/
public List<String> version = new ArrayList<String>();
/**
* Contains a list of all format details (PUID, format name etc) from the current signature file
*/
public List<String> fileFormatDetail = new ArrayList<String>();
/**
* Indicates whether fileFormatDetail was successfully populated
*/
public boolean isFileFormatPopulated = false;
//class variables:
private ConfigFile configFile = new ConfigFile();
private FileCollection fileCollection = new FileCollection();
private FFSignatureFile sigFile;
/**
* output formats to be used for saving results at end of run
*/
/**
* base file name to be used for saving results at end of run
*/
public DROIDAnalysisController() {
fileCollection = new FileCollection();
}
/**
* This is used to collect file format information from the current signature file
*/
public void getFileFormatsDetails() {
formatName = new ArrayList<String>();
PUID = new ArrayList<String>();
mimeType = new ArrayList<String>();
fileFormatDetail = new ArrayList<String>();
version = new ArrayList<String>();
try {
for (int i = 0; i < sigFile.getNumFileFormats(); i++) {
try {
FileFormat ff = sigFile.getFileFormat(i);
String strFormatName = ff.getName();
String strPUID = ff.getPUID();
String strMimeType = ff.getMimeType();
String strVersion = ff.getVersion();
String strFormatDetail = "";
if (strPUID != null) {
PUID.add(strPUID.trim());
}
if (strFormatDetail != null) {
if (!formatName.contains(strFormatName.trim())) {
formatName.add(strFormatName.trim());
}
}
if(strVersion != null && !strVersion.equals("")){
if (!strVersion.equals("") && !version.contains(strVersion.trim())) {
version.add(strVersion.trim());
}
}
if (strMimeType != null && !strMimeType.equals("")) {
if (!mimeType.contains(strMimeType.trim())) {
mimeType.add(strMimeType.trim());
}
}
} catch (Exception ex) {
System.out.println(ex.toString());
}
}
} catch (Exception ex) {
isFileFormatPopulated= false;
}
Collections.sort(PUID);
Collections.sort(formatName);
Collections.sort(mimeType);
isFileFormatPopulated=true;
}
/**
* Reads a configuration file, and loads the contents into memory.
*
* @param theFileName The name of the configuration file to open
* @throws Exception on error
*/
public void readConfiguration(String theFileName) throws Exception {
configFile = JHOVE2AnalysisControllerUtil.loadConfigFile(theFileName);
return;
}
/**
* Reads in and parses the signature file
* Updates the configuration file with this signature file
*
* @param theSigFileName Name of the signature file
* @return name of sig file
* @throws Exception on error
*/
public String readSigFile(String theSigFileName) throws Exception {
sigFile = JHOVE2AnalysisControllerUtil.loadSigFile(configFile, theSigFileName);
return sigFile.getVersion();
}
/**
* Empties the file list
*/
public void resetFileList() {
fileCollection.removeAll();
}
/**
* Add files to list of files ready for identifier.
* Calls addFile(fileFolderName, false)
*
* @param fileFolderName file or folder to add to
*/
public void addFile(String fileFolderName) {
addFile(fileFolderName, false);
}
/**
* Add file to list of files ready for identifier.
* If the file is already in list, then does not add it.
* If the file is a folder, then adds all files it contains.
* If isRecursive is set to true, then it also searches recursively through any subfolders.
*
* @param fileFolderName file or folder to add to
* @param isRecursive whether or not to search folders recursively
*/
public void addFile(String fileFolderName, boolean isRecursive) {
fileCollection.addFile(fileFolderName, isRecursive);
}
/**
* Remove file from the file list
*
* @param theFileName the name of the file to remove
*/
public void removeFile(String theFileName) {
fileCollection.removeFile(theFileName);
}
public void removeFile(int theIndex) {
fileCollection.removeFile(theIndex);
}
/**
* Returns an identificationFile object based on its index in the list
*
* @param theIndex index of file in file collection
* @return identifier file
*/
public IdentificationFile getFile(int theIndex) {
IdentificationFile theFile = null;
try {
theFile = fileCollection.getFile(theIndex);
} catch (Exception e){
//
}
return theFile;
}
/**
* Returns the number of files in identifier file list
*
* @return num of files
*/
public int getNumFiles() {
int theNumFiles = 0;
try {
theNumFiles = fileCollection.getNumFiles();
} catch (Exception e) {
//
}
return theNumFiles;
//return fileCollection.getNumFiles() ;
}
/**
* Get an iterator for the file collection
*
* @return iterator
*/
public Iterator<IdentificationFile> getFileIterator() {
return this.fileCollection.getIterator();
}
/**
* Return the version of the currently loaded signature file
*
* @return version
*/
public int getSigFileVersion() {
int theVersion = 0;
try {
theVersion = Integer.parseInt(sigFile.getVersion());
} catch (Exception e) {}
return theVersion;
}
public FFSignatureFile getSigFile() {
return sigFile;
}
/**
* Return the version of the uk application
*
* @return string
*/
public static String getDROIDVersion() {
String theVersion = DROID_VERSION;
//remove number after last . This is a development version, not to be displayed in About box
int theLastDot = theVersion.lastIndexOf(".");
if (theLastDot > -1) {
if (theVersion.indexOf(".") < theLastDot) {
theVersion = theVersion.substring(0, theLastDot);
}
}
return theVersion;
}
/**
* Access to the file collection
*
* @return the current file collection
*/
public FileCollection getFileCollection() {
return fileCollection;
}
/**
* checks whether there is a signature file available through the PRONOM web service
* which is a later version than the one currently loaded.
*
* @return boolean
*/
public boolean isNewerSigFileAvailable() {
return isNewerSigFileAvailable(this.getSigFileVersion());
}
/**
* checks whether there is a signature file available through the PRONOM web service
* which is a later version than the specified version number.
*
* @param currentVersion the version
* @return boolean
*/
public boolean isNewerSigFileAvailable(int currentVersion) {
int theLatestVersion;
try {
Element versionXML = PronomWebService.sendRequest(configFile.getSigFileURL(), configFile.getProxyHost(), configFile.getProxyPort(), "getSignatureFileVersionV1", null);
Boolean deprecated = Boolean.parseBoolean(PronomWebService.extractXMLelement(versionXML, "Deprecated").getValue());
if (deprecated) {
String message = "A new version of DROID is available.\nPlease visit http://droid.sourceforge.net";
MessageDisplay.generalInformation(message);
}
theLatestVersion = Integer.parseInt(PronomWebService.extractXMLelement(versionXML, "Version").getValue());
int sigFileLatestVersion = theLatestVersion;
MessageDisplay.setStatusText("The latest signature file available is V" + sigFileLatestVersion);
} catch (Exception e) {
MessageDisplay.generalWarning("Unable to get signature file version from PRONOM website:\n" + e.getMessage());
return false;
}
return (theLatestVersion > currentVersion);
}
/**
* Download the latest signature file from the PRONOM web service, save it to file
* An input flag determines whether or not to load it in to the current instance of uk
*
* @param theFileName file where to save signature file
* @param isLoadSigFile Flag indicating whether to load the signature file into the current instance of uk
*/
public void downloadwwwSigFile(String theFileName, boolean isLoadSigFile) {
try {
Element sigFile = PronomWebService.sendRequest(configFile.getSigFileURL(), configFile.getProxyHost(), configFile.getProxyPort(), "getSignatureFileV1", "FFSignatureFile");
try {
XMLOutputter outputter = new XMLOutputter();
java.io.BufferedWriter out = new java.io.BufferedWriter(new java.io.FileWriter(theFileName));
out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
outputter.output(sigFile, out);
out.close();
if (isLoadSigFile) {
try {
configFile.setDateLastDownload();
readSigFile(theFileName);
getFileFormatsDetails();
} catch (Exception e) {
MessageDisplay.generalWarning("Unable to read in downloaded signature file ");
}
}
} catch (Exception e) {
String locaion = theFileName.substring(0,theFileName.lastIndexOf(File.separatorChar));
MessageDisplay.generalWarning("Unable to save downloaded signature file to location: "+locaion+".\nEither the location does not exist or DROID does not have Write permissions to this location");
}
} catch (Exception e) {
MessageDisplay.generalWarning("Unable to download signature file from the PRONOM web service");
}
}
/**
* Download the latest signature file from the PRONOM web service, save it to file
* and load it in to the current instance of uk
*
* @param theFileName file where to save signature file
*/
public void downloadwwwSigFile(String theFileName) {
downloadwwwSigFile(theFileName, true);
}
/**
* Download the latest signature file from the PRONOM web service, save it to a DEFAULT location
* and load it in to the current instance of uk
* Saves to same folder as current signature file but as
* DROID_Signature_V[X].xml , where [X] is the version number of the signature file
*/
public void downloadwwwSigFile() {
try {
int theLatestVersion = Integer.parseInt(PronomWebService.sendRequest(configFile.getSigFileURL(), configFile.getProxyHost(), configFile.getProxyPort(), "getSignatureFileVersionV1", "Version").getValue());
java.io.File currentSigFile = new java.io.File(configFile.getSigFileName());
String currentPath = "";
if (currentSigFile != null) {
currentPath = (currentSigFile.getAbsoluteFile()).getParent() + java.io.File.separator;
}
final String newSigFileName = currentPath
+ "DROID_SignatureFile_V"
+ theLatestVersion
+ ".xml";
downloadwwwSigFile(newSigFileName);
} catch (Exception e) {
MessageDisplay.generalWarning("Unable to download signature file from the PRONOM web service");
}
}
/**
* Checks whether a new signature file download is due
* based on current date and settings in the configuration file
*
* @return boolean
*/
public boolean isSigFileDownloadDue() {
return configFile.isDownloadDue();
}
/**
* Returns the date current signature file was created
*
* @return date signature file was created
*/
public String getSignatureFileDate() {
String theDate = "";
try {
theDate = sigFile.getDateCreated();
} catch (Exception e) {
//
}
if (theDate.equals("")) {
theDate = "No date given";
}
return theDate;
//return sigFile.getDateCreated() ;
}
/**
* Returns the file path of the signature file
*
* @return signature file file path
*/
public String getSignatureFileName() {
return configFile.getSigFileName();
}
/**
* Get the PUID resolution base URL
*
* @return PUID resolution
*/
public String getPuidResolutionURL() {
return configFile.getPuidResolution();
}
/**
* Sets the URL of the signature file webservices
*
* @param sigFileURL signature file
*/
public void setSigFileURL(String sigFileURL) {
configFile.setSigFileURL(sigFileURL);
}
/**
* Gets the number of days after which user should be alerted for new signature file
*
* @return number of days after which user should be alerted for new signature file
*/
public int getSigFileCheckFreq() {
return configFile.getSigFileCheckFreq();
}
/**
* Updates the configuration parameter which records the interval after which
* the signature file should be updated.
*
* @param theFreq The number of days after which the user will be prompted to check for a newer signature file
*/
public void setSigFileCheckFreq(String theFreq) {
configFile.setSigFileCheckFreq(theFreq);
}
/**
* updates the DateLastDownload element of the configuration file and updates
* the configuration file. This is to be used whenever the user checks for
* a signature file update, but one is not found
*/
public void updateDateLastDownload() {
//set the DateLastDownload to now
configFile.setDateLastDownload();
//save to file
try {
configFile.saveConfiguration();
} catch (IOException e) {
MessageDisplay.generalWarning("Unable to save configuration updates");
}
}
public ConfigFile getConfigFile() {
return configFile;
}
public void setConfigFile(ConfigFile configFile) {
this.configFile = configFile;
}
public ConfigFile loadConfigFile(String theFileName) throws Exception{
this.readConfiguration(theFileName);
return this.configFile;
}
public void setSigFile(FFSignatureFile sigFile) {
this.sigFile = sigFile;
}
}