Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TOREVIEW] Merk_Thurnherr #32

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e9434a0
Initial commit
melvinmerk Mar 5, 2021
d208f32
Initial commit
melvinmerk Mar 5, 2021
93ec3fe
Start of file exporer fix
melvinmerk Mar 5, 2021
f3f0b8c
File explorer passes test
melvinmerk Mar 5, 2021
1ef5b11
Removed unused imports
melvinmerk Mar 5, 2021
69266f8
Merge pull request #1 from melvinmerk/fb-fileexplorer
gab-thr Mar 5, 2021
64221f4
added sort
melvinmerk Mar 5, 2021
03fd726
Merge pull request #2 from melvinmerk/fb-fileexplorer
melvinmerk Mar 5, 2021
6c4c15b
First version of utils
melvinmerk Mar 12, 2021
70f854b
new utils version
melvinmerk Mar 12, 2021
925de59
add methods for storing quotes
gab-thr Mar 12, 2021
4e8ee86
update annotations
gab-thr Mar 12, 2021
f24c641
Uppercase file filter implementation
melvinmerk Mar 12, 2021
76ca956
file transformer impl
melvinmerk Mar 12, 2021
86fd66f
Merge pull request #3 from melvinmerk/fb-utils
melvinmerk Mar 19, 2021
3a836e2
Merge pull request #6 from melvinmerk/fb-uppercasefilewriter
melvinmerk Mar 19, 2021
f983edf
fixed comments
melvinmerk Mar 19, 2021
4b48f3c
fixed comments
melvinmerk Mar 19, 2021
30ad961
Merge pull request #7 from melvinmerk/fb-filetransformer
melvinmerk Mar 19, 2021
744ffba
Merge branch 'dev' into fb-application-test
melvinmerk Mar 19, 2021
ded9468
File number filter
melvinmerk Mar 19, 2021
b0a020e
implement FileNumberingFilterWriter
gab-thr Mar 21, 2021
235b060
handle broken single caracter writing
gab-thr Mar 21, 2021
f3ee02e
remove dead code
gab-thr Mar 21, 2021
f4db217
Merge pull request #8 from melvinmerk/fb-filenumberfilter
gab-thr Mar 21, 2021
335e651
Merge branch 'dev' into fb-application-test
gab-thr Mar 21, 2021
7b127cb
add Application functions
gab-thr Mar 21, 2021
741e278
Merge pull request #4 from melvinmerk/fb-application-test
melvinmerk Mar 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 16 additions & 19 deletions LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -92,12 +89,7 @@ public void fetchAndStoreQuotes(int numberOfQuotes) throws IOException {
e.printStackTrace();
}
if (quote != null) {
/* There is a missing piece here!
* As you can see, this method handles the first part of the lab. It uses the web service
* 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).
*/
storeQuote(quote, "quote-" + (i + 1) + ".utf8") ;
LOG.info("Received a new joke with " + quote.getTags().size() + " tags.");
for (String tag : quote.getTags()) {
LOG.info("> " + tag);
Expand Down Expand Up @@ -133,23 +125,29 @@ 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.");
String path = WORKSPACE_DIRECTORY + "/";
for (String tag : quote.getTags()) {
path += (tag + "/");
}

File file = new File(path);
file.mkdirs();
path += filename;
FileWriter writer = new FileWriter(path);
writer.write(quote.getQuote());
writer.close();
}

/**
* This method uses a IFileExplorer to explore the file system and prints the name of each
* encountered file and directory.
*/
void printFileNames(final Writer writer) {
void printFileNames(final Writer writer) throws IOException {
IFileExplorer explorer = new DFSFileExplorer();
explorer.explore(new File(WORKSPACE_DIRECTORY), new IFileVisitor() {
@Override
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).
*/
public void visit(File file) throws IOException {
writer.write(file.getPath()+"\n");
}
});
}
Expand All @@ -159,5 +157,4 @@ public void processQuoteFiles() throws IOException {
IFileExplorer explorer = new DFSFileExplorer();
explorer.explore(new File(WORKSPACE_DIRECTORY), new CompleteFileTransformer());
}

}
25 changes: 23 additions & 2 deletions LabJavaIO/src/main/java/ch/heigvd/res/labio/impl/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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[] array = new String[2];

array[0] = "";
array[1] = lines; // Set default result if no new line separator

for(int i = 0; i < lines.length(); i++) {
char c = lines.charAt(i);

if(c == '\n' || c == '\r') {
if(c == '\r' && i < lines.length()-1) { // Handle \r\n
if(lines.charAt(i+1) == '\n') {
array[0] = lines.substring(0, i+2);
array[1] = lines.substring(i+2);
break;
}
}
array[0] = lines.substring(0, i+1);
array[1] = lines.substring(i+1);
break;
}
}

return array;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import ch.heigvd.res.labio.interfaces.IFileVisitor;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;

/**
* This implementation of the IFileExplorer interface performs a depth-first
Expand All @@ -16,8 +19,15 @@
public class DFSFileExplorer implements IFileExplorer {

@Override
public void explore(File rootDirectory, IFileVisitor vistor) {
throw new UnsupportedOperationException("The student has not implemented this method yet.");
}
public void explore(File rootDirectory, IFileVisitor visitor) throws IOException {

visitor.visit(rootDirectory);
if(rootDirectory.isDirectory()) { // Only recurse if rootDirectory is a directory
String[] paths = Objects.requireNonNull(rootDirectory.list());
Arrays.sort(paths); // Sort the arrays so it is alphabetical order on every os
for (String filePath : paths) {
explore(new File(rootDirectory + "/" + filePath), visitor);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ch.heigvd.res.labio.impl.filters;

import ch.heigvd.res.labio.impl.Utils;

import java.io.FilterWriter;
import java.io.IOException;
import java.io.Writer;
Expand All @@ -11,31 +13,74 @@
* It then sends the line number and a tab character, before resuming the write
* process.
*
* Hello\n\World -> 1\Hello\n2\tWorld
* Hello\n\World -> 1\tHello\n2\tWorld
*
* @author Olivier Liechti
*/
public class FileNumberingFilterWriter extends FilterWriter {

private static final Logger LOG = Logger.getLogger(FileNumberingFilterWriter.class.getName());
private int lineNumber = 1; // lines are numbered from 1 not 0
private boolean hasSeenCarriageReturn = 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.");

/*
* This function writes the input string to the output, recursing if the given string contains multiple newline-
* separated parts. We can establish whether recursion is required using Utils.getNextLine. Additionally, if the
* given string ends with a newline, we write the next line number already, not at the next call of this function.
*/
if (lineNumber == 1) out.write(lineNumber++ + "\t"); // handle initial write
String substr = str.substring(off, off + len);
String[] lines = Utils.getNextLine(substr);

if (!lines[0].equals("") && !lines[1].equals("")) {
out.write(lines[0], 0, lines[0].length());
out.write(lineNumber++ + "\t"); // already write next line number + tab before recursing
this.write(lines[1]);
} else if (!lines[0].equals("")) {
out.write(lines[0], 0, lines[0].length());
out.write(lineNumber++ + "\t"); // same here, write next line number + tab already.
} else if (!lines[1].equals("")) {
out.write(lines[1], 0, lines[1].length());
}

}

@Override
public void write(char[] cbuf, int off, int len) throws IOException {
throw new UnsupportedOperationException("The student has not implemented this method yet.");
// just use our recursive String implementation
this.write(new String(cbuf), off, len);
}

@Override
public void write(int c) throws IOException {
throw new UnsupportedOperationException("The student has not implemented this method yet.");
// Write the character, but when we encounter a carriage return we need to "remember" that we saw it, to handle all
// possible newline permutations (\r, \r\n and \n) correctly.
if (lineNumber == 1) out.write(lineNumber++ + "\t");

if (hasSeenCarriageReturn) { // if we saw a carriage return before
if (c == '\n') { // if newline, write newline then next line number
out.write(c);
out.write(lineNumber++ + "\t");
} else { // otherwise, write next line number before writing the character
out.write(lineNumber++ + "\t");
out.write(c);
}
hasSeenCarriageReturn = c == '\r';
} else { // otherwise, handle single newlines without carriage return
out.write(c);
if (c == '\n') {
out.write(lineNumber++ + "\t");
} else {
hasSeenCarriageReturn = c == '\r';
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@ 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.");
super.write(str.substring(0, off) + str.substring(off, off+len).toUpperCase(), 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 = off; i < off+len; i++) {
cbuf[i] = Character.toUpperCase(cbuf[i]);
}
super.write(cbuf, off, len);
}

@Override
public void write(int c) throws IOException {
throw new UnsupportedOperationException("The student has not implemented this method yet.");
super.write(Character.toUpperCase(c));
}

}
Original file line number Diff line number Diff line change
@@ -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;

/**
Expand All @@ -15,16 +18,13 @@ 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 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
* input files. So, the input is first prefixed with line numbers, then transformed to uppercase, then sent to the output file.
*/
//writer = new FileNumberingFilterWriter(new UpperCaseFilterWriter(writer));
writer = new FileNumberingFilterWriter(new UpperCaseFilterWriter(writer));
return writer;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ public void visit(File file) {
Writer writer = new OutputStreamWriter(new FileOutputStream(file.getPath()+ ".out"), StandardCharsets.UTF_8); // the bug fix by teacher
writer = decorateWithFilters(writer);

/*
* 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.
*/
// buffered reader for performance
BufferedReader bufferedReader = new BufferedReader(reader);

int c;
while((c = bufferedReader.read()) != -1) {
writer.write(c);
}

reader.close();
writer.flush();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ public class NoOpFileTransformer extends FileTransformer {

@Override
public Writer decorateWithFilters(Writer writer) {
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.
* the output file at all.
*/
//return writer;
return writer;
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ch.heigvd.res.labio.interfaces;

import java.io.File;
import java.io.IOException;

/**
* This interface is used to perform one operation on each element (file and
Expand All @@ -23,6 +24,6 @@ public interface IFileExplorer {
* @param rootDirectory the directory where to start the traversal
* @param vistor defines the operation to be performed on each file
*/
public void explore(File rootDirectory, IFileVisitor vistor);
public void explore(File rootDirectory, IFileVisitor vistor) throws IOException;

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ch.heigvd.res.labio.interfaces;

import java.io.File;
import java.io.IOException;

/**
* This interface is used together with the IFileExplorer interface. It defines
Expand All @@ -18,6 +19,6 @@ public interface IFileVisitor {
*
* @param file the current file or directory visited by the IFileExplorer instance
*/
public void visit(File file);
public void visit(File file) throws IOException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class DFSFileExplorerTest {
private static final Logger LOG = Logger.getLogger(DFSFileExplorerTest.class.getName());

@Test
public void dfsExplorerShouldWork() {
public void dfsExplorerShouldWork() throws IOException {
List<String> dfsNodes = generateTestTree(5, 5, 5);

final List<String> directories = new ArrayList<>();
Expand All @@ -39,7 +39,7 @@ public void visit(File file) {
}

@Test
public void dfsExplorerShouldWorkWhenThereIsNoFile() {
public void dfsExplorerShouldWorkWhenThereIsNoFile() throws IOException {
List<String> dfsNodes = generateTestTree(0, 0, 0);

final List<String> directories = new ArrayList<>();
Expand Down