Java tutorial
/* * #%L * Netarchivesuite - common - test * %% * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, * the National Library of France and the Austrian National Library. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 2.1 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * <http://www.gnu.org/licenses/lgpl-2.1.html>. * #L% */ package dk.netarkivet.common.arcrepository; import java.io.File; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.OutputStream; import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.archive.io.ArchiveReader; import org.archive.io.ArchiveReaderFactory; import org.archive.io.ArchiveRecord; import dk.netarkivet.common.distribute.RemoteFileFactory; import dk.netarkivet.common.distribute.arcrepository.ArcRepositoryClient; import dk.netarkivet.common.distribute.arcrepository.BatchStatus; import dk.netarkivet.common.distribute.arcrepository.BitarchiveRecord; import dk.netarkivet.common.distribute.arcrepository.Replica; import dk.netarkivet.common.distribute.arcrepository.ReplicaStoreState; import dk.netarkivet.common.exceptions.ArgumentNotValid; import dk.netarkivet.common.exceptions.IOFailure; import dk.netarkivet.common.exceptions.NotImplementedException; import dk.netarkivet.common.utils.FileUtils; import dk.netarkivet.common.utils.batch.BatchLocalFiles; import dk.netarkivet.common.utils.batch.FileBatchJob; /** * A minimal implementation of ArcRepositoryClient that just has one local directory that it keeps its files in, no * checking no nothing. */ public class TrivialArcRepositoryClient implements ArcRepositoryClient { /** The directory name of the local arcrepository. */ private static final String ARC_REPOSITORY_DIR_NAME = "ArcRepository"; /** Store files in this dir -- might later use a separate setting. */ private final File dir = new File(FileUtils.getTempDir(), ARC_REPOSITORY_DIR_NAME); /** The class logger. */ private Log log = LogFactory.getLog(getClass()); /** * Constructor for this class. Creates a local directory for the arcrepository. */ public TrivialArcRepositoryClient() { FileUtils.createDir(dir); } /** Call on shutdown to release external resources. */ public void close() { } /** * Store the given file in the ArcRepository. After storing, the file is deleted. * * @param file A file to be stored. Must exist. * @throws IOFailure thrown if store is unsuccessful, or failed to clean up files after the store operation. * @throws ArgumentNotValid if file parameter is null or file is not an existing file. */ public void store(File file) throws IOFailure, ArgumentNotValid { ArgumentNotValid.checkNotNull(file, "file"); FileUtils.copyFile(file, new File(dir, file.getName())); FileUtils.remove(file); } /** * Gets a single ARC record out of the ArcRepository. * * @param arcfile The name of a file containing the desired record. * @param index The offset of the desired record in the file * @return a BitarchiveRecord-object, or null if request times out or object is not found. * @throws ArgumentNotValid if arcfile is null or empty, or index is negative * @throws IOFailure If the get operation failed. */ public BitarchiveRecord get(String arcfile, long index) throws ArgumentNotValid { ArgumentNotValid.checkNotNullOrEmpty(arcfile, "arcfile"); ArgumentNotValid.checkNotNegative(index, "index"); ArchiveReader reader = null; ArchiveRecord record = null; try { reader = ArchiveReaderFactory.get(new File(dir, arcfile), index); record = reader.get(); return new BitarchiveRecord(record, arcfile); } catch (IOException e) { throw new IOFailure("Error reading record from '" + arcfile + "' offset " + index, e); } finally { if (record != null) { try { record.close(); } catch (IOException e) { log.info("Error closing ARC record '" + record + "'", e); } } if (reader != null) { try { reader.close(); } catch (IOException e) { log.info("Error closing ARC reader '" + reader + "'", e); } } } } /** * Retrieves a file from an ArcRepository and places it in a local file. * * @param arcfilename Name of the arcfile to retrieve. * @param replica The bitarchive to retrieve the data from (not used in this implementation) * @param toFile Filename of a place where the file fetched can be put. * @throws IOFailure if there are problems getting a reply or the file could not be found. */ public void getFile(String arcfilename, Replica replica, File toFile) { ArgumentNotValid.checkNotNullOrEmpty(arcfilename, "arcfilename"); ArgumentNotValid.checkNotNull(toFile, "toFile"); FileUtils.copyFile(new File(dir, arcfilename), toFile); } /** * Runs a batch batch job on each file in the ArcRepository. * * @param job An object that implements the FileBatchJob interface. The initialize() method will be called before * processing and the finish() method will be called afterwards. The process() method will be called with each File * entry. An optional function postProcess() allows handling the combined results of the batchjob, e.g. summing the * results, sorting, etc. * @param replicaId The archive to execute the job on (not used in this implementation) * @param args The arguments for the batchjob. * @return The status of the batch job after it ended. */ public BatchStatus batch(final FileBatchJob job, String replicaId, String... args) { ArgumentNotValid.checkNotNull(job, "job"); OutputStream os = null; File resultFile; try { resultFile = File.createTempFile("batch", replicaId, FileUtils.getTempDir()); os = new FileOutputStream(resultFile); File[] files = dir.listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { Pattern filenamePattern = job.getFilenamePattern(); return new File(dir, name).isFile() && (filenamePattern == null || filenamePattern.matcher(name).matches()); } }); BatchLocalFiles batcher = new BatchLocalFiles(files); batcher.run(job, os); } catch (IOException e) { throw new IOFailure("Cannot perform batch job '" + job + "'", e); } finally { if (os != null) { try { os.close(); } catch (IOException e) { log.info("Error closing batch output stream '" + os + "'", e); } } } return new BatchStatus(replicaId, job.getFilesFailed(), job.getNoOfFilesProcessed(), RemoteFileFactory.getMovefileInstance(resultFile), job.getExceptions()); } /** * Updates the administrative data in the ArcRepository for a given file and replica. (not implemented) * * @param fileName The name of a file stored in the ArcRepository. * @param bitarchiveId The id of the replica that the administrative data for fileName is wrong for. * @param newval What the administrative data will be updated to. */ public void updateAdminData(String fileName, String bitarchiveId, ReplicaStoreState newval) { throw new NotImplementedException("Function has not been implemented"); } /** * Updates the checksum kept in the ArcRepository for a given file. It is the responsibility of the ArcRepository * implementation to ensure that this checksum matches that of the underlying files. * * @param filename The name of a file stored in the ArcRepository. * @param checksum The new checksum. */ public void updateAdminChecksum(String filename, String checksum) { throw new NotImplementedException("Function has not been implemented"); } /** * Remove a file from one part of the ArcRepository, retrieving a copy for security purposes. This is typically used * when repairing a file that has been corrupted. * * @param fileName The name of the file to remove. * @param bitarchiveId The id of the replica from which to remove the file (not used) * @param checksum The checksum of the file to be removed (not used) * @param credentials A string that shows that the user is allowed to perform this operation (not used) * @return A local copy of the file removed. */ public File removeAndGetFile(String fileName, String bitarchiveId, String checksum, String credentials) { ArgumentNotValid.checkNotNullOrEmpty(fileName, "fileName"); // Ignores bitarchiveId, checksum, and credentials for now File copiedTo = null; try { copiedTo = File.createTempFile("removeAndGetFile", fileName); } catch (IOException e) { throw new IOFailure("Cannot make temp file to copy '" + fileName + "' into", e); } File file = new File(dir, fileName); FileUtils.copyFile(file, copiedTo); FileUtils.remove(file); return copiedTo; } public File getAllChecksums(String replicaId) { // TODO Auto-generated method stub throw new NotImplementedException("TODO: Implement me!"); } public File getAllFilenames(String replicaId) { // TODO Auto-generated method stub throw new NotImplementedException("TODO: Implement me!"); } public File correct(String replicaId, String checksum, File file, String credentials) { // TODO Auto-generated method stub throw new NotImplementedException("TODO: Implement me!"); } @Override public String getChecksum(String replicaId, String filename) { // TODO Auto-generated method stub return null; } }