diff --git a/java-data-handling-template.iml b/java-data-handling-template.iml new file mode 100644 index 00000000..5e9ffdc5 --- /dev/null +++ b/java-data-handling-template.iml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/epam/izh/rd/online/repository/SimpleFileRepository.java b/src/main/java/com/epam/izh/rd/online/repository/SimpleFileRepository.java index 1783b845..3896039e 100644 --- a/src/main/java/com/epam/izh/rd/online/repository/SimpleFileRepository.java +++ b/src/main/java/com/epam/izh/rd/online/repository/SimpleFileRepository.java @@ -1,5 +1,15 @@ package com.epam.izh.rd.online.repository; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + public class SimpleFileRepository implements FileRepository { /** @@ -10,7 +20,26 @@ public class SimpleFileRepository implements FileRepository { */ @Override public long countFilesInDirectory(String path) { - return 0; + File file = new File(path); + if (!(file.isDirectory() || file.isFile())) + { + URL url = getClass().getResource("/" + path); + file = new File(url.getPath()); + } + File[] directory = file.listFiles(); + + long count = 0; + + if (directory != null) { + for (File item : directory) { + if (!item.isFile()) { + count += countFilesInDirectory(item.getPath()); + } else { + count++; + } + } + } + return count; } /** @@ -21,7 +50,28 @@ public long countFilesInDirectory(String path) { */ @Override public long countDirsInDirectory(String path) { - return 0; + long count = 0; + + File file = new File(path); + if (!(file.isDirectory() || file.isFile())) + { + URL url = getClass().getResource("/" + path); + file = new File(url.getPath()); + count++; + } + + File[] directory = file.listFiles(); + + + if (directory != null) { + for (File item : directory) { + if (item.isDirectory()) { + count++; + count += countDirsInDirectory(item.getPath()); + } + } + } + return count; } /** @@ -32,9 +82,17 @@ public long countDirsInDirectory(String path) { */ @Override public void copyTXTFiles(String from, String to) { - return; + File file = new File(to); + createFile(file.getParent(), file.getName()); + + try { + Files.copy(Paths.get(from), Paths.get(to), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException ioEx) { + ioEx.printStackTrace(); + } } + /** * Метод создает файл на диске с расширением txt * @@ -44,6 +102,20 @@ public void copyTXTFiles(String from, String to) { */ @Override public boolean createFile(String path, String name) { + URL url = getClass().getResource("/"); + File folder = new File(url.getPath() + "/" + path); + + File file = new File(folder.getPath() + "/" + name); + boolean isDirectoryCreated = !new File(path).isDirectory(); + + try { + if (isDirectoryCreated) { + Files.createDirectory(Paths.get(path)); + } + return file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } return false; } @@ -55,6 +127,15 @@ public boolean createFile(String path, String name) { */ @Override public String readFileFromResources(String fileName) { - return null; + StringBuilder stringBuilder = new StringBuilder(); + try (BufferedReader is = new BufferedReader(new FileReader("src/main/resources/" + fileName))) { + String line; + while ((line = is.readLine()) != null) { + stringBuilder.append(line); + } + } catch (IOException ioex) { + ioex.printStackTrace(); + } + return stringBuilder.toString(); } } diff --git a/src/main/java/com/epam/izh/rd/online/service/SieveEratosthenes.java b/src/main/java/com/epam/izh/rd/online/service/SieveEratosthenes.java new file mode 100644 index 00000000..b8fdd5d5 --- /dev/null +++ b/src/main/java/com/epam/izh/rd/online/service/SieveEratosthenes.java @@ -0,0 +1,52 @@ +package com.epam.izh.rd.online.service; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +class SieveEratosthenes { + + private static class PrimePair { + BigInteger prime; + BigInteger lastCrossed; + + PrimePair(BigInteger prime, BigInteger lastCrossed) { + this.prime = prime; + this.lastCrossed = lastCrossed; + } + } + + private List primes; + + SieveEratosthenes() { + primes = new ArrayList<>(); + primes.add(new PrimePair(new BigInteger("2"), new BigInteger("2"))); + primes.add(new PrimePair(new BigInteger("3"), new BigInteger("3"))); + } + + BigInteger fillNPrimes(int n) { + if (n >= 0 && n <= 1) { + return primes.get(n).prime; + } + while (primes.size() <= n) { + addNextPrime(); + } + return primes.get(primes.size() - 1).prime; + } + + private void addNextPrime() { + BigInteger candidate = primes.get(primes.size() - 1).prime.add(new BigInteger("2")); + for (int i = 1; i < primes.size(); i++) { + PrimePair p = primes.get(i); + while (p.lastCrossed.compareTo(candidate) < 0) { + p.lastCrossed = p.lastCrossed.add(p.prime); + } + if (p.lastCrossed.compareTo(candidate) == 0) { + candidate = candidate.add(new BigInteger("2")); + i = -1; + } + } + primes.add(new PrimePair(candidate, candidate)); + } +} + diff --git a/src/main/java/com/epam/izh/rd/online/service/SimpleBigNumbersService.java b/src/main/java/com/epam/izh/rd/online/service/SimpleBigNumbersService.java index a94c7bba..17aa7304 100644 --- a/src/main/java/com/epam/izh/rd/online/service/SimpleBigNumbersService.java +++ b/src/main/java/com/epam/izh/rd/online/service/SimpleBigNumbersService.java @@ -2,18 +2,21 @@ import java.math.BigDecimal; import java.math.BigInteger; +import java.math.RoundingMode; public class SimpleBigNumbersService implements BigNumbersService { /** * Метод делит первое число на второе с заданной точностью * Например 1/3 с точностью 2 = 0.33 + * * @param range точность * @return результат */ @Override public BigDecimal getPrecisionNumber(int a, int b, int range) { - return null; + BigDecimal[] bigDecimals = {new BigDecimal(a), new BigDecimal(b)}; + return bigDecimals[0].divide(bigDecimals[1], range, RoundingMode.HALF_UP); } /** @@ -24,6 +27,8 @@ public BigDecimal getPrecisionNumber(int a, int b, int range) { */ @Override public BigInteger getPrimaryNumber(int range) { - return null; + SieveEratosthenes sieveEratosthenes = new SieveEratosthenes(); + return sieveEratosthenes.fillNPrimes(range); } } + diff --git a/src/main/java/com/epam/izh/rd/online/service/SimpleDateService.java b/src/main/java/com/epam/izh/rd/online/service/SimpleDateService.java index 70d64dfd..0d1f670d 100644 --- a/src/main/java/com/epam/izh/rd/online/service/SimpleDateService.java +++ b/src/main/java/com/epam/izh/rd/online/service/SimpleDateService.java @@ -3,6 +3,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.GregorianCalendar; public class SimpleDateService implements DateService { @@ -14,7 +15,8 @@ public class SimpleDateService implements DateService { */ @Override public String parseDate(LocalDate localDate) { - return null; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy"); + return localDate.format(formatter); } /** @@ -25,7 +27,8 @@ public String parseDate(LocalDate localDate) { */ @Override public LocalDateTime parseString(String string) { - return null; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + return LocalDateTime.parse(string, formatter); } /** @@ -37,7 +40,8 @@ public LocalDateTime parseString(String string) { */ @Override public String convertToCustomFormat(LocalDate localDate, DateTimeFormatter formatter) { - return null; + + return localDate.format(formatter); } /** @@ -47,7 +51,14 @@ public String convertToCustomFormat(LocalDate localDate, DateTimeFormatter forma */ @Override public long getNextLeapYear() { - return 0; + GregorianCalendar calendar = (GregorianCalendar) GregorianCalendar.getInstance(); + int leapYear = calendar.get(GregorianCalendar.YEAR); + for (; ; ) { + leapYear++; + if (calendar.isLeapYear(leapYear)) { + return leapYear; + } + } } /** @@ -57,7 +68,12 @@ public long getNextLeapYear() { */ @Override public long getSecondsInYear(int year) { - return 0; + GregorianCalendar calendar = (GregorianCalendar) GregorianCalendar.getInstance(); + if (calendar.isLeapYear(year)) { + return 366 * 24 * 60 * 60; + } else { + return 365 * 24 * 60 * 60; + } } diff --git a/src/main/java/com/epam/izh/rd/online/service/SimpleRegExpService.java b/src/main/java/com/epam/izh/rd/online/service/SimpleRegExpService.java index b6eff56b..d2011f3b 100644 --- a/src/main/java/com/epam/izh/rd/online/service/SimpleRegExpService.java +++ b/src/main/java/com/epam/izh/rd/online/service/SimpleRegExpService.java @@ -1,5 +1,9 @@ package com.epam.izh.rd.online.service; +import com.epam.izh.rd.online.repository.SimpleFileRepository; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class SimpleRegExpService implements RegExpService { /** @@ -11,7 +15,16 @@ public class SimpleRegExpService implements RegExpService { */ @Override public String maskSensitiveData() { - return null; + StringBuilder stringBuilder = new StringBuilder( + new SimpleFileRepository().readFileFromResources("sensitive_data.txt") + ); + + Pattern pattern = Pattern.compile("((\\d){4}\\s?){4}"); + Matcher matcher = pattern.matcher(stringBuilder.toString()); + while (matcher.find()) { + stringBuilder.replace(matcher.start() + 4, matcher.end() - 5, " **** **** "); + } + return stringBuilder.toString(); } /** @@ -22,6 +35,23 @@ public String maskSensitiveData() { */ @Override public String replacePlaceholders(double paymentAmount, double balance) { - return null; + StringBuilder stringBuilder = new StringBuilder( + new SimpleFileRepository().readFileFromResources("sensitive_data.txt") + ); + + Pattern pattern = Pattern.compile("[$][{]{1}\\w+[}]{1}"); + Matcher matcher = pattern.matcher(stringBuilder.toString()); + + while (matcher.find()) { + if (stringBuilder.substring(matcher.start() + 2, matcher.end() - 1).equals("payment_amount")) { + stringBuilder.replace(matcher.start(), matcher.end(), String.format("%.0f", paymentAmount)); + matcher = pattern.matcher(stringBuilder.toString()); + } else if (stringBuilder.substring(matcher.start() + 2, matcher.end() - 1).equals("balance")) { + stringBuilder.replace(matcher.start(), matcher.end(), String.format("%.0f", balance)); + matcher = pattern.matcher(stringBuilder.toString()); + } + } + return stringBuilder.toString(); } + } diff --git a/src/main/java/com/epam/izh/rd/online/service/SimpleTextService.java b/src/main/java/com/epam/izh/rd/online/service/SimpleTextService.java index 68951fbe..5526abe6 100644 --- a/src/main/java/com/epam/izh/rd/online/service/SimpleTextService.java +++ b/src/main/java/com/epam/izh/rd/online/service/SimpleTextService.java @@ -1,64 +1,89 @@ package com.epam.izh.rd.online.service; +import java.lang.String; + public class SimpleTextService implements TextService { /** * Реализовать функционал удаления строки из другой строки. - * + *

* Например для базовой строки "Hello, hello, hello, how low?" и строки для удаления ", he" * метод вернет "Hellollollo, how low?" * - * @param base - базовая строка с текстом + * @param base - базовая строка с текстом * @param remove - строка которую необходимо удалить */ @Override public String removeString(String base, String remove) { - return null; //TODO + return base.replace(remove, ""); } /** * Реализовать функционал проверки на то, что строка заканчивается знаком вопроса. - * + *

* Например для строки "Hello, hello, hello, how low?" метод вернет true * Например для строки "Hello, hello, hello!" метод вернет false */ @Override public boolean isQuestionString(String text) { - return false; //TODO + return (text.length() > 0 && text.charAt(text.length() - 1) == '?'); } /** * Реализовать функционал соединения переданных строк. - * + *

* Например для параметров {"Smells", " ", "Like", " ", "Teen", " ", "Spirit"} * метод вернет "Smells Like Teen Spirit" */ @Override public String concatenate(String... elements) { - return null; //TODO + StringBuilder result = new StringBuilder(); + for (String str : elements) { + result.append(str); + } + return result.toString(); } /** * Реализовать функционал изменения регистра в вид лесенки. * Возвращаемый текст должен начинаться с прописного регистра. - * + *

* Например для строки "Load Up On Guns And Bring Your Friends" * метод вернет "lOaD Up oN GuNs aNd bRiNg yOuR FrIeNdS". */ @Override public String toJumpCase(String text) { - return null; //TODO + StringBuilder result = new StringBuilder(); + for (int i = 0; i < text.length(); i++) { + if ((i % 2) != 0) { + result.append(Character.toUpperCase(text.charAt(i))); + } else { + result.append(Character.toLowerCase(text.charAt(i))); + } + } + return result.toString(); } /** * Метод определяет, является ли строка палиндромом. - * + *

* Палиндром - строка, которая одинаково читается слева направо и справа налево. - * + *

* Например для строки "а роза упала на лапу Азора" вернется true, а для "я не палиндром" false */ @Override public boolean isPalindrome(String string) { - return false; //TODO + if (string.length() == 0) { + return false; + } + boolean palindrome = true; + string = removeString(string, " ").toLowerCase(); + for (int i = 0; i < string.length() / 2; i++) { + if (string.charAt(i) != string.charAt(string.length() - 1 - i)) { + palindrome = false; + break; + } + } + return palindrome; } } diff --git a/src/test/java/com/epam/izh/rd/online/BigNumbersServiceTest.java b/src/test/java/com/epam/izh/rd/online/BigNumbersServiceTest.java index d86a5fe3..8421507c 100644 --- a/src/test/java/com/epam/izh/rd/online/BigNumbersServiceTest.java +++ b/src/test/java/com/epam/izh/rd/online/BigNumbersServiceTest.java @@ -32,5 +32,13 @@ void testGetPrecisionNumber() { void testGetPrimaryNumber() { assertEquals(BigInteger.valueOf(547), bigNumbersService.getPrimaryNumber(100), "Для вызова метода: bigNumbersService.getPrimaryNumber(100)"); + assertEquals(BigInteger.valueOf(2), bigNumbersService.getPrimaryNumber(0), + "Для вызова метода: bigNumbersService.getPrimaryNumber(100)"); + assertEquals(BigInteger.valueOf(3), bigNumbersService.getPrimaryNumber(1), + "Для вызова метода: bigNumbersService.getPrimaryNumber(100)"); + assertEquals(BigInteger.valueOf(5), bigNumbersService.getPrimaryNumber(2), + "Для вызова метода: bigNumbersService.getPrimaryNumber(100)"); + assertEquals(BigInteger.valueOf(7), bigNumbersService.getPrimaryNumber(3), + "Для вызова метода: bigNumbersService.getPrimaryNumber(100)"); } } diff --git a/src/test/java/com/epam/izh/rd/online/FileRepositoryTest.java b/src/test/java/com/epam/izh/rd/online/FileRepositoryTest.java index d581bac2..31ff55b5 100644 --- a/src/test/java/com/epam/izh/rd/online/FileRepositoryTest.java +++ b/src/test/java/com/epam/izh/rd/online/FileRepositoryTest.java @@ -105,4 +105,4 @@ private File getFile(String path) { } return new File(""); } -} +} \ No newline at end of file diff --git a/src/test/java/com/epam/izh/rd/online/RegExpServiceTest.java b/src/test/java/com/epam/izh/rd/online/RegExpServiceTest.java index 0dd35e47..4911eb0e 100644 --- a/src/test/java/com/epam/izh/rd/online/RegExpServiceTest.java +++ b/src/test/java/com/epam/izh/rd/online/RegExpServiceTest.java @@ -21,7 +21,7 @@ static void setup() { @DisplayName("Тест метода RegExpService.maskSensitiveData()") void testMaskSensitiveData() { assertEquals("Вчера вечером со счета номер 4301 **** **** 2140 был совершен перевод на счет 5042 **** ****" + - " 2043 в размере ${payment_amount} рублей. На счету осталось ${balance} рублей", + " 2043 в размере ${payment_amount} рублей. На счету осталось ${balance} рублей", regExpService.maskSensitiveData()); }