more detailed error messages, recursion prevention, stacktrace doesn't print on error anymore, xml fix, some other minor fixes
This commit is contained in:
parent
e36983b378
commit
5a3877c86b
11 changed files with 141 additions and 46 deletions
|
@ -15,7 +15,7 @@ public class Lab5 {
|
|||
try {
|
||||
peopleDatabase.load();
|
||||
} catch (Database.DatabaseLoadFailedException e) {
|
||||
System.out.println("Не удалось загрузить коллекцию из файла");
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
PeopleDatabaseCommands.setPeopleDatabase(peopleDatabase);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.util.TreeSet;
|
|||
|
||||
/**
|
||||
* Класс базы данных людей, реализующий интерфейс Database
|
||||
*
|
||||
* @see ru.erius.lab5.collection.Database
|
||||
*/
|
||||
@XmlRootElement
|
||||
|
@ -33,9 +34,14 @@ public class PeopleDatabase implements Database {
|
|||
private JAXBContext context;
|
||||
@XmlTransient
|
||||
private File file;
|
||||
@Getter @XmlElement(name = "person")
|
||||
@XmlTransient
|
||||
private String errorMessage;
|
||||
@Getter
|
||||
@XmlElement(name = "person")
|
||||
private TreeSet<Person> collection = new TreeSet<>();
|
||||
@Getter @XmlJavaTypeAdapter(LocalDateAdapter.class) @XmlElement(name = "initDate")
|
||||
@Getter
|
||||
@XmlJavaTypeAdapter(LocalDateAdapter.class)
|
||||
@XmlElement(name = "initDate")
|
||||
private LocalDate initDate = LocalDate.now();
|
||||
|
||||
{
|
||||
|
@ -65,20 +71,28 @@ public class PeopleDatabase implements Database {
|
|||
System.out.println("Инициализация коллекции из файла...");
|
||||
|
||||
String path = System.getenv(ENV_VAR);
|
||||
if (path == null)
|
||||
if (path == null) {
|
||||
errorMessage = "Не найдена переменная окружения LAB5_PATH";
|
||||
throw new DatabaseLoadFailedException("Не найдена переменная окружения LAB5_PATH");
|
||||
file = new File(path);
|
||||
}
|
||||
File file = new File(path);
|
||||
|
||||
if (!file.exists())
|
||||
throw new DatabaseLoadFailedException("Файл %s не был найден. Поменяйте значение переменной окружения LAB5_PATH", path);
|
||||
if (!file.canRead())
|
||||
throw new DatabaseLoadFailedException("У вас нет прав на чтение файла %s", path);
|
||||
if (!file.canWrite())
|
||||
throw new DatabaseLoadFailedException("У вас нет прав на запись в файл %s", path);
|
||||
if (file.isFile())
|
||||
System.out.println("Файл успешно найден");
|
||||
else
|
||||
if (!file.exists()) {
|
||||
errorMessage = String.format("Файл %s не был найден. Поменяйте значение переменной окружения LAB5_PATH", path);
|
||||
throw new DatabaseLoadFailedException(errorMessage);
|
||||
}
|
||||
if (file.isDirectory())
|
||||
file = createFile(file);
|
||||
if (!file.canRead()) {
|
||||
errorMessage = String.format("У вас нет прав на чтение файла %s", path);
|
||||
throw new DatabaseLoadFailedException(errorMessage);
|
||||
}
|
||||
if (!file.canWrite()) {
|
||||
errorMessage = String.format("У вас нет прав на запись в файл %s", path);
|
||||
throw new DatabaseLoadFailedException(errorMessage);
|
||||
}
|
||||
this.file = file;
|
||||
System.out.println("Файл успешно найден");
|
||||
|
||||
try {
|
||||
Unmarshaller unmarshaller = context.createUnmarshaller();
|
||||
|
@ -87,7 +101,8 @@ public class PeopleDatabase implements Database {
|
|||
this.initDate = pd.initDate;
|
||||
System.out.println("Инициализация успешно выполнена");
|
||||
} catch (JAXBException e) {
|
||||
throw new DatabaseLoadFailedException("Не удалось загрузить коллекцию из файла %s", file.getPath(), e);
|
||||
e.printStackTrace();
|
||||
throw new DatabaseLoadFailedException("Не удалось загрузить коллекцию из файла %s, он пуст, либо нарушена структура xml", file.getPath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,13 +117,13 @@ public class PeopleDatabase implements Database {
|
|||
@Override
|
||||
public void save() throws Database.DatabaseSaveFailedException {
|
||||
if (file == null || context == null)
|
||||
throw new DatabaseSaveFailedException("Не удалось сохранить коллекцию");
|
||||
throw new DatabaseSaveFailedException("Не удалось сохранить коллекцию, " + errorMessage);
|
||||
try {
|
||||
Marshaller marshaller = context.createMarshaller();
|
||||
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
|
||||
marshaller.marshal(this, file);
|
||||
} catch (JAXBException e) {
|
||||
throw new DatabaseSaveFailedException("Не удалось сохранить коллекцию в файл %s", file.getPath(), e);
|
||||
throw new DatabaseSaveFailedException("Не удалось сохранить коллекцию в файл %s, формат xml файла был нарушен", file.getPath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.io.*;
|
|||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Класс обработчика командной строки, реализует шаблон проектирования Singleton,
|
||||
|
@ -19,6 +20,7 @@ public final class CommandLineHandler {
|
|||
private final static CommandLineHandler instance = new CommandLineHandler();
|
||||
|
||||
private final Deque<Reader> inputs = new LinkedList<>();
|
||||
private final Deque<String> fileNames = new LinkedList<>();
|
||||
private final List<String> history = new LinkedList<>();
|
||||
private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
||||
private boolean isActive = false;
|
||||
|
@ -128,7 +130,7 @@ public final class CommandLineHandler {
|
|||
System.out.println("Что-то пошло не так");
|
||||
return;
|
||||
}
|
||||
addNewInput(streamReader);
|
||||
addNewInput(streamReader, fileName);
|
||||
}
|
||||
|
||||
private void updateHistory(String command) {
|
||||
|
@ -203,21 +205,19 @@ public final class CommandLineHandler {
|
|||
return transform.apply(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод, меняющий текущий поток ввода на stream и добавляет его в очередь {@link #inputs inputs}
|
||||
*
|
||||
* @param reader Новый поток ввода
|
||||
*/
|
||||
public void addNewInput(Reader reader) {
|
||||
public void addNewInput(Reader reader, String filePath) {
|
||||
if (this.fileNames.contains(filePath)) {
|
||||
System.err.println("Замечена рекурсия, отмена смены потока");
|
||||
return;
|
||||
}
|
||||
this.fileNames.add(filePath);
|
||||
this.reader = new BufferedReader(reader);
|
||||
this.inputs.add(reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Метод, убирающий текущий поток ввода из очереди {@link #inputs inputs}
|
||||
* и меняющий его либо на следующий в очереди поток, либо на System.in, если очередь пуста
|
||||
*/
|
||||
public void removeInput() {
|
||||
if (fileNames.size() > 0)
|
||||
fileNames.removeLast();
|
||||
inputs.poll();
|
||||
Reader reader = inputs.isEmpty() ? new InputStreamReader(System.in) : inputs.peek();
|
||||
this.reader = new BufferedReader(reader);
|
||||
|
|
|
@ -113,8 +113,7 @@ public final class PeopleDatabaseCommands {
|
|||
peopleDatabase.save();
|
||||
System.out.println("Коллекция была успешно сохранена");
|
||||
} catch (Database.DatabaseSaveFailedException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println("Не удалось сохранить коллекцию");
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,9 +45,9 @@ public class Coordinates implements Comparable<Coordinates> {
|
|||
* @throws IllegalArgumentException Если Y меньше или равен -816
|
||||
*/
|
||||
public void setY(float y) {
|
||||
if (y <= -816)
|
||||
throw new IllegalArgumentException("Поле y класса Coordinates должно быть больше -816");
|
||||
this.y = y;
|
||||
if (y <= -816)
|
||||
this.y = 0F;
|
||||
}
|
||||
|
||||
private double distance() {
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
package ru.erius.lab5.data;
|
||||
|
||||
import lombok.*;
|
||||
import ru.erius.lab5.parser.NameAdapter;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Класс данных местоположения, реализует сортировку по умолчанию
|
||||
* по имени и расстоянию до точки (0; 0; 0)
|
||||
*/
|
||||
@Data @NoArgsConstructor @EqualsAndHashCode @ToString
|
||||
@Data @EqualsAndHashCode @ToString
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class Location implements Comparable<Location> {
|
||||
|
||||
|
@ -31,8 +33,13 @@ public class Location implements Comparable<Location> {
|
|||
* Имя локации, может быть null
|
||||
*/
|
||||
@XmlElement(nillable = true)
|
||||
@XmlJavaTypeAdapter(NameAdapter.class)
|
||||
private String name;
|
||||
|
||||
private Location() {
|
||||
this.setName(this.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Конструктор с параметрами
|
||||
*
|
||||
|
@ -59,9 +66,9 @@ public class Location implements Comparable<Location> {
|
|||
* @throws IllegalArgumentException Если name является пустой строкой
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if (name != null && name.isEmpty())
|
||||
throw new IllegalArgumentException("Поле name класса Location не может быть пустым");
|
||||
this.name = name;
|
||||
if (name != null && name.isEmpty())
|
||||
this.name = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,7 +4,10 @@ import lombok.Data;
|
|||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NonNull;
|
||||
import lombok.ToString;
|
||||
import ru.erius.lab5.parser.HeightAdapter;
|
||||
import ru.erius.lab5.parser.LocalDateAdapter;
|
||||
import ru.erius.lab5.parser.NameAdapter;
|
||||
import ru.erius.lab5.parser.PassportAdapter;
|
||||
|
||||
import javax.xml.bind.annotation.*;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
@ -35,6 +38,7 @@ public class Person implements Comparable<Person> {
|
|||
/**
|
||||
* Имя человека, не может быть null, строка не может быть пустой
|
||||
*/
|
||||
@XmlJavaTypeAdapter(NameAdapter.class)
|
||||
private String name;
|
||||
/**
|
||||
* Координаты человека, не может быть null
|
||||
|
@ -49,11 +53,13 @@ public class Person implements Comparable<Person> {
|
|||
* Рост человека, может быть null, значение поля должно быть больше 0
|
||||
*/
|
||||
@XmlElement(nillable = true)
|
||||
@XmlJavaTypeAdapter(HeightAdapter.class)
|
||||
private Integer height;
|
||||
/**
|
||||
* Номер паспорта человека, длина строки должна быть не меньше 8, поле может быть null
|
||||
*/
|
||||
@XmlElement(nillable = true)
|
||||
@XmlJavaTypeAdapter(PassportAdapter.class)
|
||||
private String passportID;
|
||||
/**
|
||||
* Цвет глаз человека, не может быть null
|
||||
|
@ -132,9 +138,9 @@ public class Person implements Comparable<Person> {
|
|||
* Если имя является пустой строкой
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if (name.isEmpty())
|
||||
throw new IllegalArgumentException("Поле name класса Person не может быть null или пустым");
|
||||
this.name = name;
|
||||
if (name.isEmpty())
|
||||
this.name = "none";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,9 +151,9 @@ public class Person implements Comparable<Person> {
|
|||
* @throws IllegalArgumentException Если рост меньше 0
|
||||
*/
|
||||
public void setHeight(Integer height) {
|
||||
if (height != null && height <= 0)
|
||||
throw new IllegalArgumentException("Поле height класса Person должно быть больше 0");
|
||||
this.height = height;
|
||||
if (height != null && height <= 0)
|
||||
this.height = 150;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,9 +164,9 @@ public class Person implements Comparable<Person> {
|
|||
* @throws IllegalArgumentException Если номер паспорта меньше 8 символов в длину
|
||||
*/
|
||||
public void setPassportID(String passportID) {
|
||||
if (passportID != null && passportID.length() < 8)
|
||||
throw new IllegalArgumentException("Поле passportID класса Person не может быть меньше 8 символов в длину");
|
||||
this.passportID = passportID;
|
||||
if (passportID != null && passportID.length() < 8)
|
||||
this.passportID = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
16
src/main/java/ru/erius/lab5/parser/CoordinateYAdapter.java
Normal file
16
src/main/java/ru/erius/lab5/parser/CoordinateYAdapter.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
package ru.erius.lab5.parser;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
public class CoordinateYAdapter extends XmlAdapter<String, Float> {
|
||||
@Override
|
||||
public Float unmarshal(String v) throws Exception {
|
||||
float result = Float.parseFloat(v);
|
||||
return result > -816F ? result : 0F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String marshal(Float v) throws Exception {
|
||||
return v.toString();
|
||||
}
|
||||
}
|
21
src/main/java/ru/erius/lab5/parser/HeightAdapter.java
Normal file
21
src/main/java/ru/erius/lab5/parser/HeightAdapter.java
Normal file
|
@ -0,0 +1,21 @@
|
|||
package ru.erius.lab5.parser;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
public class HeightAdapter extends XmlAdapter<String, Integer> {
|
||||
|
||||
@Override
|
||||
public Integer unmarshal(String v) throws Exception {
|
||||
if (v == null)
|
||||
return null;
|
||||
int result = Integer.parseInt(v);
|
||||
if (result <= 0)
|
||||
return 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String marshal(Integer v) throws Exception {
|
||||
return v.toString();
|
||||
}
|
||||
}
|
15
src/main/java/ru/erius/lab5/parser/NameAdapter.java
Normal file
15
src/main/java/ru/erius/lab5/parser/NameAdapter.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package ru.erius.lab5.parser;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
public class NameAdapter extends XmlAdapter<String, String> {
|
||||
@Override
|
||||
public String unmarshal(String v) throws Exception {
|
||||
return v.isEmpty() ? "none" : v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String marshal(String v) throws Exception {
|
||||
return v;
|
||||
}
|
||||
}
|
16
src/main/java/ru/erius/lab5/parser/PassportAdapter.java
Normal file
16
src/main/java/ru/erius/lab5/parser/PassportAdapter.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
package ru.erius.lab5.parser;
|
||||
|
||||
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
||||
|
||||
public class PassportAdapter extends XmlAdapter<String, String> {
|
||||
|
||||
@Override
|
||||
public String unmarshal(String v) throws Exception {
|
||||
return v.length() < 8 ? "no_passport" : v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String marshal(String v) throws Exception {
|
||||
return v;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue