diff --git a/task01/src/com/example/task01/Logger.java b/task01/src/com/example/task01/Logger.java new file mode 100644 index 00000000..fcd4f674 --- /dev/null +++ b/task01/src/com/example/task01/Logger.java @@ -0,0 +1,100 @@ +package com.example.task01; + +import java.util.ArrayList; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class Logger { + + private static final DateTimeFormatter FORMATTER = + DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss"); + + private String getCurrentDateTime() { + return LocalDateTime.now().format(FORMATTER); + } + + public enum Level { + DEBUG, + INFO, + WARNING, + ERROR + } + + private String name; + private static ArrayList loggerList = new ArrayList<>(); + private Level level; + + public String getName(){ + return name; + } + + public Level getLevel(){ + return level; + } + + public void setLevel(Level level){ + this.level = level; + } + + public Logger(String name, Level level){ + this.name = name; + this.level = level; + loggerList.add(this); + } + + public static Logger getLogger(String name){ + for (Logger e : loggerList){ + if (e.getName().equals(name)) return e; + } + + return new Logger(name, Level.DEBUG); + } + + public void debug(String message){ + log(Level.DEBUG, message); + } + + public void debug(String pattern, Object... args){ + log(Level.DEBUG, pattern, args); + } + + public void info(String message){ + log(Level.INFO, message); + } + + public void info(String pattern, Object... args){ + log(Level.INFO, pattern, args); + } + + public void warning(String message){ + log(Level.WARNING, message); + } + + public void warning(String pattern, Object... args){ + log(Level.WARNING, pattern, args); + } + + public void error(String message){ + log(Level.ERROR, message); + } + + public void error(String pattern, Object... args){ + log(Level.ERROR, pattern, args); + } + + public void log(Level level, String message){ + if (level.ordinal() >= this.level.ordinal()){ + String datetime = getCurrentDateTime(); + String logMessage = String.format("[%s] %s %s - %s", + level, datetime, name, message); + + System.out.println(logMessage); + } + } + + public void log(Level level, String pattern, Object... args){ + if (level.ordinal() >= this.level.ordinal()){ + System.out.println(String.format(pattern, args)); + } + } +} diff --git a/task02/src/com/example/task02/DiscountBill.java b/task02/src/com/example/task02/DiscountBill.java new file mode 100644 index 00000000..65319415 --- /dev/null +++ b/task02/src/com/example/task02/DiscountBill.java @@ -0,0 +1,22 @@ +package com.example.task02; + +public class DiscountBill extends Bill { + private final double discount; + + public DiscountBill(double discount){ + this.discount = discount; + } + + @Override + public long getPrice(){ + return (long) (super.getPrice() - super.getPrice() * this.discount); + } + + public double getDiscount(){ + return this.discount * 100; + } + + public long getAbsoluteDiscount(){ + return super.getPrice() - this.getPrice(); + } +} diff --git a/task03/src/com/example/task03/Hours.java b/task03/src/com/example/task03/Hours.java new file mode 100644 index 00000000..61eb972d --- /dev/null +++ b/task03/src/com/example/task03/Hours.java @@ -0,0 +1,29 @@ +package com.example.task03; + +public class Hours implements TimeUnit{ + private final long amount; + + public Hours(long amount) { + this.amount = amount; + } + + @Override + public long toMillis() { + return amount * 60 * 60 * 1000; + } + + @Override + public long toSeconds() { + return amount * 60 * 60; + } + + @Override + public long toMinutes() { + return amount * 60; + } + + @Override + public long getHours() { + return amount; + } +} diff --git a/task03/src/com/example/task03/Milliseconds.java b/task03/src/com/example/task03/Milliseconds.java index 5115bc7d..1774a71f 100644 --- a/task03/src/com/example/task03/Milliseconds.java +++ b/task03/src/com/example/task03/Milliseconds.java @@ -18,11 +18,16 @@ public long toMillis() { @Override public long toSeconds() { - return amount / 1000; + return Math.round(amount / 1000.0); } @Override public long toMinutes() { - return amount / 1000 * 60; + return Math.round(amount / (1000.0 * 60.0)); + } + + @Override + public long getHours() { + return Math.round(amount / (1000.0 * 60.0 * 60.0)); } } diff --git a/task03/src/com/example/task03/Minutes.java b/task03/src/com/example/task03/Minutes.java index d6fa0594..d1f755bb 100644 --- a/task03/src/com/example/task03/Minutes.java +++ b/task03/src/com/example/task03/Minutes.java @@ -1,27 +1,33 @@ package com.example.task03; public class Minutes implements TimeUnit { + private final long amount; public Minutes(long amount) { // TODO: реализовать - throw new UnsupportedOperationException(); + this.amount = amount; } @Override public long toMillis() { // TODO: реализовать - throw new UnsupportedOperationException(); + return amount * 60 * 1000; } @Override public long toSeconds() { // TODO: реализовать - throw new UnsupportedOperationException(); + return amount * 60; } @Override public long toMinutes() { // TODO: реализовать - throw new UnsupportedOperationException(); + return amount; + } + + @Override + public long getHours() { + return Math.round(amount / 60.0); } } diff --git a/task03/src/com/example/task03/Seconds.java b/task03/src/com/example/task03/Seconds.java index ce6bc213..008f5b25 100644 --- a/task03/src/com/example/task03/Seconds.java +++ b/task03/src/com/example/task03/Seconds.java @@ -23,6 +23,11 @@ public long toSeconds() { @Override public long toMinutes() { - return Math.round(amount / 60); + return Math.round(amount / 60.0); + } + + @Override + public long getHours() { + return Math.round(amount / (60.0 * 60.0)); } } diff --git a/task03/src/com/example/task03/TimeUnit.java b/task03/src/com/example/task03/TimeUnit.java index 3b123fb8..907bda1f 100644 --- a/task03/src/com/example/task03/TimeUnit.java +++ b/task03/src/com/example/task03/TimeUnit.java @@ -28,4 +28,11 @@ public interface TimeUnit { */ long toMinutes(); + /** + * Возвращает продолжительность текущего интервала, пересчитанного в часах. + * При необходимости округлять по обычным правилам округления (число, меньшее 0.5 переходит в 0, большее или равное - в 1) + * + * @return количество часов в текущем интервале + */ + long getHours(); } diff --git a/task03/src/com/example/task03/TimeUnitUtils.java b/task03/src/com/example/task03/TimeUnitUtils.java index 790f8850..6397da86 100644 --- a/task03/src/com/example/task03/TimeUnitUtils.java +++ b/task03/src/com/example/task03/TimeUnitUtils.java @@ -15,6 +15,14 @@ public static Milliseconds toMillis(Seconds seconds) { return new Milliseconds(seconds.toMillis()); } + public static Milliseconds toMillis(Minutes minutes) { + return new Milliseconds(minutes.toMillis()); + } + + public static Milliseconds toMillis(Hours hours) { + return new Milliseconds(hours.toMillis()); + } + /** * Конвертирует интервал в миллисекундах в интервал в секундах * @@ -24,4 +32,48 @@ public static Milliseconds toMillis(Seconds seconds) { public static Seconds toSeconds(Milliseconds millis) { return new Seconds(millis.toSeconds()); } + + public static Seconds toSeconds(Minutes minutes) { + return new Seconds(minutes.toSeconds()); + } + + public static Seconds toSeconds(Hours hours) { + return new Seconds(hours.toSeconds()); + } + + /** + * Конвертирует интервал в миллисекундах в интервал в минутах + * + * @param millis интервал в миллисекундах + * @return интервал в минутах + */ + public static Minutes toMinutes(Milliseconds millis) { + return new Minutes(millis.toMinutes()); + } + + public static Minutes toMinutes(Seconds seconds) { + return new Minutes(seconds.toMinutes()); + } + + public static Minutes toMinutes(Hours hours) { + return new Minutes(hours.toMinutes()); + } + + /** + * Конвертирует интервал в миллисекундах в интервал в часах + * + * @param millis интервал в миллисекундах + * @return интервал в часах + */ + public static Hours getHours(Milliseconds millis) { + return new Hours(millis.getHours()); + } + + public static Hours getHours(Seconds seconds) { + return new Hours(seconds.getHours()); + } + + public static Hours getHours(Minutes minutes) { + return new Hours(minutes.getHours()); + } } diff --git a/task04/src/com/example/task04/ConsoleHandler.java b/task04/src/com/example/task04/ConsoleHandler.java new file mode 100644 index 00000000..b0df320e --- /dev/null +++ b/task04/src/com/example/task04/ConsoleHandler.java @@ -0,0 +1,8 @@ +package com.example.task04; + +public class ConsoleHandler implements MessageHandler{ + @Override + public void log(String message){ + System.out.println(message); + } +} diff --git a/task04/src/com/example/task04/FileHandler.java b/task04/src/com/example/task04/FileHandler.java new file mode 100644 index 00000000..8c226e2c --- /dev/null +++ b/task04/src/com/example/task04/FileHandler.java @@ -0,0 +1,32 @@ +package com.example.task04; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.io.IOException; +import java.nio.file.StandardOpenOption; + +public class FileHandler implements MessageHandler { + private final Path filePath; + + public FileHandler(String filePath) { + this.filePath = Paths.get(filePath); + try { + if (this.filePath.getParent() != null) { + Files.createDirectories(this.filePath.getParent()); + } + } catch (IOException e) { + throw new RuntimeException("Cannot create directories", e); + } + } + + @Override + public void log(String message) { + try { + Files.write(filePath, (message + System.lineSeparator()).getBytes(), + StandardOpenOption.CREATE, StandardOpenOption.APPEND); + } catch (IOException e) { + throw new RuntimeException("Cannot write to file: " + filePath, e); + } + } +} diff --git a/task04/src/com/example/task04/Logger.java b/task04/src/com/example/task04/Logger.java new file mode 100644 index 00000000..ec628612 --- /dev/null +++ b/task04/src/com/example/task04/Logger.java @@ -0,0 +1,119 @@ +package com.example.task04; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; + +public class Logger { + + private static final DateTimeFormatter FORMATTER = + DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss"); + + private String getCurrentDateTime() { + return LocalDateTime.now().format(FORMATTER); + } + + public enum Level { + DEBUG, + INFO, + WARNING, + ERROR + } + + private String name; + private static ArrayList loggerList = new ArrayList<>(); + private Level level; + private List handlers = new ArrayList<>(); + + public String getName(){ + return name; + } + + public Level getLevel(){ + return level; + } + + public void setLevel(Level level){ + this.level = level; + } + + public void addHandler(MessageHandler handler) { + handlers.add(handler); + } + + public void removeHandler(MessageHandler handler) { + handlers.remove(handler); + } + + public List getHandlers() { + return new ArrayList<>(handlers); + } + + public Logger(String name, Level level){ + this.name = name; + this.level = level; + loggerList.add(this); + } + + public static Logger getLogger(String name){ + for (Logger e : loggerList){ + if (e.getName().equals(name)) return e; + } + + return new Logger(name, Level.DEBUG); + } + + private String formatMessage(Level level, String message) { + return String.format("[%s] %s %s - %s", + level, getCurrentDateTime(), name, message); + } + + private void handleLog(Level level, String formattedMessage) { + if (level.ordinal() >= this.level.ordinal()) { + for (MessageHandler handler : handlers) { + handler.log(formattedMessage); + } + } + } + + public void debug(String message){ + log(Level.DEBUG, message); + } + + public void debug(String pattern, Object... args){ + log(Level.DEBUG, pattern, args); + } + + public void info(String message){ + log(Level.INFO, message); + } + + public void info(String pattern, Object... args){ + log(Level.INFO, pattern, args); + } + + public void warning(String message){ + log(Level.WARNING, message); + } + + public void warning(String pattern, Object... args){ + log(Level.WARNING, pattern, args); + } + + public void error(String message){ + log(Level.ERROR, message); + } + + public void error(String pattern, Object... args){ + log(Level.ERROR, pattern, args); + } + + public void log(Level level, String message){ + handleLog(level, formatMessage(level, message)); + } + + public void log(Level level, String pattern, Object... args){ + handleLog(level, formatMessage(level, String.format(pattern, args))); + } +} diff --git a/task04/src/com/example/task04/MemoryHandler.java b/task04/src/com/example/task04/MemoryHandler.java new file mode 100644 index 00000000..b274b2af --- /dev/null +++ b/task04/src/com/example/task04/MemoryHandler.java @@ -0,0 +1,37 @@ +package com.example.task04; + +import java.util.ArrayList; +import java.util.List; + +public class MemoryHandler implements MessageHandler { + private final MessageHandler targetHandler; + private final int bufferSize; + private final List buffer; + + public MemoryHandler(MessageHandler targetHandler, int bufferSize) { + this.targetHandler = targetHandler; + this.bufferSize = bufferSize; + this.buffer = new ArrayList<>(bufferSize); + } + + @Override + public void log(String message) { + synchronized (buffer) { + buffer.add(message); + if (buffer.size() >= bufferSize) { + flush(); + } + } + } + + public void flush() { + synchronized (buffer) { + if (!buffer.isEmpty()) { + for (String message : buffer) { + targetHandler.log(message); + } + buffer.clear(); + } + } + } +} diff --git a/task04/src/com/example/task04/MessageHandler.java b/task04/src/com/example/task04/MessageHandler.java new file mode 100644 index 00000000..13beca02 --- /dev/null +++ b/task04/src/com/example/task04/MessageHandler.java @@ -0,0 +1,5 @@ +package com.example.task04; + +public interface MessageHandler { + void log(String message); +} diff --git a/task04/src/com/example/task04/RotationFileHandler.java b/task04/src/com/example/task04/RotationFileHandler.java new file mode 100644 index 00000000..67f6eaba --- /dev/null +++ b/task04/src/com/example/task04/RotationFileHandler.java @@ -0,0 +1,52 @@ +package com.example.task04; + +import java.nio.file.StandardOpenOption; +import java.time.temporal.ChronoUnit; +import java.time.format.DateTimeFormatter; +import java.time.LocalDateTime; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.io.IOException; + +public class RotationFileHandler implements MessageHandler { + private final String basePath; + private final ChronoUnit rotationUnit; + private final DateTimeFormatter timeFormatter; + + public RotationFileHandler(String basePath, ChronoUnit rotationUnit) { + this.basePath = basePath; + this.rotationUnit = rotationUnit; + this.timeFormatter = getDateTimeFormatter(rotationUnit); + } + + private DateTimeFormatter getDateTimeFormatter(ChronoUnit rotationUnit) { + switch (rotationUnit) { + case HOURS: return DateTimeFormatter.ofPattern("yyyy-MM-dd-HH"); + case DAYS: return DateTimeFormatter.ofPattern("yyyy-MM-dd"); + case MONTHS: return DateTimeFormatter.ofPattern("yyyy-MM"); + default: return DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"); + } + } + + private Path getCurrentFilePath() { + LocalDateTime now = LocalDateTime.now().truncatedTo(rotationUnit); + String filename = basePath + "_" + now.format(timeFormatter) + ".log"; + return Paths.get(filename); + } + + @Override + public void log(String message) { + Path currentFilePath = getCurrentFilePath(); + + try { + if (currentFilePath.getParent() != null) { + Files.createDirectories(currentFilePath.getParent()); + } + Files.write(currentFilePath, (message + System.lineSeparator()).getBytes(), + StandardOpenOption.CREATE, StandardOpenOption.APPEND); + } catch (IOException e) { + throw new RuntimeException("Cannot write to file: " + currentFilePath, e); + } + } +} diff --git a/task04/src/com/example/task04/Task04Main.java b/task04/src/com/example/task04/Task04Main.java index 55917a30..c3139316 100644 --- a/task04/src/com/example/task04/Task04Main.java +++ b/task04/src/com/example/task04/Task04Main.java @@ -1,5 +1,7 @@ package com.example.task04; +import java.time.temporal.ChronoUnit; + public class Task04Main { public static void main(String[] args) {