I have the following Main
class:
public class Main {
public static void main(String[] args) {
try {
MessageWriter writer = null;
if (args.length < 1) {
throw new IllegalArgumentException("There is no input file path");
} else if (args.length == 1) {
writer = new ConsoleMessageWriter();
} else {
writer = new FileMessageWriter(args[1]);
}
CompressingMessageWrite compressingMessageWrite = new CompressingMessageWrite(writer);
FileMessageReader fileMessageReader = new FileMessageReader(args[0]);
int numberOfMessages = fileMessageReader.getNumberOfMessages();
int loopCounter = (numberOfMessages % 2 == 0) ? numberOfMessages : numberOfMessages - 1;
if (numberOfMessages < 1) {
return;
}
for (int i = 0; i < loopCounter / 2; i++) {
Message message1 = fileMessageReader.readMessage();
Message message2 = fileMessageReader.readMessage();
compressingMessageWrite.writeMessages(message1, message2);
}
if (loopCounter != numberOfMessages) {
Message message = fileMessageReader.readMessage();
compressingMessageWrite.writeMessage(message);
}
} catch (IllegalMessageFormatException | IOException e){
System.out.println(e.getMessage());
}
}
}
My professor says that I don't close any files in the Main
class. I don't understand the files to which he's referring.
Note: Classes FileMessageWriter
and FileMessageReader
works with files using try-with-resources statement
, like this:
try (FileReader file = new FileReader(messageFilePath);
BufferedReader reader = new BufferedReader(file)) {
String line;
while ((line = reader.readLine()) != null) {
//work with line
}
}
FileMessageReader.java:
/**
* Reading messages from file
*/
public class FileMessageReader {
private static final int UndefinedNumberOfLines = -1;
private int lastReadStringNumber = 0;
private final String messageFilePath;
/**
* Constructs a new FileMessageReader with specific <code>filePath</code>.
* @param filePath file with messages
* @throws FileNotFoundException if given file does not exist
*/
public FileMessageReader(String filePath) throws FileNotFoundException {
if (filePath == null)
{
throw new IllegalArgumentException("filePath is null");
}
File f = new File(filePath);
if (!f.exists() || f.isDirectory()) {
throw new FileNotFoundException("file" + filePath + " not found.");
}
messageFilePath = filePath;
}
/**
* Reading next message from a file
* @return Read message
* @throws IllegalMessageFormatException if message has illegal format
* @throws java.io.IOException If an input or output exception occurred
*/
public Message readMessage() throws IllegalMessageFormatException, IOException {
int currentLine = 0;
Message message = new Message();
try (FileReader file = new FileReader(messageFilePath);
BufferedReader reader = new BufferedReader(file)) {
String line;
int numberLinesInMessage = UndefinedNumberOfLines;
for(int i = 0; i < lastReadStringNumber; i++) {
reader.readLine();
currentLine++;
}
while ((line = reader.readLine()) != null) {
if (numberLinesInMessage == UndefinedNumberOfLines) {
if (isInteger(line)) {
numberLinesInMessage = Integer.parseInt(line);
} else {
throw new IllegalMessageFormatException("line is not a number");
}
} else if (numberLinesInMessage > 0) {
message.append(line);
numberLinesInMessage--;
}
currentLine++;
if (numberLinesInMessage == 0) {
lastReadStringNumber = currentLine;
return message;
}
}
if (numberLinesInMessage > 0) {
throw new IllegalMessageFormatException("Message has less lines than is specified.");
}
} catch (FileNotFoundException e) {
throw new FileNotFoundException("file" + messageFilePath + " not found.");
} catch (IOException e) {
throw new IOException("Strange IOException happened. Message: " + e.getMessage());
}
lastReadStringNumber = currentLine;
return message;
}
/**
* @return number of messages in file
* @throws IllegalMessageFormatException if message has illegal format
* @throws java.io.IOException If an input or output exception occurred
*/
public int getNumberOfMessages() throws IllegalMessageFormatException, IOException {
int numberOfMessages = 0;
try (FileReader file = new FileReader(messageFilePath);
BufferedReader reader = new BufferedReader(file)) {
String line;
int numberLinesInMessage = UndefinedNumberOfLines;
while ((line = reader.readLine()) != null) {
if (numberLinesInMessage == UndefinedNumberOfLines) {
if (isInteger(line)) {
numberLinesInMessage = Integer.parseInt(line);
} else {
throw new IllegalMessageFormatException("line is not a number");
}
} else if (numberLinesInMessage > 0) {
numberLinesInMessage--;
}
if (numberLinesInMessage == 0) {
numberOfMessages++;
numberLinesInMessage = UndefinedNumberOfLines;
}
}
if (numberLinesInMessage > 0) {
throw new IllegalMessageFormatException("Message has less lines than is specified.");
}
} catch (FileNotFoundException e) {
throw new FileNotFoundException("file" + messageFilePath + " not found.");
} catch (IOException e) {
throw new IOException("Strange IOException happened. Message: " + e.getMessage());
}
return numberOfMessages;
}
private static boolean isInteger(String s) throws IllegalMessageFormatException {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
throw new IllegalMessageFormatException("line is not a number");
}
return true;
}
}
CompressingMessageWrite.java:
/**
* Compress messages to input
*/
public class CompressingMessageWrite implements MessageWriter {
private final MessageWriter writer;
/**
* Constructs a new CompressingMessageWrite with specific <code>writer</code>.
* @param writer which is used for writing to some input
*/
public CompressingMessageWrite(MessageWriter writer) {
if (writer == null) {
throw new IllegalArgumentException("writer is null");
}
this.writer = writer;
}
/**
* Write message to input
* @param message which will be wrote
*/
@Override
public void writeMessage(Message message) {
if (message == null) {
throw new IllegalArgumentException("message is null");
}
writer.writeMessage(message);
}
/**
* Write messages to input
* @param message1 which will be wrote
* @param message2 which will be wrote
*/
public void writeMessages(Message message1, Message message2) {
if (message1 == null) {
throw new IllegalArgumentException("message1 is null");
}
if (message2 == null) {
throw new IllegalArgumentException("message2 is null");
}
Message resultMessage = new Message();
resultMessage.append(message1);
resultMessage.append(message2);
writer.writeMessage(resultMessage);
}
}
Message.java:
/**
* Message class
*/
public class Message {
private final List<String> lines = new ArrayList<>();
private final StringBuilder stringBuilder = new StringBuilder();
/**
* Adding <code>line</code> to this message
* @param line which adding to this message
*/
public void append(String line) {
if (line == null) {
throw new IllegalArgumentException("line is null");
}
lines.add(line);
}
/**
* Adding <code>message</code> to this message
* @param message added message
*/
public void append(Message message) {
if (message == null) {
throw new IllegalArgumentException("message is null");
}
message.getLines().forEach(this::append);
}
/**
* @return list of message lines
*/
public List<String> getLines() {
return Collections.unmodifiableList(lines);
}
/**
* @return String representation of Message
*/
@Override
public String toString() {
stringBuilder.append(getLines().size());
stringBuilder.append(System.lineSeparator());
for (String msg : lines)
{
stringBuilder.append(msg);
stringBuilder.append(System.lineSeparator());
}
stringBuilder.setLength(0);
return stringBuilder.toString();
}
}
MessageWritter.java:
/**
* Interface for writing of messages
*/
public interface MessageWriter {
/**
* Write message in source
* @param message which will be wrote
*/
public void writeMessage(Message message);
}
FileMessageWritter.java:
/**
* Write messages to file
*/
public class FileMessageWriter implements MessageWriter {
private final String messageFilePath;
/**
* Constructs a new FileMessageWriter with specific <code>filePath</code>.
* @param filePath file for messages
* @throws FileNotFoundException if given file does not exist
*/
public FileMessageWriter(String filePath) throws FileNotFoundException {
if (filePath == null)
{
throw new IllegalArgumentException("filePath is null");
}
File f = new File(filePath);
if (!f.exists() || f.isDirectory()) {
throw new FileNotFoundException("file" + filePath + " not found.");
}
messageFilePath = filePath;
}
/**
* Write message to console
* @param message which will be wrote
*/
@Override
public void writeMessage(Message message) {
if (message == null) {
throw new IllegalArgumentException("message is null");
}
try (FileWriter fileWriter = new FileWriter(messageFilePath, true);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
PrintWriter out = new PrintWriter(bufferedWriter)) {
out.print(message);
} catch (IOException e) {
throw new RuntimeException("Strange IOException happened. Message: " + e.getMessage());
}
}
}
MessageWriter
interface, and the other missing classes, likeMessage
\$\endgroup\$