Java tutorial
/** * This file is part of vVoteVerifier which is designed to be used as a verifiation tool for the vVote Election System. * Copyright (C) 2014 James Rumble (jerumble@gmail.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 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 Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.vvote.verifierlibrary.utils.io; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import au.com.bytecode.opencsv.CSVReader; import com.vvote.commits.CommitFileNames; import com.vvote.thirdparty.json.orgjson.JSONArray; import com.vvote.thirdparty.json.orgjson.JSONException; import com.vvote.thirdparty.json.orgjson.JSONObject; import com.vvote.verifierlibrary.exceptions.JSONIOException; /** * Provides a number of input and output functions for use throughout the system * * @author James Rumble * */ public class IOUtils { /** * A full stop */ private static final String PERIOD = "."; /** * Provides logging for the class */ private static final Logger logger = LoggerFactory.getLogger(IOUtils.class); /** * Checks the extension of a file * * @param fileType * @param filename * @return true if the extension of the filename matches that which is * expected */ public static boolean checkExtension(FileType fileType, String filename) { return checkExtension(fileType.getExtension(), filename); } /** * Checks a filename for an expected extension * * @param expectedExtension * @param filename * @return the name of the file without the extension */ private static boolean checkExtension(String expectedExtension, String filename) { if (filename != null) { if (filename.length() > 0) { if (filename.contains(".")) { // check for last period int index = filename.lastIndexOf('.'); if (index > 0) { // check extension is correct if (!filename.substring(index + 1).equals(expectedExtension)) { return false; } return true; } } } } return false; } /** * Finds a file using the filename provided * * @param name * @param filename * @return the path for the found file */ public static String findFile(String name, String filename) { File file = new File(filename); if (file.exists()) { return findFile(name, file); } return null; } /** * Finds a file using its file name from a specified File starting point. * * @param name * @param file * @return the path for the found file */ public static String findFile(String name, File file) { File[] currentFileList = file.listFiles(); String result = null; if (currentFileList != null) { for (File currentFile : currentFileList) { if (name.equalsIgnoreCase(currentFile.getName())) { return currentFile.getPath(); } else if (currentFile.isDirectory()) { result = findFile(name, currentFile); if (result != null) { return result; } } } } return null; } /** * Utility class to extract a zip file * * @param filepath * @return the location of the extract zip file * @throws IOException */ public static String extractZipFile(String filepath) throws IOException { if (IOUtils.checkExtension(FileType.ZIP, filepath)) { try (ZipFile zipFile = new ZipFile(filepath)) { // files in zip file Enumeration<? extends ZipEntry> entries = zipFile.entries(); // current zip directory File zipDirectory = new File(filepath); // output directory - doesn't include the .zip extension File outputDirectory = new File( IOUtils.join(zipDirectory.getParent(), IOUtils.getFileNameWithoutExtension(filepath))); // make directory if not exists if (!outputDirectory.exists()) { outputDirectory.mkdir(); } InputStream is = null; FileOutputStream fos = null; byte[] bytes = null; int length = 0; // loop over each file in zip file while (entries.hasMoreElements()) { ZipEntry zipEntry = entries.nextElement(); String entryName = zipEntry.getName(); // current output file File file = new File(IOUtils.join(outputDirectory.getPath(), entryName)); File currentOutputFile = new File(getFilePathWithoutExtension(file.getPath())); if (currentOutputFile.exists()) { if (getFileNameWithoutExtension(entryName) .contains(CommitFileNames.WBB_UPLOAD.getFileName())) { try (ZipFile currentZipFile = new ZipFile(file)) { Enumeration<? extends ZipEntry> currentZipEntries = currentZipFile.entries(); long currentUncompressedZipSize = currentZipEntries.nextElement().getSize(); long currentDirectorySize = FileUtils.sizeOfDirectory(currentOutputFile); if (currentUncompressedZipSize == currentDirectorySize) { continue; } } } } // if directory make it if (entryName.endsWith("/")) { file.mkdirs(); } else { // write current input zip file to output location is = zipFile.getInputStream(zipEntry); fos = new FileOutputStream(file); bytes = new byte[1024]; while ((length = is.read(bytes)) >= 0) { fos.write(bytes, 0, length); } is.close(); fos.close(); } } return outputDirectory.getPath(); } } logger.error("Provided filepath: {} does not point to a valid zip file", filepath); throw new IOException("Provided filepath: " + filepath + " does not point to a valid zip file"); } /** * Gets the name of a file without the extension * * @param filename * @return the name of a file without the extension */ public static String getFileNameWithoutExtension(String filename) { return FilenameUtils.removeExtension(new File(filename).getName()); } /** * Gets a file path not including the extension of the file * * @param filename * @return file path without the extension of the file */ public static String getFilePathWithoutExtension(String filename) { return FilenameUtils.removeExtension(new File(filename).getPath()); } /** * Performs a joining of two paths together * * @param path1 * @param path2 * @return the path when the two input paths are 'joined' */ public static String join(String path1, String path2) { File file1 = new File(path1); File file2 = new File(file1, path2); return file2.getPath(); } /** * Read a csv file from a specified filepath into an arraylist containing * * @param filepath * @return a list of rows of the csv file * @throws IOException * @throws FileNotFoundException */ public static List<List<String>> readCSVFromFile(String filepath) throws FileNotFoundException, IOException { if (IOUtils.checkExtension(FileType.CSV, filepath)) { List<List<String>> csvResult = new ArrayList<List<String>>(); try (CSVReader reader = new CSVReader(new FileReader(filepath))) { String[] nextLine; List<String> currentLine = null; while ((nextLine = reader.readNext()) != null) { currentLine = Arrays.asList(nextLine); csvResult.add(currentLine); } } return csvResult; } logger.error("Provided filepath: {} does not point to a valid csv file", filepath); throw new IOException("Provided filepath: " + filepath + " does not point to a valid csv file"); } /** * Reads a JSON array from a given filepath * * @param filepath * @return The <code>JSONArray</code> * @throws JSONIOException */ public static JSONArray readJSONArrayFromFile(String filepath) throws JSONIOException { if (IOUtils.checkExtension(FileType.JSON, filepath)) { try { logger.debug("Reading JSONArray from file: '" + filepath + "'"); return new JSONArray(IOUtils.readStringFromFile(filepath)); } catch (JSONException e) { logger.error("Error when trying to read from: '" + filepath + "'", e); throw new JSONIOException("Error when trying to read from: '" + filepath + "'", e); } catch (FileNotFoundException e) { logger.error("Error when trying to read from: '" + filepath + "'", e); throw new JSONIOException("Error when trying to read from: '" + filepath + "'", e); } catch (IOException e) { logger.error("Error when trying to read from: '" + filepath + "'", e); throw new JSONIOException("Error when trying to read from: '" + filepath + "'", e); } } logger.error("Provided filepath: {} does not point to a valid json file", filepath); throw new JSONIOException("Provided filepath: " + filepath + " does not point to a valid json file"); } /** * Reads a JSON message from a given filepath * * @param filepath * @return The <code>List</code> of <code>JSONObject</code> messages * @throws JSONIOException */ public static List<JSONObject> readJSONMessagesFromFile(String filepath) throws JSONIOException { logger.debug("Reading in messages: {}", filepath); if (IOUtils.checkExtension(FileType.JSON, filepath)) { List<JSONObject> jsonMessages = new ArrayList<JSONObject>(); String line = null; // create reader for the file containing election data try (BufferedReader messagesReader = new BufferedReader(new FileReader(filepath))) { // loop over each line and construct a new message per line // using the message factory while ((line = messagesReader.readLine()) != null) { jsonMessages.add(new JSONObject(line)); } } catch (FileNotFoundException e) { logger.error("Error when trying to read from: '" + filepath + "'", e); throw new JSONIOException("Error when trying to read from: '" + filepath + "'", e); } catch (IOException e) { logger.error("Error when trying to read from: '" + filepath + "'", e); throw new JSONIOException("Error when trying to read from: '" + filepath + "'", e); } catch (JSONException e) { logger.error("Error when trying to read from: '" + filepath + "'", e); throw new JSONIOException("Error when trying to read from: '" + filepath + "'", e); } logger.debug("Successfully loaded in the messages data file: {}", filepath); return jsonMessages; } logger.error("Provided filepath: {} does not point to a valid json file", filepath); throw new JSONIOException("Provided filepath: " + filepath + " does not point to a valid json file"); } /** * Reads a single JSONObject from a given filepath * * @param filepath * @return The <code>JSONObject</code> * @throws JSONIOException */ public static JSONObject readJSONObjectFromFile(String filepath) throws JSONIOException { if (IOUtils.checkExtension(FileType.JSON, filepath)) { try { logger.debug("Reading JSONObject from file: '" + filepath + "'"); return new JSONObject(IOUtils.readStringFromFile(filepath)); } catch (JSONException e) { logger.error("Error when trying to read from: '" + filepath + "'", e); throw new JSONIOException("Error when trying to read from: '" + filepath + "'", e); } catch (FileNotFoundException e) { logger.error("Error when trying to read from: '" + filepath + "'", e); throw new JSONIOException("Error when trying to read from: '" + filepath + "'", e); } catch (IOException e) { logger.error("Error when trying to read from: '" + filepath + "'", e); throw new JSONIOException("Error when trying to read from: '" + filepath + "'", e); } } logger.error("Provided filepath: {} does not point to a valid json file", filepath); throw new JSONIOException("Provided filepath: " + filepath + " does not point to a valid json file"); } /** * Reads a string from a given filepath. Reads the whole file into a single * string object before returning * * @param filepath * @return the whole file being read as a single string * @throws IOException * @throws FileNotFoundException */ public static String readStringFromFile(String filepath) throws FileNotFoundException, IOException { logger.debug("Reading a string from a given filepath: {}", filepath); StringBuffer sb = new StringBuffer(); String line = null; try (BufferedReader br = new BufferedReader(new FileReader(new File(filepath)))) { while ((line = br.readLine()) != null) { if (line.trim().length() > 0) { sb.append(line); } } } return sb.toString(); } /** * Read in the zip file and store each entry so it can be looked up later * * @param filepath * @return the list of all files within the provided zip file * @throws IOException * @throws FileNotFoundException */ public static List<String> readZipFileNames(String filepath) throws FileNotFoundException, IOException { logger.debug("Reading zip file contents: {}", filepath); if (IOUtils.checkExtension(FileType.ZIP, filepath)) { List<String> zipFiles = new ArrayList<String>(); ZipEntry zipEntry = null; try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(filepath))) { // loop over each file while ((zipEntry = zipInputStream.getNextEntry()) != null) { // add the filename zipFiles.add(zipEntry.getName()); } } logger.debug("Successfully read the zip file: {}", filepath); return zipFiles; } logger.error("Provided filepath: {} does not point to a valid zip file", filepath); throw new IOException("Provided filepath: " + filepath + " does not point to a valid zip file"); } /** * Writes a JSON array to file * * @param obj * @param filepath * @throws JSONIOException */ public static void writeJSONToFile(JSONArray obj, String filepath) throws JSONIOException { try { writeStringToFile(obj.toString(), filepath); } catch (IOException e) { logger.error("Cannot write JSONArray to file: {}", filepath, e); throw new JSONIOException("Cannot write JSONArray to file:" + filepath, e); } } /** * Writes a String to file * * @param data * @param filepath * @throws IOException */ public static void writeStringToFile(String data, String filepath) throws IOException { File file = new File(filepath); if (file.getParentFile() != null && !file.getParentFile().exists()) { file.getParentFile().mkdirs(); } try (BufferedWriter bw = new BufferedWriter(new FileWriter(filepath))) { bw.write(data); } } /** * Prevents the class being externally created */ private IOUtils() { return; } /** * Simple method to add an extension onto a filename * * @param fileName * @param fileType * @return the filename with the added extension */ public static String addExtension(String fileName, FileType fileType) { if (fileName.endsWith(PERIOD)) { return fileName + fileType.getExtension(); } return fileName + PERIOD + fileType.getExtension(); } }