Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
66ae61e
initial commit
pozniako16 Mar 5, 2021
9ac7899
le parcours bfs a été mis en place. Il pourra être vérifier plus tard…
AxelVallon Mar 5, 2021
8159952
Did the uppercase filter
pozniako16 Mar 5, 2021
9bddfce
did the uppercase filter
pozniako16 Mar 5, 2021
93aa97a
Merge branch 'lab1' of github.com:pozniako16/https-github.com-SoftEng…
pozniako16 Mar 5, 2021
ea1527c
Merge pull request #1 from pozniako16/feat/filters
pozniako16 Mar 5, 2021
87c2da3
NoOpFile and CompleteFile done, mis content of FileTransformer, I pus…
AxelVallon Mar 5, 2021
e70cb8b
started the implementation
pozniako16 Mar 5, 2021
c751999
fix visitor, now pass the tests
AxelVallon Mar 9, 2021
4ad3e22
create loop to copy data from reader to writer
AxelVallon Mar 9, 2021
b68acbb
change writer position, before reader
AxelVallon Mar 9, 2021
bbf7056
Merge pull request #2 from pozniako16/fb-transformer
pozniako16 Mar 9, 2021
59f7818
Merge pull request #3 from pozniako16/fb-visitor
pozniako16 Mar 9, 2021
ac111a5
Revert "Fb visitor"
pozniako16 Mar 9, 2021
551275b
Merge pull request #4 from pozniako16/revert-3-fb-visitor
pozniako16 Mar 9, 2021
242fe55
Merge pull request #5 from pozniako16/fb-visitor
pozniako16 Mar 9, 2021
ac2f2b7
test
pozniako16 Mar 9, 2021
0872daf
Merge branch 'lab1' of github.com:pozniako16/https-github.com-SoftEng…
pozniako16 Mar 9, 2021
7e85c3e
Fixed numberingFilter, need comments
pozniako16 Mar 9, 2021
6ade161
Merge pull request #6 from pozniako16/feat/FileNumberingFilterWriter
pozniako16 Mar 9, 2021
4fd18b6
to push branch
pozniako16 Mar 9, 2021
c341cf1
cleared utils test
pozniako16 Mar 9, 2021
1aea633
Merge branch 'master' into feat/Utils
pozniako16 Mar 9, 2021
ad482e6
Merge pull request #12 from pozniako16/feat/Utils
pozniako16 Mar 9, 2021
eaa3881
Revert "Feat/utils"
pozniako16 Mar 9, 2021
be65ec2
Revert "Feat/file numbering filter writer"
pozniako16 Mar 9, 2021
b9ea8ac
Merge pull request #14 from pozniako16/revert-6-feat/FileNumberingFil…
pozniako16 Mar 9, 2021
4a172bf
Merge pull request #13 from pozniako16/revert-12-feat/Utils
pozniako16 Mar 9, 2021
c0d7de2
Revert "fix visitor, now pass the tests"
pozniako16 Mar 9, 2021
a17164a
Merge pull request #15 from pozniako16/revert-5-fb-visitor
pozniako16 Mar 9, 2021
fee5c55
fixing git
pozniako16 Mar 9, 2021
f96067a
Merge pull request #16 from pozniako16/fb-visitor
pozniako16 Mar 9, 2021
7030f9a
fixing git
pozniako16 Mar 9, 2021
dd83ae6
Merge pull request #17 from pozniako16/feat/FileNumberingFilterWriter
pozniako16 Mar 9, 2021
5ad5216
fixing git
pozniako16 Mar 9, 2021
d20ab11
Merge branch 'feat/Utils' of github.com:pozniako16/https-github.com-S…
pozniako16 Mar 9, 2021
e2220f6
Merge pull request #18 from pozniako16/feat/Utils
pozniako16 Mar 9, 2021
6bbbe02
update utils
pozniako16 Mar 9, 2021
3579ea2
Refix git
pozniako16 Mar 9, 2021
8744c49
Application effectué et les tests sont valide, et fix bug sur visitor…
AxelVallon Mar 12, 2021
973334e
nothing
pozniako16 Mar 17, 2021
d3aecb9
Added the commentaries and did final check
pozniako16 Mar 19, 2021
a8d8f09
Merge pull request #20 from pozniako16/final/Commentaries
pozniako16 Mar 19, 2021
97fa85f
woopsy daisy zappé des trucs
pozniako16 Mar 19, 2021
dce8afa
Merge pull request #21 from pozniako16/final/Commentaries
pozniako16 Mar 19, 2021
bd9dfcd
maj comments
AxelVallon Mar 19, 2021
360ebfd
fixed problem with string init in application
pozniako16 Mar 23, 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
276 changes: 140 additions & 136 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,155 +9,159 @@
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.nio.charset.StandardCharsets;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author Olivier Liechti
*/
public class Application implements IApplication {

/**
* This constant defines where the quotes will be stored. The path is relative
* 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
/**
* This constant defines where the quotes will be stored. The path is relative
* to where the Java application is invoked.
*/
System.setProperty("java.util.logging.SimpleFormatter.format", "%4$s: %5$s%6$s%n");


int numberOfQuotes = 0;
try {
numberOfQuotes = Integer.parseInt(args[0]);
} catch (Exception e) {
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();
}
}

@Override
public void fetchAndStoreQuotes(int numberOfQuotes) throws IOException {
clearOutputDirectory();
QuoteClient client = new QuoteClient();
for (int i = 0; i < numberOfQuotes; i++) {
Quote quote = null;
try {
quote = client.fetchQuote();
} catch (URISyntaxException | InterruptedException e) {
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).
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
*/
LOG.info("Received a new joke with " + quote.getTags().size() + " tags.");
for (String tag : quote.getTags()) {
LOG.info("> " + tag);
System.setProperty("java.util.logging.SimpleFormatter.format", "%4$s: %5$s%6$s%n");


int numberOfQuotes = 0;
try {
numberOfQuotes = Integer.parseInt(args[0]);
} catch (Exception e) {
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();
}
}

@Override
public void fetchAndStoreQuotes(int numberOfQuotes) throws IOException {
clearOutputDirectory();
QuoteClient client = new QuoteClient();
for (int i = 0; i < numberOfQuotes; i++) {
Quote quote = null;
try {
quote = client.fetchQuote();
} catch (URISyntaxException | InterruptedException e) {
e.printStackTrace();
}
if (quote != null) {
//ajout de la quote avec son nom correct
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);
}
}

}
}

/**
* 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
*/
void clearOutputDirectory() throws IOException {
FileUtils.deleteDirectory(new File(WORKSPACE_DIRECTORY));
}

/**
* This method stores the content of a quote in the local file system. It has
* 2 responsibilities:
* <p>
* - 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.
* <p>
* - 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
*/
void storeQuote(Quote quote, String filename) throws IOException {
String tmp = "";
for (String tag : quote.getTags())
tmp += "/" + tag;
tmp += "/";
File f = new File(WORKSPACE_DIRECTORY + tmp, filename);
f.getParentFile().mkdirs();//crée tous le path d'un seul coup

//utilisation sur Stream pour forcer l'UTF-8
BufferedWriter writer =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), StandardCharsets.UTF_8));
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) {
IFileExplorer explorer = new DFSFileExplorer();
explorer.explore(new File(WORKSPACE_DIRECTORY), new IFileVisitor() {
@Override
public void visit(File file) {
try {
writer.write(file.getPath().replace('\\', '/') + '\n'); // fix problème path windows
} catch (IOException e) {
e.printStackTrace();
}
}
});
}

@Override
public void processQuoteFiles() throws IOException {
IFileExplorer explorer = new DFSFileExplorer();
explorer.explore(new File(WORKSPACE_DIRECTORY), new CompleteFileTransformer());
}
}

/**
* 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
*/
void clearOutputDirectory() throws IOException {
FileUtils.deleteDirectory(new File(WORKSPACE_DIRECTORY));
}

/**
* This method stores the content of a quote in the local file system. It has
* 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
*/
void storeQuote(Quote quote, String filename) throws IOException {
throw new UnsupportedOperationException("The student has not implemented this method yet.");
}

/**
* 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) {
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).
*/
}
});
}

@Override
public void processQuoteFiles() throws IOException {
IFileExplorer explorer = new DFSFileExplorer();
explorer.explore(new File(WORKSPACE_DIRECTORY), new CompleteFileTransformer());
}

}
30 changes: 28 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 @@ -5,6 +5,7 @@
/**
*
* @author Olivier Liechti
* Modified by: Lev Pozniakoff
*/
public class Utils {

Expand All @@ -20,7 +21,32 @@ 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.");
}
boolean foundSeparator = false;
int limitIndex = 0;
for (int i = 0; i < lines.length() && !foundSeparator; ++i) {
if (lines.charAt(i) == '\r') {
if (i <= lines.length() - 2 && lines.charAt(i + 1) == '\n')
++i;
else {
foundSeparator = true;
limitIndex = i;
}
}
if (lines.charAt(i) == '\n') {
foundSeparator = true;
limitIndex = i;
}
}

String[] output = {"", ""};
if (limitIndex == lines.length() - 1)
output[0] = lines;
else if (!foundSeparator)
output[1] = lines;
else {
output[0] = lines.substring(0, limitIndex+1);
output[1] = lines.substring(limitIndex+1);
}
return output;
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
package ch.heigvd.res.labio.impl.explorers;

import ch.heigvd.res.labio.interfaces.IFileExplorer;
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
* exploration of the file system and invokes the visitor for every encountered
* node (file and directory). When the explorer reaches a directory, it visits all
* files in the directory and then moves into the subdirectories.
*
*
*
* @author Olivier Liechti
*/
public class DFSFileExplorer implements IFileExplorer {

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

@Override
public void explore(File rootDirectory, IFileVisitor vistor) {
//on visite tous les fichiers (même les repos)
vistor.visit(rootDirectory);
//on récupère la liste des fichiers et répertoire enfant
File[] listOfFileAndDir = rootDirectory.listFiles();
if (listOfFileAndDir == null) //si pas d'enfant, on quitte
return;
Arrays.sort(listOfFileAndDir);
for (File file : listOfFileAndDir) {
explore(file, vistor); //si on a un repertoire, on le visite
}
}
}
Loading