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 ad87a7d..3992e12 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 @@ -7,10 +7,8 @@ import ch.heigvd.res.labio.interfaces.IFileVisitor; import ch.heigvd.res.labio.quotes.QuoteClient; import ch.heigvd.res.labio.quotes.Quote; -import java.io.File; -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; + +import java.io.*; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.io.FileUtils; @@ -26,19 +24,19 @@ public class Application implements IApplication { * to where the Java application is invoked. */ public static String WORKSPACE_DIRECTORY = "./workspace/quotes"; - + private static final Logger LOG = Logger.getLogger(Application.class.getName()); - + public static void main(String[] args) { - + /* * I prefer to have LOG output on a single line, it's easier to read. Being able * to change the formatting of console outputs is one of the reasons why it is * better to use a Logger rather than using System.out.println */ System.setProperty("java.util.logging.SimpleFormatter.format", "%4$s: %5$s%6$s%n"); - - + + int numberOfQuotes = 0; try { numberOfQuotes = Integer.parseInt(args[0]); @@ -46,32 +44,32 @@ public static void main(String[] args) { System.err.println("The command accepts a single numeric argument (number of quotes to fetch)"); System.exit(-1); } - + Application app = new Application(); try { /* * Step 1 : clear the output directory */ app.clearOutputDirectory(); - + /* * Step 2 : use the QuotesClient to fetch quotes; store each quote in a file */ app.fetchAndStoreQuotes(numberOfQuotes); - + /* * Step 3 : use a file explorer to traverse the file system; print the name of each directory and file */ Writer writer = new StringWriter(); // we create a special writer that will send characters into a string (memory) app.printFileNames(writer); // we hand over this writer to the printFileNames method LOG.info(writer.toString()); // we dump the whole result on the console - + /* * Step 4 : process the quote files, by applying 2 transformations to their content * (convert to uppercase and add line numbers) */ app.processQuoteFiles(); - + } catch (IOException ex) { LOG.log(Level.SEVERE, "Could not fetch quotes. {0}", ex.getMessage()); ex.printStackTrace(); @@ -90,42 +88,56 @@ public void fetchAndStoreQuotes(int numberOfQuotes) throws IOException { * 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). */ + storeQuote(quote,"quote-"+quote.getValue().getId()); LOG.info("Received a new joke with " + quote.getTags().size() + " tags."); for (String tag : quote.getTags()) { LOG.info("> " + tag); } } } - + /** * This method deletes the WORKSPACE_DIRECTORY and its content. It uses the * apache commons-io library. You should call this method in the main method. - * - * @throws IOException + * + * @throws IOException */ void clearOutputDirectory() throws IOException { - FileUtils.deleteDirectory(new File(WORKSPACE_DIRECTORY)); + FileUtils.deleteDirectory(new File(WORKSPACE_DIRECTORY)); } /** * This method stores the content of a quote in the local file system. It has - * 2 responsibilities: - * + * 2 responsibilities: + * * - with quote.getTags(), it gets a list of tags and uses * it to create sub-folders (for instance, if a quote has three tags "A", "B" and * "C", it will be stored in /quotes/A/B/C/quotes-n.utf8. - * + * * - with quote.getQuote(), it has access to the text of the quote. It stores * this text in UTF-8 file. - * + * * @param quote the quote object, with tags and text * @param filename the name of the file to create and where to store the quote text - * @throws IOException + * @throws IOException */ void storeQuote(Quote quote, String filename) throws IOException { - throw new UnsupportedOperationException("The student has not implemented this method yet."); + String path = WORKSPACE_DIRECTORY + "/"; + for(String c : quote.getTags()){ + path += c +"/"; + } + File newDir = new File(path); + newDir.mkdirs(); + + path += filename +".utf8"; + + File newFile = new File(path); + newFile.createNewFile(); + FileOutputStream writeFile = new FileOutputStream(newFile); + writeFile.write((quote.getQuote().getBytes())); + writeFile.close(); } - + /** * This method uses a IFileExplorer to explore the file system and prints the name of each * encountered file and directory. @@ -140,6 +152,11 @@ public void visit(File file) { * 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). */ + try { + writer.write(file.getPath()+"\n"); + } catch (IOException exception){ + System.err.println("Error in file visit"); + } } }); } @@ -147,7 +164,7 @@ public void visit(File file) { @Override public void processQuoteFiles() throws IOException { IFileExplorer explorer = new DFSFileExplorer(); - explorer.explore(new File(WORKSPACE_DIRECTORY), new CompleteFileTransformer()); + explorer.explore(new File(WORKSPACE_DIRECTORY), new CompleteFileTransformer()); } } 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 c8a3a5a..09af669 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 @@ -20,7 +20,28 @@ public class Utils { * 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."); + String[] result = new String[2]; + result[0] = ""; + result[1] = ""; + boolean isWindowsNewLine = false; + boolean nextLineOk = false; + for(int i = 0; i < lines.length();i++){ + if(nextLineOk) { + result[1] += lines.charAt(i); + }else{ + result[0] += lines.charAt(i); + if(lines.charAt(i) == '\n'){ + nextLineOk = true; + } + if(lines.charAt(i) == '\r' && ((i+1 < lines.length())&&(lines.charAt(i+1)!= '\n')||(i == lines.length()-1))){ + nextLineOk = true; + } + } + } + if(nextLineOk == false){ + result[1] = result[0]; + result[0] = ""; + } + return result; } - } 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 83f8e61..d3df0e8 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 @@ -3,6 +3,9 @@ import ch.heigvd.res.labio.interfaces.IFileExplorer; import ch.heigvd.res.labio.interfaces.IFileVisitor; import java.io.File; +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.Objects; /** * This implementation of the IFileExplorer interface performs a depth-first @@ -16,7 +19,14 @@ 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); + if(!rootDirectory.isDirectory()){ + return; + } + File[] files = Objects.requireNonNull(rootDirectory.listFiles()); + Arrays.sort(files); + for(File file : files) { + explore(file, vistor); + } } - } 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 976c946..b0d9370 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 @@ -18,24 +18,44 @@ public class FileNumberingFilterWriter extends FilterWriter { private static final Logger LOG = Logger.getLogger(FileNumberingFilterWriter.class.getName()); - + int nbLine = 1; + boolean isNewLine = true; + boolean isWindowsNewLine = false; public FileNumberingFilterWriter(Writer out) { super(out); } @Override public void write(String str, int off, int len) throws IOException { - throw new UnsupportedOperationException("The student has not implemented this method yet."); + write(str.toCharArray(),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