diff --git a/LabJavaIO/pom.xml b/LabJavaIO/pom.xml index 6a5afb94..6c48572c 100644 --- a/LabJavaIO/pom.xml +++ b/LabJavaIO/pom.xml @@ -7,8 +7,8 @@ jar UTF-8 - 1.8 - 1.8 + 11 + 11 RES Lab Java IO diff --git a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/Application.java b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/Application.java index 25e835c4..d2c711f6 100644 --- a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/Application.java +++ b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/Application.java @@ -9,10 +9,7 @@ import ch.heigvd.res.labio.quotes.QuoteClient; import org.apache.commons.io.FileUtils; -import java.io.File; -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; +import java.io.*; import java.net.URISyntaxException; import java.util.logging.Level; import java.util.logging.Logger; @@ -97,11 +94,15 @@ public void fetchAndStoreQuotes(int numberOfQuotes) throws IOException { * client to fetch quotes. We have removed a single line from this method. It is a call to * one method provided by this class, which is responsible for storing the content of the * quote in a text file (and for generating the directories based on the tags). + * + * => Done */ LOG.info("Received a new joke with " + quote.getTags().size() + " tags."); for (String tag : quote.getTags()) { LOG.info("> " + tag); } + // Call storeQuote. With quote and the filename = "quote-i.utf8 + storeQuote(quote, "quote-" + Integer.toString(i) + ".utf8"); } } @@ -133,7 +134,30 @@ void clearOutputDirectory() throws IOException { * @throws IOException */ void storeQuote(Quote quote, String filename) throws IOException { - throw new UnsupportedOperationException("The student has not implemented this method yet."); + + //Create directories with with the tags + + String str = WORKSPACE_DIRECTORY; + for (int i = 0; i < quote.getTags().size(); ++i){ + str += "/"; + str += quote.getTags().get(i); + } + new File(str).mkdirs(); + + + //Create file and write quote in + + str += "/"; + str += filename; + + try { + FileWriter myWriter = new FileWriter(str); + myWriter.write(quote.getQuote()); + myWriter.close(); + } catch (IOException e) { + System.out.println("An error occurred."); + e.printStackTrace(); + } } /** @@ -149,7 +173,14 @@ public void visit(File file) { * There is a missing piece here. Notice how we use an anonymous class here. We provide the implementation * of the the IFileVisitor interface inline. You just have to add the body of the visit method, which should * be pretty easy (we want to write the filename, including the path, to the writer passed in argument). + * + * => Done */ + try { + writer.write(file.getPath() + "\n"); + } catch (IOException e) { + e.printStackTrace(); + } } }); } diff --git a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/Utils.java b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/Utils.java index c8a3a5ad..22ae3b1d 100644 --- a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/Utils.java +++ b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/Utils.java @@ -3,24 +3,57 @@ import java.util.logging.Logger; /** - * * @author Olivier Liechti */ public class Utils { - private static final Logger LOG = Logger.getLogger(Utils.class.getName()); - - /** - * This method looks for the next new line separators (\r, \n, \r\n) to extract - * the next line in the string passed in arguments. - * - * @param lines a string that may contain 0, 1 or more lines - * @return an array with 2 elements; the first element is the next line with - * the line separator, the second element is the remaining text. If the argument does not - * contain any line separator, then the first element is an empty string. - */ - public static String[] getNextLine(String lines) { - throw new UnsupportedOperationException("The student has not implemented this method yet."); - } + private static final Logger LOG = Logger.getLogger(Utils.class.getName()); + + /** + * This method looks for the next new line separators (\r, \n, \r\n) to extract + * the next line in the string passed in arguments. + * + * @param lines a string that may contain 0, 1 or more lines + * @return an array with 2 elements; the first element is the next line with + * the line separator, the second element is the remaining text. If the argument does not + * contain any line separator, then the first element is an empty string. + */ + public static String[] getNextLine(String lines) { + + // String array of size 2 + String[] s = new String[2]; + s[0] = ""; + s[1] = ""; + + // Write char in the first cell of the String array until end or line separators. + for (int i = 0; i < lines.length(); ++i) { + s[0] += lines.substring(i, i + 1); + if (lines.charAt(i) == '\r') { + // Check if there is \n after \r for windows conditions. + if ((i + 1) < lines.length()) { + if (lines.charAt(i + 1) == '\n') { + ++i; + s[0] += lines.substring(i, i + 1); + } + } + break; + } + if (lines.charAt(i) == '\n') + break; + } + + // Write what remains in lines in the 2nd cell + if (s[0].length() < lines.length()) + s[1] = lines.substring(s[0].length()); + char c = s[0].charAt(s[0].length() - 1); + + // If there is only one line, first cell is empty, 2nd has the line. + if (c != '\r' && c != '\n') { + s[1] = s[0]; + s[0] = ""; + } + + return s; + } } diff --git a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/explorers/DFSFileExplorer.java b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/explorers/DFSFileExplorer.java index b97c4a72..2f73a7bf 100644 --- a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/explorers/DFSFileExplorer.java +++ b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/explorers/DFSFileExplorer.java @@ -4,6 +4,7 @@ import ch.heigvd.res.labio.interfaces.IFileVisitor; import java.io.File; +import java.util.Arrays; /** * This implementation of the IFileExplorer interface performs a depth-first @@ -17,7 +18,24 @@ public class DFSFileExplorer implements IFileExplorer { @Override public void explore(File rootDirectory, IFileVisitor vistor) { - throw new UnsupportedOperationException("The student has not implemented this method yet."); + vistor.visit(rootDirectory); + File[] lFiles = rootDirectory.listFiles(); + if (lFiles != null) + Arrays.sort(lFiles); + if (lFiles != null) { + for (File file : lFiles) { + if (file.isDirectory()) { + explore(file, vistor); + } + } + } + if (lFiles != null) { + for (File file : lFiles) { + if (!file.isDirectory()) { + vistor.visit(file); + } + } + } } } diff --git a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/filters/FileNumberingFilterWriter.java b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/filters/FileNumberingFilterWriter.java index 976c9462..c638ca44 100644 --- a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/filters/FileNumberingFilterWriter.java +++ b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/filters/FileNumberingFilterWriter.java @@ -10,32 +10,95 @@ * When filter encounters a line separator, it sends it to the decorated writer. * It then sends the line number and a tab character, before resuming the write * process. - * + *

* Hello\n\World -> 1\Hello\n2\tWorld * * @author Olivier Liechti */ public class FileNumberingFilterWriter extends FilterWriter { - private static final Logger LOG = Logger.getLogger(FileNumberingFilterWriter.class.getName()); + private static final Logger LOG = Logger.getLogger(FileNumberingFilterWriter.class.getName()); + + private int nbLines = 0; + boolean isLastIsN = false; + boolean isLastIsR = false; + + public FileNumberingFilterWriter(Writer out) { + super(out); + } + + @Override + public void write(String str, int off, int len) throws IOException { + + // Creation of the new String to write + String newStr = ""; + + // Keep trace of new char + int newChar = 0; + + // Condition for first line + if (nbLines == 0) { + newStr = str.substring(0, off) + "1\t"; + ++nbLines; + newChar += 2; + } + newStr += str.substring(off); + + // Add nbLines + \t when there is a line separator + for (int i = 0; i < newStr.length(); ++i) { + if (newStr.charAt(i) == '\r' || newStr.charAt(i) == '\n') { + ++nbLines; + ++i; + if (i < newStr.length()) { + if (newStr.charAt(i) == '\n' && newStr.charAt(i-1) == '\r') { + ++i; + } + } + newStr = newStr.substring(0, i) + Integer.toString(nbLines) + "\t" + newStr.substring(i); + newChar += 1; + newChar += Integer.toString(nbLines).length(); + } + } + + // Keep trace for write(int c) + isLastIsN = newStr.charAt(newStr.length() - 1) == '\n'; + isLastIsR = newStr.charAt(newStr.length() - 1) == '\r'; + + // Write + out.write(newStr, off, len + newChar); + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + // Simply send it to String version. + String str = new String(cbuf); + write(str, off, len); + } - public FileNumberingFilterWriter(Writer out) { - super(out); - } + @Override + public void write(int c) throws IOException { - @Override - public void write(String str, int off, int len) throws IOException { - throw new UnsupportedOperationException("The student has not implemented this method yet."); - } + // First line conditions + if (nbLines == 0) { + ++nbLines; + out.write('1'); + out.write('\t'); + } - @Override - public void write(char[] cbuf, int off, int len) throws IOException { - throw new UnsupportedOperationException("The student has not implemented this method yet."); - } + // If last is a separator line, then write new line + // Except if next char is the 2nd is the separator line for windows condition + if (isLastIsR || isLastIsN) { + if (c != '\n') { + ++nbLines; + out.write(Integer.toString(nbLines)); + out.write('\t'); + } + } - @Override - public void write(int c) throws IOException { - throw new UnsupportedOperationException("The student has not implemented this method yet."); - } + // Keep trace and write current char + isLastIsR = c == '\r'; + isLastIsN = c == '\n'; + out.write(c); + } } diff --git a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/filters/UpperCaseFilterWriter.java b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/filters/UpperCaseFilterWriter.java index 0f41a5dd..73365480 100644 --- a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/filters/UpperCaseFilterWriter.java +++ b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/filters/UpperCaseFilterWriter.java @@ -8,6 +8,8 @@ * * @author Olivier Liechti */ + +//initial commit public class UpperCaseFilterWriter extends FilterWriter { public UpperCaseFilterWriter(Writer wrappedWriter) { @@ -16,17 +18,22 @@ public UpperCaseFilterWriter(Writer wrappedWriter) { @Override public void write(String str, int off, int len) throws IOException { - throw new UnsupportedOperationException("The student has not implemented this method yet."); + String newStr = str.substring(0, off); + newStr += str.substring(off, off + len).toUpperCase(); + newStr += str.substring(off + len); + out.write(newStr, off, len); } @Override public void write(char[] cbuf, int off, int len) throws IOException { - throw new UnsupportedOperationException("The student has not implemented this method yet."); + for (int i = 0; i < len; ++i) + cbuf[i + off] = Character.toUpperCase(cbuf[i + off]); + out.write(cbuf, off, len); } @Override public void write(int c) throws IOException { - throw new UnsupportedOperationException("The student has not implemented this method yet."); + out.write(Character.toUpperCase(c)); } } diff --git a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/CompleteFileTransformer.java b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/CompleteFileTransformer.java index 4beca482..1656db52 100644 --- a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/CompleteFileTransformer.java +++ b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/CompleteFileTransformer.java @@ -1,5 +1,8 @@ package ch.heigvd.res.labio.impl.transformers; +import ch.heigvd.res.labio.impl.filters.FileNumberingFilterWriter; +import ch.heigvd.res.labio.impl.filters.UpperCaseFilterWriter; + import java.io.Writer; /** @@ -15,16 +18,19 @@ public class CompleteFileTransformer extends FileTransformer { @Override public Writer decorateWithFilters(Writer writer) { - if (true) { - throw new UnsupportedOperationException("The student has not implemented this method yet."); - } + //if (true) { + //throw new UnsupportedOperationException("The student has not implemented this method yet."); + //} + /* * If you uncomment the following line (and get rid of th 3 previous lines...), you will restore the decoration * of the writer (connected to the file. You can see that you first decorate the writer with an UpperCaseFilterWriter, which you then * decorate with a FileNumberingFilterWriter. The resulting writer is used by the abstract class to write the characters read from the * input files. So, the input is first prefixed with line numbers, then transformed to uppercase, then sent to the output file.f + * + * => Done */ - //writer = new FileNumberingFilterWriter(new UpperCaseFilterWriter(writer)); + writer = new FileNumberingFilterWriter(new UpperCaseFilterWriter(writer)); return writer; } diff --git a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/FileTransformer.java b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/FileTransformer.java index bde833e8..9af4eeb0 100644 --- a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/FileTransformer.java +++ b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/FileTransformer.java @@ -51,7 +51,14 @@ public void visit(File file) { * There is a missing piece here: you have an input reader and an ouput writer (notice how the * writer has been decorated by the concrete subclass!). You need to write a loop to read the * characters and write them to the writer. + * + * => Done */ + int i; + + while((i = reader.read()) != -1){ + writer.write((char) i); + } reader.close(); writer.flush(); diff --git a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/NoOpFileTransformer.java b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/NoOpFileTransformer.java index 5971a302..4d460c9d 100644 --- a/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/NoOpFileTransformer.java +++ b/LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/transformers/NoOpFileTransformer.java @@ -13,14 +13,16 @@ public class NoOpFileTransformer extends FileTransformer { @Override public Writer decorateWithFilters(Writer writer) { - throw new UnsupportedOperationException("The student has not implemented this method yet."); + //throw new UnsupportedOperationException("The student has not implemented this method yet."); /* * The NoOpFileTransformer does not apply any transformation of the character stream * (no uppercase, no line number, etc.). So, we don't need to decorate the writer connected to * the output file at all. Just uncomment the following line and get rid of the UnsupportedOperationException and * you will be all set. + * + * => Done */ - //return writer; + return writer; } } diff --git a/LabJavaIO/src/main/java/ch/heigvd/res/labio/quotes/Quote.java b/LabJavaIO/src/main/java/ch/heigvd/res/labio/quotes/Quote.java index d02b320e..0c2eee61 100644 --- a/LabJavaIO/src/main/java/ch/heigvd/res/labio/quotes/Quote.java +++ b/LabJavaIO/src/main/java/ch/heigvd/res/labio/quotes/Quote.java @@ -1,5 +1,6 @@ package ch.heigvd.res.labio.quotes; + import lombok.Getter; import lombok.Setter;