From 22fc85d3f3eeee18024c3ed4b46047f52e92d811 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Tue, 17 Oct 2017 11:50:59 +0300 Subject: [PATCH 01/46] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 127b1304a..a6de25e17 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ - используя асинхронные сервлеты 3.0 - сохранение данных в PostgreSQL используя [jDBI](http://jdbi.org/) - миграция базы [LiquiBase](http://www.liquibase.org/) -- использование в проекте [Guava](https://github.com/google/guava/wiki), [Thymleaf](http://www.thymeleaf.org/), [Lombook](https://projectlombok.org/), [StreamEx](https://github.com/amaembo/streamex), +- использование в проекте [Guava](https://github.com/google/guava/wiki), [Thymleaf](http://www.thymeleaf.org/), [Lombok](https://projectlombok.org/), [StreamEx](https://github.com/amaembo/streamex), [Typesafe Config](https://github.com/typesafehub/config), [Java Microbenchmark JMH](http://openjdk.java.net/projects/code-tools/jmh) ### Требование к участникам @@ -134,14 +134,14 @@ MatrixBenchmark.concurrentMultiply3 1000 ss 100 186,827 ± 11,882 - Maven. Поиск и разрешение конфликтов зависимостей - Подключаем логирование с общими настройкам - Библиотеки и фреймворки для работы с JDBC. -- Модуль persist +- Модуль persistence ## Занятие 5 - Разбор ДЗ - Сохранение в базу в batch-моде с обработкой конфликтов - Вставка в несколько потоков - Конфигурирование приложения (Typesafe config) -- Lombook +- Lombok ## Занятие 6 - Разбор ДЗ (доработка модели и модуля export) From 66dbb57f307e8ac7f01f61af948a3a315a40b4f5 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Mon, 23 Oct 2017 05:31:40 +0300 Subject: [PATCH 02/46] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a6de25e17..2d26e390c 100644 --- a/README.md +++ b/README.md @@ -99,9 +99,9 @@ ----- ## ![error](https://cloud.githubusercontent.com/assets/13649199/13672935/ef09ec1e-e6e7-11e5-9f79-d1641c05cbe6.png) Подсказки по HW1 -- не делайте 1000 000 тасок, лучше их сделать крупнее -- у меня разница между 4 и 1000 тасками по времени незаметна, поэтому делайте просто и не делайте сложно -- наконец: можно не считать значение элемента результирующей матрицы C за раз, а накапливать (`concurrentMultiply3`). Мои результаты: +- 1: не делайте 1000 000 тасок, лучше их сделать крупнее +- 2: у меня разница между 4 и 1000 тасками по времени незаметна, поэтому делайте просто и не делайте сложно +- 3: наконец: можно не считать значение элемента результирующей матрицы C за раз, а накапливать (`concurrentMultiply3`). Тогда трансформация B не нужна. Мои результаты: ``` Benchmark (matrixSize) Mode Cnt Score Error Units MatrixBenchmark.singleThreadMultiplyOpt 1000 ss 100 837,867 ± 25,530 ms/op From 4b3a183635f38c7190971038b7a720395f808f41 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 22 Feb 2018 18:07:56 +0300 Subject: [PATCH 03/46] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2d26e390c..6157a56d3 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ #### Скачайте [1_1_MailService.patch](https://drive.google.com/open?id=0B9Ye2auQ_NsFTE5ZV3pzWElxTWM), положите его в проект, правой мышкой на нем сделайте Apply Patch ... ---------------------------- +- [Как сделать Java код проще и нагляднее](https://habrahabr.ru/company/wrike/blog/349652/) ### Ресурсы (основы) - Intuit, Потоки выполнения. Синхронизация From 389d911b60d0e1ddca77dbde8c9d34311e5f115a Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 8 Nov 2018 16:37:46 +0300 Subject: [PATCH 04/46] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6157a56d3..e5fe3209b 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ > В видео в `LazySingleton` ошибка: должно быть как в коде проекта `instance == null` ### Структура памяти: куча, стек, permanent/metaspace - - JVM изнутри - оптимизация и профилирование. + - JVM изнутри - оптимизация и профилирование. - Stack and Heap - Дополнительно: - Из каких частей состоит память java процесса. From 45f97151852c296e41061236c0c9b5ab3e5dd331 Mon Sep 17 00:00:00 2001 From: Java Online Projects Date: Thu, 27 Dec 2018 19:32:21 +0300 Subject: [PATCH 05/46] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e5fe3209b..2ece5d267 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,9 @@ - Permanent область памяти - Java thread stack - Размер Java объектов + - Оптимизация памяти + - [Escape analysis и скаляризация: Пусть GC отдохнет](https://habr.com/company/jugru/blog/322348) + - [Условия для размещения объекта в стеке](https://stackoverflow.com/a/43002529/548473) ### Ленивая инициализация - Реализация Singleton в JAVA From d0c8423e2f1fdd54fafc7965329b3a3fa34735ac Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:08:45 +0200 Subject: [PATCH 06/46] 1 1 MailService --- .../masterjava/service/MailService.java | 72 ++++++++++++++++++- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/javaops/masterjava/service/MailService.java b/src/main/java/ru/javaops/masterjava/service/MailService.java index 2b6aeb294..cef46e55e 100644 --- a/src/main/java/ru/javaops/masterjava/service/MailService.java +++ b/src/main/java/ru/javaops/masterjava/service/MailService.java @@ -1,8 +1,10 @@ package ru.javaops.masterjava.service; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.concurrent.*; +import java.util.stream.Collectors; public class MailService { private static final String OK = "OK"; @@ -11,10 +13,74 @@ public class MailService { private static final String INTERRUPTED_BY_TIMEOUT = "+++ Interrupted by timeout"; private static final String INTERRUPTED_EXCEPTION = "+++ InterruptedException"; + private final ExecutorService mailExecutor = Executors.newFixedThreadPool(8); + public GroupResult sendToList(final String template, final Set emails) throws Exception { - return new GroupResult(0, Collections.emptyList(), null); - } + final CompletionService completionService = new ExecutorCompletionService<>(mailExecutor); + + List> futures = emails.stream() + .map(email -> completionService.submit(() -> sendToUser(template, email))) + .collect(Collectors.toList()); + return new Callable() { + private int success = 0; + private List failed = new ArrayList<>(); + + @Override + public GroupResult call() { + while (!futures.isEmpty()) { + try { + Future future = completionService.poll(10, TimeUnit.SECONDS); + if (future == null) { + return cancelWithFail(INTERRUPTED_BY_TIMEOUT); + } + futures.remove(future); + MailResult mailResult = future.get(); + if (mailResult.isOk()) { + success++; + } else { + failed.add(mailResult); + if (failed.size() >= 5) { + return cancelWithFail(INTERRUPTED_BY_FAULTS_NUMBER); + } + } + } catch (ExecutionException e) { + return cancelWithFail(e.getCause().toString()); + } catch (InterruptedException e) { + return cancelWithFail(INTERRUPTED_EXCEPTION); + } + } +/* + for (Future future : futures) { + MailResult mailResult; + try { + mailResult = future.get(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + return cancelWithFail(INTERRUPTED_EXCEPTION); + } catch (ExecutionException e) { + return cancelWithFail(e.getCause().toString()); + } catch (TimeoutException e) { + return cancelWithFail(INTERRUPTED_BY_TIMEOUT); + } + if (mailResult.isOk()) { + success++; + } else { + failed.add(mailResult); + if (failed.size() >= 5) { + return cancelWithFail(INTERRUPTED_BY_FAULTS_NUMBER); + } + } + } +*/ + return new GroupResult(success, failed, null); + } + + private GroupResult cancelWithFail(String cause) { + futures.forEach(f -> f.cancel(true)); + return new GroupResult(success, failed, cause); + } + }.call(); + } // dummy realization public MailResult sendToUser(String template, String email) throws Exception { From b0c6988e848acde12f4a62f31f427acfb5f4f63a Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:14:32 +0200 Subject: [PATCH 07/46] 2 01 HW1 singleThreadMultiplyOpt --- 1_1_MailService.patch | 96 +++ 2_01_HW1_singleThreadMultiplyOpt.patch | 54 ++ 2_02_HW1_concurrentMultiply.patch | 182 ++++ 2_03_HW1_concurrentMultiply2.patch | 245 ++++++ 2_04_JMH_Benchmark.patch | 113 +++ 2_05_JMH_main_jar.patch | 85 ++ 2_06_xml_scheme.patch | 754 ++++++++++++++++ 2_07_JAXB.patch | 342 ++++++++ 2_08_StAX.patch | 109 +++ 2_09_XPath.patch | 101 +++ 2_10_Xslt.patch | 95 ++ 3_1_HW2_schema.patch | 815 ++++++++++++++++++ 3_2_HW2_JAXB_HTML.patch | 132 +++ 3_3_HW2_StAX.patch | 147 ++++ 3_4_StAX_refactoring.patch | 158 ++++ 3_5_HW2_xslt.patch | 104 +++ 3_6_multimodule.patch | 294 +++++++ 4_10_persist.patch | 552 ++++++++++++ 4_1_HW3_pom_structure.patch | 535 ++++++++++++ 4_2_HW3_thymeleaf_upload.patch | 425 +++++++++ 4_3_HW3_upload_servlet3.patch | 87 ++ 4_4_HW3_jaxb_stax.patch | 341 ++++++++ 4_5_dependencies.patch | 33 + 4_6_fix_convergence.patch | 58 ++ 4_7_enforcer.patch | 32 + 4_8_logging.patch | 184 ++++ 4_9_context.patch | 57 ++ .../javaops/masterjava/matrix/MainMatrix.java | 2 +- 28 files changed, 6131 insertions(+), 1 deletion(-) create mode 100644 1_1_MailService.patch create mode 100644 2_01_HW1_singleThreadMultiplyOpt.patch create mode 100644 2_02_HW1_concurrentMultiply.patch create mode 100644 2_03_HW1_concurrentMultiply2.patch create mode 100644 2_04_JMH_Benchmark.patch create mode 100644 2_05_JMH_main_jar.patch create mode 100644 2_06_xml_scheme.patch create mode 100644 2_07_JAXB.patch create mode 100644 2_08_StAX.patch create mode 100644 2_09_XPath.patch create mode 100644 2_10_Xslt.patch create mode 100644 3_1_HW2_schema.patch create mode 100644 3_2_HW2_JAXB_HTML.patch create mode 100644 3_3_HW2_StAX.patch create mode 100644 3_4_StAX_refactoring.patch create mode 100644 3_5_HW2_xslt.patch create mode 100644 3_6_multimodule.patch create mode 100644 4_10_persist.patch create mode 100644 4_1_HW3_pom_structure.patch create mode 100644 4_2_HW3_thymeleaf_upload.patch create mode 100644 4_3_HW3_upload_servlet3.patch create mode 100644 4_4_HW3_jaxb_stax.patch create mode 100644 4_5_dependencies.patch create mode 100644 4_6_fix_convergence.patch create mode 100644 4_7_enforcer.patch create mode 100644 4_8_logging.patch create mode 100644 4_9_context.patch diff --git a/1_1_MailService.patch b/1_1_MailService.patch new file mode 100644 index 000000000..59985d4a9 --- /dev/null +++ b/1_1_MailService.patch @@ -0,0 +1,96 @@ +Index: src/main/java/ru/javaops/masterjava/service/MailService.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/service/MailService.java (revision 500495ec05bb1a01c3811657f6d0770347ff8a8d) ++++ src/main/java/ru/javaops/masterjava/service/MailService.java (revision ) +@@ -1,8 +1,10 @@ + package ru.javaops.masterjava.service; + +-import java.util.Collections; ++import java.util.ArrayList; + import java.util.List; + import java.util.Set; ++import java.util.concurrent.*; ++import java.util.stream.Collectors; + + public class MailService { + private static final String OK = "OK"; +@@ -11,10 +13,74 @@ + private static final String INTERRUPTED_BY_TIMEOUT = "+++ Interrupted by timeout"; + private static final String INTERRUPTED_EXCEPTION = "+++ InterruptedException"; + ++ private final ExecutorService mailExecutor = Executors.newFixedThreadPool(8); ++ + public GroupResult sendToList(final String template, final Set emails) throws Exception { +- return new GroupResult(0, Collections.emptyList(), null); +- } ++ final CompletionService completionService = new ExecutorCompletionService<>(mailExecutor); ++ ++ List> futures = emails.stream() ++ .map(email -> completionService.submit(() -> sendToUser(template, email))) ++ .collect(Collectors.toList()); ++ ++ return new Callable() { ++ private int success = 0; ++ private List failed = new ArrayList<>(); ++ ++ @Override ++ public GroupResult call() { ++ while (!futures.isEmpty()) { ++ try { ++ Future future = completionService.poll(10, TimeUnit.SECONDS); ++ if (future == null) { ++ return cancelWithFail(INTERRUPTED_BY_TIMEOUT); ++ } ++ futures.remove(future); ++ MailResult mailResult = future.get(); ++ if (mailResult.isOk()) { ++ success++; ++ } else { ++ failed.add(mailResult); ++ if (failed.size() >= 5) { ++ return cancelWithFail(INTERRUPTED_BY_FAULTS_NUMBER); ++ } ++ } ++ } catch (ExecutionException e) { ++ return cancelWithFail(e.getCause().toString()); ++ } catch (InterruptedException e) { ++ return cancelWithFail(INTERRUPTED_EXCEPTION); ++ } ++ } ++/* ++ for (Future future : futures) { ++ MailResult mailResult; ++ try { ++ mailResult = future.get(10, TimeUnit.SECONDS); ++ } catch (InterruptedException e) { ++ return cancelWithFail(INTERRUPTED_EXCEPTION); ++ } catch (ExecutionException e) { ++ return cancelWithFail(e.getCause().toString()); ++ } catch (TimeoutException e) { ++ return cancelWithFail(INTERRUPTED_BY_TIMEOUT); ++ } ++ if (mailResult.isOk()) { ++ success++; ++ } else { ++ failed.add(mailResult); ++ if (failed.size() >= 5) { ++ return cancelWithFail(INTERRUPTED_BY_FAULTS_NUMBER); ++ } ++ } ++ } ++*/ ++ return new GroupResult(success, failed, null); ++ } + ++ private GroupResult cancelWithFail(String cause) { ++ futures.forEach(f -> f.cancel(true)); ++ return new GroupResult(success, failed, cause); ++ } ++ }.call(); ++ } + + // dummy realization + public MailResult sendToUser(String template, String email) throws Exception { diff --git a/2_01_HW1_singleThreadMultiplyOpt.patch b/2_01_HW1_singleThreadMultiplyOpt.patch new file mode 100644 index 000000000..c0661a165 --- /dev/null +++ b/2_01_HW1_singleThreadMultiplyOpt.patch @@ -0,0 +1,54 @@ +Index: src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (revision d9b13eb2b75334b7485b55a83399716ab1899b7e) ++++ src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (revision bbace72e8bb84842d5ca73ba331e84d8e8d5ca6c) +@@ -24,7 +24,7 @@ + while (count < 6) { + System.out.println("Pass " + count); + long start = System.currentTimeMillis(); +- final int[][] matrixC = MatrixUtil.singleThreadMultiply(matrixA, matrixB); ++ final int[][] matrixC = MatrixUtil.singleThreadMultiplyOpt(matrixA, matrixB); + double duration = (System.currentTimeMillis() - start) / 1000.; + out("Single thread time, sec: %.3f", duration); + singleThreadSum += duration; +Index: src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (revision d9b13eb2b75334b7485b55a83399716ab1899b7e) ++++ src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (revision bbace72e8bb84842d5ca73ba331e84d8e8d5ca6c) +@@ -18,18 +18,24 @@ + return matrixC; + } + +- // TODO optimize by https://habrahabr.ru/post/114797/ +- public static int[][] singleThreadMultiply(int[][] matrixA, int[][] matrixB) { ++ // Optimized by https://habrahabr.ru/post/114797/ ++ public static int[][] singleThreadMultiplyOpt(int[][] matrixA, int[][] matrixB) { + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; + +- for (int i = 0; i < matrixSize; i++) { +- for (int j = 0; j < matrixSize; j++) { ++ for (int col = 0; col < matrixSize; col++) { ++ final int[] columnB = new int[matrixSize]; ++ for (int k = 0; k < matrixSize; k++) { ++ columnB[k] = matrixB[k][col]; ++ } ++ ++ for (int row = 0; row < matrixSize; row++) { + int sum = 0; ++ final int[] rowA = matrixA[row]; + for (int k = 0; k < matrixSize; k++) { +- sum += matrixA[i][k] * matrixB[k][j]; ++ sum += rowA[k] * columnB[k]; + } +- matrixC[i][j] = sum; ++ matrixC[row][col] = sum; + } + } + return matrixC; diff --git a/2_02_HW1_concurrentMultiply.patch b/2_02_HW1_concurrentMultiply.patch new file mode 100644 index 000000000..125962b60 --- /dev/null +++ b/2_02_HW1_concurrentMultiply.patch @@ -0,0 +1,182 @@ +Index: src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (date 1508266595000) ++++ src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (date 1508268723000) +@@ -1,8 +1,9 @@ + package ru.javaops.masterjava.matrix; + +-import java.util.Random; +-import java.util.concurrent.ExecutionException; +-import java.util.concurrent.ExecutorService; ++import java.util.*; ++import java.util.concurrent.*; ++import java.util.stream.Collectors; ++import java.util.stream.IntStream; + + /** + * gkislin +@@ -10,11 +11,153 @@ + */ + public class MatrixUtil { + +- // TODO implement parallel multiplication matrixA*matrixB + public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; + ++ class ColumnMultipleResult { ++ private final int col; ++ private final int[] columnC; ++ ++ private ColumnMultipleResult(int col, int[] columnC) { ++ this.col = col; ++ this.columnC = columnC; ++ } ++ } ++ ++ final CompletionService completionService = new ExecutorCompletionService<>(executor); ++ ++ for (int j = 0; j < matrixSize; j++) { ++ final int col = j; ++ final int[] columnB = new int[matrixSize]; ++ for (int k = 0; k < matrixSize; k++) { ++ columnB[k] = matrixB[k][col]; ++ } ++ completionService.submit(() -> { ++ final int[] columnC = new int[matrixSize]; ++ ++ for (int row = 0; row < matrixSize; row++) { ++ final int[] rowA = matrixA[row]; ++ int sum = 0; ++ for (int k = 0; k < matrixSize; k++) { ++ sum += rowA[k] * columnB[k]; ++ } ++ columnC[row] = sum; ++ } ++ return new ColumnMultipleResult(col, columnC); ++ }); ++ } ++ ++ for (int i = 0; i < matrixSize; i++) { ++ ColumnMultipleResult res = completionService.take().get(); ++ for (int k = 0; k < matrixSize; k++) { ++ matrixC[k][res.col] = res.columnC[k]; ++ } ++ } ++ return matrixC; ++ } ++ ++ public static int[][] concurrentMultiplyCayman(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { ++ final int matrixSize = matrixA.length; ++ final int[][] matrixResult = new int[matrixSize][matrixSize]; ++ final int threadCount = Runtime.getRuntime().availableProcessors(); ++ final int maxIndex = matrixSize * matrixSize; ++ final int cellsInThread = maxIndex / threadCount; ++ final int[][] matrixBFinal = new int[matrixSize][matrixSize]; ++ ++ for (int i = 0; i < matrixSize; i++) { ++ for (int j = 0; j < matrixSize; j++) { ++ matrixBFinal[i][j] = matrixB[j][i]; ++ } ++ } ++ ++ Set> threads = new HashSet<>(); ++ int fromIndex = 0; ++ for (int i = 1; i <= threadCount; i++) { ++ final int toIndex = i == threadCount ? maxIndex : fromIndex + cellsInThread; ++ final int firstIndexFinal = fromIndex; ++ threads.add(() -> { ++ for (int j = firstIndexFinal; j < toIndex; j++) { ++ final int row = j / matrixSize; ++ final int col = j % matrixSize; ++ ++ int sum = 0; ++ for (int k = 0; k < matrixSize; k++) { ++ sum += matrixA[row][k] * matrixBFinal[col][k]; ++ } ++ matrixResult[row][col] = sum; ++ } ++ return true; ++ }); ++ fromIndex = toIndex; ++ } ++ executor.invokeAll(threads); ++ return matrixResult; ++ } ++ ++ public static int[][] concurrentMultiplyDarthVader(int[][] matrixA, int[][] matrixB, ExecutorService executor) ++ throws InterruptedException, ExecutionException { ++ ++ final int matrixSize = matrixA.length; ++ final int[][] matrixC = new int[matrixSize][matrixSize]; ++ ++ List> tasks = IntStream.range(0, matrixSize) ++ .parallel() ++ .mapToObj(i -> new Callable() { ++ private final int[] tempColumn = new int[matrixSize]; ++ ++ @Override ++ public Void call() throws Exception { ++ for (int c = 0; c < matrixSize; c++) { ++ tempColumn[c] = matrixB[c][i]; ++ } ++ for (int j = 0; j < matrixSize; j++) { ++ int row[] = matrixA[j]; ++ int sum = 0; ++ for (int k = 0; k < matrixSize; k++) { ++ sum += tempColumn[k] * row[k]; ++ } ++ matrixC[j][i] = sum; ++ } ++ return null; ++ } ++ }) ++ .collect(Collectors.toList()); ++ ++ executor.invokeAll(tasks); ++ return matrixC; ++ } ++ ++ public static int[][] concurrentMultiply2(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { ++ final int matrixSize = matrixA.length; ++ final int[][] matrixC = new int[matrixSize][]; ++ ++ final int[][] matrixBT = new int[matrixSize][matrixSize]; ++ for (int i = 0; i < matrixSize; i++) { ++ for (int j = 0; j < matrixSize; j++) { ++ matrixBT[i][j] = matrixB[j][i]; ++ } ++ } ++ ++ List> tasks = new ArrayList<>(matrixSize); ++ for (int j = 0; j < matrixSize; j++) { ++ final int row = j; ++ tasks.add(() -> { ++ final int[] rowC = new int[matrixSize]; ++ for (int col = 0; col < matrixSize; col++) { ++ final int[] rowA = matrixA[row]; ++ final int[] columnB = matrixBT[col]; ++ int sum = 0; ++ for (int k = 0; k < matrixSize; k++) { ++ sum += rowA[k] * columnB[k]; ++ } ++ rowC[col] = sum; ++ } ++ matrixC[row] = rowC; ++ return null; ++ }); ++ } ++ executor.invokeAll(tasks); + return matrixC; + } + +@@ -64,4 +207,4 @@ + } + return true; + } +-} ++} +\ No newline at end of file diff --git a/2_03_HW1_concurrentMultiply2.patch b/2_03_HW1_concurrentMultiply2.patch new file mode 100644 index 000000000..867926b60 --- /dev/null +++ b/2_03_HW1_concurrentMultiply2.patch @@ -0,0 +1,245 @@ +Index: src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (date 1508268723000) ++++ src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (revision ) +@@ -1,134 +1,39 @@ + package ru.javaops.masterjava.matrix; + +-import java.util.*; ++import java.util.ArrayList; ++import java.util.List; ++import java.util.Random; + import java.util.concurrent.*; +-import java.util.stream.Collectors; + import java.util.stream.IntStream; + +-/** +- * gkislin +- * 03.07.2016 +- */ + public class MatrixUtil { + +- public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { +- final int matrixSize = matrixA.length; +- final int[][] matrixC = new int[matrixSize][matrixSize]; +- +- class ColumnMultipleResult { +- private final int col; +- private final int[] columnC; +- +- private ColumnMultipleResult(int col, int[] columnC) { +- this.col = col; +- this.columnC = columnC; +- } +- } +- +- final CompletionService completionService = new ExecutorCompletionService<>(executor); +- +- for (int j = 0; j < matrixSize; j++) { +- final int col = j; +- final int[] columnB = new int[matrixSize]; +- for (int k = 0; k < matrixSize; k++) { +- columnB[k] = matrixB[k][col]; +- } +- completionService.submit(() -> { +- final int[] columnC = new int[matrixSize]; +- +- for (int row = 0; row < matrixSize; row++) { +- final int[] rowA = matrixA[row]; +- int sum = 0; +- for (int k = 0; k < matrixSize; k++) { +- sum += rowA[k] * columnB[k]; +- } +- columnC[row] = sum; +- } +- return new ColumnMultipleResult(col, columnC); +- }); +- } +- +- for (int i = 0; i < matrixSize; i++) { +- ColumnMultipleResult res = completionService.take().get(); +- for (int k = 0; k < matrixSize; k++) { +- matrixC[k][res.col] = res.columnC[k]; +- } +- } +- return matrixC; +- } +- +- public static int[][] concurrentMultiplyCayman(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { +- final int matrixSize = matrixA.length; +- final int[][] matrixResult = new int[matrixSize][matrixSize]; +- final int threadCount = Runtime.getRuntime().availableProcessors(); +- final int maxIndex = matrixSize * matrixSize; +- final int cellsInThread = maxIndex / threadCount; +- final int[][] matrixBFinal = new int[matrixSize][matrixSize]; +- +- for (int i = 0; i < matrixSize; i++) { +- for (int j = 0; j < matrixSize; j++) { +- matrixBFinal[i][j] = matrixB[j][i]; +- } +- } +- +- Set> threads = new HashSet<>(); +- int fromIndex = 0; +- for (int i = 1; i <= threadCount; i++) { +- final int toIndex = i == threadCount ? maxIndex : fromIndex + cellsInThread; +- final int firstIndexFinal = fromIndex; +- threads.add(() -> { +- for (int j = firstIndexFinal; j < toIndex; j++) { +- final int row = j / matrixSize; +- final int col = j % matrixSize; +- +- int sum = 0; +- for (int k = 0; k < matrixSize; k++) { +- sum += matrixA[row][k] * matrixBFinal[col][k]; +- } +- matrixResult[row][col] = sum; +- } +- return true; +- }); +- fromIndex = toIndex; +- } +- executor.invokeAll(threads); +- return matrixResult; +- } +- +- public static int[][] concurrentMultiplyDarthVader(int[][] matrixA, int[][] matrixB, ExecutorService executor) ++ public static int[][] concurrentMultiplyStreams(int[][] matrixA, int[][] matrixB, int threadNumber) + throws InterruptedException, ExecutionException { + + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; + +- List> tasks = IntStream.range(0, matrixSize) +- .parallel() +- .mapToObj(i -> new Callable() { +- private final int[] tempColumn = new int[matrixSize]; ++ new ForkJoinPool(threadNumber).submit( ++ () -> IntStream.range(0, matrixSize) ++ .parallel() ++ .forEach(row -> { ++ final int[] rowA = matrixA[row]; ++ final int[] rowC = matrixC[row]; + +- @Override +- public Void call() throws Exception { +- for (int c = 0; c < matrixSize; c++) { +- tempColumn[c] = matrixB[c][i]; +- } +- for (int j = 0; j < matrixSize; j++) { +- int row[] = matrixA[j]; +- int sum = 0; +- for (int k = 0; k < matrixSize; k++) { +- sum += tempColumn[k] * row[k]; ++ for (int idx = 0; idx < matrixSize; idx++) { ++ final int elA = rowA[idx]; ++ final int[] rowB = matrixB[idx]; ++ for (int col = 0; col < matrixSize; col++) { ++ rowC[col] += elA * rowB[col]; ++ } + } +- matrixC[j][i] = sum; +- } +- return null; +- } +- }) +- .collect(Collectors.toList()); ++ })).get(); + +- executor.invokeAll(tasks); + return matrixC; + } + +- public static int[][] concurrentMultiply2(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { ++ public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][]; + +@@ -161,7 +66,30 @@ + return matrixC; + } + +- // Optimized by https://habrahabr.ru/post/114797/ ++ public static int[][] concurrentMultiply2(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException { ++ final int matrixSize = matrixA.length; ++ final int[][] matrixC = new int[matrixSize][matrixSize]; ++ final CountDownLatch latch = new CountDownLatch(matrixSize); ++ ++ for (int row = 0; row < matrixSize; row++) { ++ final int[] rowA = matrixA[row]; ++ final int[] rowC = matrixC[row]; ++ ++ executor.submit(() -> { ++ for (int idx = 0; idx < matrixSize; idx++) { ++ final int elA = rowA[idx]; ++ final int[] rowB = matrixB[idx]; ++ for (int col = 0; col < matrixSize; col++) { ++ rowC[col] += elA * rowB[col]; ++ } ++ } ++ latch.countDown(); ++ }); ++ } ++ latch.await(); ++ return matrixC; ++ } ++ + public static int[][] singleThreadMultiplyOpt(int[][] matrixA, int[][] matrixB) { + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; +@@ -183,6 +111,25 @@ + } + return matrixC; + } ++ ++ public static int[][] singleThreadMultiplyOpt2(int[][] matrixA, int[][] matrixB) { ++ final int matrixSize = matrixA.length; ++ final int[][] matrixC = new int[matrixSize][matrixSize]; ++ ++ for (int row = 0; row < matrixSize; row++) { ++ final int[] rowA = matrixA[row]; ++ final int[] rowC = matrixC[row]; ++ ++ for (int idx = 0; idx < matrixSize; idx++) { ++ final int elA = rowA[idx]; ++ final int[] rowB = matrixB[idx]; ++ for (int col = 0; col < matrixSize; col++) { ++ rowC[col] += elA * rowB[col]; ++ } ++ } ++ } ++ return matrixC; ++ } + + public static int[][] create(int size) { + int[][] matrix = new int[size][size]; +Index: src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (date 1508268723000) ++++ src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (revision ) +@@ -4,10 +4,6 @@ + import java.util.concurrent.ExecutorService; + import java.util.concurrent.Executors; + +-/** +- * gkislin +- * 03.07.2016 +- */ + public class MainMatrix { + private static final int MATRIX_SIZE = 1000; + private static final int THREAD_NUMBER = 10; +@@ -30,7 +26,7 @@ + singleThreadSum += duration; + + start = System.currentTimeMillis(); +- final int[][] concurrentMatrixC = MatrixUtil.concurrentMultiply(matrixA, matrixB, executor); ++ final int[][] concurrentMatrixC = MatrixUtil.concurrentMultiplyStreams(matrixA, matrixB, Runtime.getRuntime().availableProcessors() - 1); + duration = (System.currentTimeMillis() - start) / 1000.; + out("Concurrent thread time, sec: %.3f", duration); + concurrentThreadSum += duration; diff --git a/2_04_JMH_Benchmark.patch b/2_04_JMH_Benchmark.patch new file mode 100644 index 000000000..d5bd75f16 --- /dev/null +++ b/2_04_JMH_Benchmark.patch @@ -0,0 +1,113 @@ +Index: src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (revision ) ++++ src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (revision ) +@@ -0,0 +1,70 @@ ++package ru.javaops.masterjava.matrix; ++ ++import org.openjdk.jmh.annotations.*; ++ ++import java.util.concurrent.ExecutorService; ++import java.util.concurrent.Executors; ++import java.util.concurrent.TimeUnit; ++ ++@Warmup(iterations = 10) ++@Measurement(iterations = 10) ++@BenchmarkMode({Mode.SingleShotTime}) ++@OutputTimeUnit(TimeUnit.MILLISECONDS) ++@State(Scope.Benchmark) ++@Threads(1) ++@Fork(10) ++@Timeout(time = 5, timeUnit = TimeUnit.MINUTES) ++public class MatrixBenchmark { ++ ++ // Matrix size ++ private static final int MATRIX_SIZE = 1000; ++ ++ @Param({"3", "4", "10"}) ++ private int threadNumber; ++ ++ private static int[][] matrixA; ++ private static int[][] matrixB; ++ ++ @Setup ++ public void setUp() { ++ matrixA = MatrixUtil.create(MATRIX_SIZE); ++ matrixB = MatrixUtil.create(MATRIX_SIZE); ++ } ++ ++ private ExecutorService executor; ++ ++ // @Benchmark ++ public int[][] singleThreadMultiplyOpt() throws Exception { ++ return MatrixUtil.singleThreadMultiplyOpt(matrixA, matrixB); ++ } ++ ++ // @Benchmark ++ public int[][] singleThreadMultiplyOpt2() throws Exception { ++ return MatrixUtil.singleThreadMultiplyOpt(matrixA, matrixB); ++ } ++ ++ @Benchmark ++ public int[][] concurrentMultiplyStreams() throws Exception { ++ return MatrixUtil.concurrentMultiplyStreams(matrixA, matrixB, threadNumber); ++ } ++ ++ // @Benchmark ++ public int[][] concurrentMultiply() throws Exception { ++ return MatrixUtil.concurrentMultiply(matrixA, matrixB, executor); ++ } ++ ++ @Benchmark ++ public int[][] concurrentMultiply2() throws Exception { ++ return MatrixUtil.concurrentMultiply2(matrixA, matrixB, executor); ++ } ++ ++ @Setup ++ public void setup() { ++ executor = Executors.newFixedThreadPool(threadNumber); ++ } ++ ++ @TearDown ++ public void tearDown() { ++ executor.shutdown(); ++ } ++} +\ No newline at end of file +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1508790464000) ++++ pom.xml (revision ) +@@ -24,7 +24,7 @@ + + org.apache.maven.plugins + maven-compiler-plugin +- 3.1 ++ 3.7.0 + + ${java.version} + ${java.version} +@@ -34,6 +34,17 @@ + + + ++ ++ org.openjdk.jmh ++ jmh-core ++ RELEASE ++ ++ ++ org.openjdk.jmh ++ jmh-generator-annprocess ++ RELEASE ++ provided ++ + + + diff --git a/2_05_JMH_main_jar.patch b/2_05_JMH_main_jar.patch new file mode 100644 index 000000000..1ad9083f5 --- /dev/null +++ b/2_05_JMH_main_jar.patch @@ -0,0 +1,85 @@ +Index: src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (date 1508792580000) ++++ src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (revision ) +@@ -1,6 +1,11 @@ + package ru.javaops.masterjava.matrix; + + import org.openjdk.jmh.annotations.*; ++import org.openjdk.jmh.runner.Runner; ++import org.openjdk.jmh.runner.RunnerException; ++import org.openjdk.jmh.runner.options.Options; ++import org.openjdk.jmh.runner.options.OptionsBuilder; ++import org.openjdk.jmh.runner.options.TimeValue; + + import java.util.concurrent.ExecutorService; + import java.util.concurrent.Executors; +@@ -33,6 +38,16 @@ + + private ExecutorService executor; + ++ public static void main(String[] args) throws RunnerException { ++ Options options = new OptionsBuilder() ++ .include(MatrixBenchmark.class.getSimpleName()) ++ .threads(1) ++ .forks(10) ++ .timeout(TimeValue.minutes(5)) ++ .build(); ++ new Runner(options).run(); ++ } ++ + // @Benchmark + public int[][] singleThreadMultiplyOpt() throws Exception { + return MatrixUtil.singleThreadMultiplyOpt(matrixA, matrixB); +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1508792580000) ++++ pom.xml (revision ) +@@ -30,6 +30,41 @@ + ${java.version} + + ++ ++ org.apache.maven.plugins ++ maven-shade-plugin ++ 3.1.0 ++ ++ ++ package ++ ++ shade ++ ++ ++ benchmarks ++ ++ ++ org.openjdk.jmh.Main ++ ++ ++ ++ ++ ++ *:* ++ ++ META-INF/*.SF ++ META-INF/*.DSA ++ META-INF/*.RSA ++ ++ ++ ++ ++ ++ ++ + + + diff --git a/2_06_xml_scheme.patch b/2_06_xml_scheme.patch new file mode 100644 index 000000000..9650668ee --- /dev/null +++ b/2_06_xml_scheme.patch @@ -0,0 +1,754 @@ +Index: src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (revision ) +@@ -0,0 +1,85 @@ ++ ++package ru.javaops.masterjava.xml.schema; ++ ++import javax.xml.bind.JAXBElement; ++import javax.xml.bind.annotation.XmlElementDecl; ++import javax.xml.bind.annotation.XmlRegistry; ++import javax.xml.namespace.QName; ++ ++ ++/** ++ * This object contains factory methods for each ++ * Java content interface and Java element interface ++ * generated in the ru.javaops.masterjava.xml.schema package. ++ *

An ObjectFactory allows you to programatically ++ * construct new instances of the Java representation ++ * for XML content. The Java representation of XML ++ * content can consist of schema derived interfaces ++ * and classes representing the binding of schema ++ * type definitions, element declarations and model ++ * groups. Factory methods for each of these are ++ * provided in this class. ++ * ++ */ ++@XmlRegistry ++public class ObjectFactory { ++ ++ private final static QName _City_QNAME = new QName("http://javaops.ru", "City"); ++ ++ /** ++ * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: ru.javaops.masterjava.xml.schema ++ * ++ */ ++ public ObjectFactory() { ++ } ++ ++ /** ++ * Create an instance of {@link Payload } ++ * ++ */ ++ public Payload createPayload() { ++ return new Payload(); ++ } ++ ++ /** ++ * Create an instance of {@link User } ++ * ++ */ ++ public User createUser() { ++ return new User(); ++ } ++ ++ /** ++ * Create an instance of {@link Payload.Cities } ++ * ++ */ ++ public Payload.Cities createPayloadCities() { ++ return new Payload.Cities(); ++ } ++ ++ /** ++ * Create an instance of {@link Payload.Users } ++ * ++ */ ++ public Payload.Users createPayloadUsers() { ++ return new Payload.Users(); ++ } ++ ++ /** ++ * Create an instance of {@link CityType } ++ * ++ */ ++ public CityType createCityType() { ++ return new CityType(); ++ } ++ ++ /** ++ * Create an instance of {@link JAXBElement }{@code <}{@link CityType }{@code >}} ++ * ++ */ ++ @XmlElementDecl(namespace = "http://javaops.ru", name = "City") ++ public JAXBElement createCity(CityType value) { ++ return new JAXBElement(_City_QNAME, CityType.class, null, value); ++ } ++ ++} +Index: src/main/java/ru/javaops/masterjava/xml/schema/Payload.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (revision ) +@@ -0,0 +1,233 @@ ++ ++package ru.javaops.masterjava.xml.schema; ++ ++import java.util.ArrayList; ++import java.util.List; ++import javax.xml.bind.annotation.XmlAccessType; ++import javax.xml.bind.annotation.XmlAccessorType; ++import javax.xml.bind.annotation.XmlElement; ++import javax.xml.bind.annotation.XmlRootElement; ++import javax.xml.bind.annotation.XmlType; ++ ++ ++/** ++ *

Java class for anonymous complex type. ++ * ++ *

The following schema fragment specifies the expected content contained within this class. ++ * ++ *

++ * <complexType>
++ *   <complexContent>
++ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
++ *       <all>
++ *         <element name="Cities">
++ *           <complexType>
++ *             <complexContent>
++ *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
++ *                 <sequence maxOccurs="unbounded">
++ *                   <element ref="{http://javaops.ru}City"/>
++ *                 </sequence>
++ *               </restriction>
++ *             </complexContent>
++ *           </complexType>
++ *         </element>
++ *         <element name="Users">
++ *           <complexType>
++ *             <complexContent>
++ *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
++ *                 <sequence maxOccurs="unbounded" minOccurs="0">
++ *                   <element ref="{http://javaops.ru}User"/>
++ *                 </sequence>
++ *               </restriction>
++ *             </complexContent>
++ *           </complexType>
++ *         </element>
++ *       </all>
++ *     </restriction>
++ *   </complexContent>
++ * </complexType>
++ * 
++ * ++ * ++ */ ++@XmlAccessorType(XmlAccessType.FIELD) ++@XmlType(name = "", propOrder = { ++ ++}) ++@XmlRootElement(name = "Payload", namespace = "http://javaops.ru") ++public class Payload { ++ ++ @XmlElement(name = "Cities", namespace = "http://javaops.ru", required = true) ++ protected Payload.Cities cities; ++ @XmlElement(name = "Users", namespace = "http://javaops.ru", required = true) ++ protected Payload.Users users; ++ ++ /** ++ * Gets the value of the cities property. ++ * ++ * @return ++ * possible object is ++ * {@link Payload.Cities } ++ * ++ */ ++ public Payload.Cities getCities() { ++ return cities; ++ } ++ ++ /** ++ * Sets the value of the cities property. ++ * ++ * @param value ++ * allowed object is ++ * {@link Payload.Cities } ++ * ++ */ ++ public void setCities(Payload.Cities value) { ++ this.cities = value; ++ } ++ ++ /** ++ * Gets the value of the users property. ++ * ++ * @return ++ * possible object is ++ * {@link Payload.Users } ++ * ++ */ ++ public Payload.Users getUsers() { ++ return users; ++ } ++ ++ /** ++ * Sets the value of the users property. ++ * ++ * @param value ++ * allowed object is ++ * {@link Payload.Users } ++ * ++ */ ++ public void setUsers(Payload.Users value) { ++ this.users = value; ++ } ++ ++ ++ /** ++ *

Java class for anonymous complex type. ++ * ++ *

The following schema fragment specifies the expected content contained within this class. ++ * ++ *

++     * <complexType>
++     *   <complexContent>
++     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
++     *       <sequence maxOccurs="unbounded">
++     *         <element ref="{http://javaops.ru}City"/>
++     *       </sequence>
++     *     </restriction>
++     *   </complexContent>
++     * </complexType>
++     * 
++ * ++ * ++ */ ++ @XmlAccessorType(XmlAccessType.FIELD) ++ @XmlType(name = "", propOrder = { ++ "city" ++ }) ++ public static class Cities { ++ ++ @XmlElement(name = "City", namespace = "http://javaops.ru", required = true) ++ protected List city; ++ ++ /** ++ * Gets the value of the city property. ++ * ++ *

++ * This accessor method returns a reference to the live list, ++ * not a snapshot. Therefore any modification you make to the ++ * returned list will be present inside the JAXB object. ++ * This is why there is not a set method for the city property. ++ * ++ *

++ * For example, to add a new item, do as follows: ++ *

++         *    getCity().add(newItem);
++         * 
++ * ++ * ++ *

++ * Objects of the following type(s) are allowed in the list ++ * {@link CityType } ++ * ++ * ++ */ ++ public List getCity() { ++ if (city == null) { ++ city = new ArrayList(); ++ } ++ return this.city; ++ } ++ ++ } ++ ++ ++ /** ++ *

Java class for anonymous complex type. ++ * ++ *

The following schema fragment specifies the expected content contained within this class. ++ * ++ *

++     * <complexType>
++     *   <complexContent>
++     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
++     *       <sequence maxOccurs="unbounded" minOccurs="0">
++     *         <element ref="{http://javaops.ru}User"/>
++     *       </sequence>
++     *     </restriction>
++     *   </complexContent>
++     * </complexType>
++     * 
++ * ++ * ++ */ ++ @XmlAccessorType(XmlAccessType.FIELD) ++ @XmlType(name = "", propOrder = { ++ "user" ++ }) ++ public static class Users { ++ ++ @XmlElement(name = "User", namespace = "http://javaops.ru") ++ protected List user; ++ ++ /** ++ * Gets the value of the user property. ++ * ++ *

++ * This accessor method returns a reference to the live list, ++ * not a snapshot. Therefore any modification you make to the ++ * returned list will be present inside the JAXB object. ++ * This is why there is not a set method for the user property. ++ * ++ *

++ * For example, to add a new item, do as follows: ++ *

++         *    getUser().add(newItem);
++         * 
++ * ++ * ++ *

++ * Objects of the following type(s) are allowed in the list ++ * {@link User } ++ * ++ * ++ */ ++ public List getUser() { ++ if (user == null) { ++ user = new ArrayList(); ++ } ++ return this.user; ++ } ++ ++ } ++ ++} +Index: src/main/java/ru/javaops/masterjava/xml/schema/User.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/User.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/schema/User.java (revision ) +@@ -0,0 +1,151 @@ ++ ++package ru.javaops.masterjava.xml.schema; ++ ++import javax.xml.bind.annotation.XmlAccessType; ++import javax.xml.bind.annotation.XmlAccessorType; ++import javax.xml.bind.annotation.XmlAttribute; ++import javax.xml.bind.annotation.XmlElement; ++import javax.xml.bind.annotation.XmlIDREF; ++import javax.xml.bind.annotation.XmlRootElement; ++import javax.xml.bind.annotation.XmlSchemaType; ++import javax.xml.bind.annotation.XmlType; ++ ++ ++/** ++ *

Java class for anonymous complex type. ++ * ++ *

The following schema fragment specifies the expected content contained within this class. ++ * ++ *

++ * <complexType>
++ *   <complexContent>
++ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
++ *       <sequence>
++ *         <element name="email" type="{http://www.w3.org/2001/XMLSchema}string"/>
++ *         <element name="fullName" type="{http://www.w3.org/2001/XMLSchema}string"/>
++ *       </sequence>
++ *       <attribute name="flag" use="required" type="{http://javaops.ru}flagType" />
++ *       <attribute name="city" use="required" type="{http://www.w3.org/2001/XMLSchema}IDREF" />
++ *     </restriction>
++ *   </complexContent>
++ * </complexType>
++ * 
++ * ++ * ++ */ ++@XmlAccessorType(XmlAccessType.FIELD) ++@XmlType(name = "", propOrder = { ++ "email", ++ "fullName" ++}) ++@XmlRootElement(name = "User", namespace = "http://javaops.ru") ++public class User { ++ ++ @XmlElement(namespace = "http://javaops.ru", required = true) ++ protected String email; ++ @XmlElement(namespace = "http://javaops.ru", required = true) ++ protected String fullName; ++ @XmlAttribute(name = "flag", required = true) ++ protected FlagType flag; ++ @XmlAttribute(name = "city", required = true) ++ @XmlIDREF ++ @XmlSchemaType(name = "IDREF") ++ protected Object city; ++ ++ /** ++ * Gets the value of the email property. ++ * ++ * @return ++ * possible object is ++ * {@link String } ++ * ++ */ ++ public String getEmail() { ++ return email; ++ } ++ ++ /** ++ * Sets the value of the email property. ++ * ++ * @param value ++ * allowed object is ++ * {@link String } ++ * ++ */ ++ public void setEmail(String value) { ++ this.email = value; ++ } ++ ++ /** ++ * Gets the value of the fullName property. ++ * ++ * @return ++ * possible object is ++ * {@link String } ++ * ++ */ ++ public String getFullName() { ++ return fullName; ++ } ++ ++ /** ++ * Sets the value of the fullName property. ++ * ++ * @param value ++ * allowed object is ++ * {@link String } ++ * ++ */ ++ public void setFullName(String value) { ++ this.fullName = value; ++ } ++ ++ /** ++ * Gets the value of the flag property. ++ * ++ * @return ++ * possible object is ++ * {@link FlagType } ++ * ++ */ ++ public FlagType getFlag() { ++ return flag; ++ } ++ ++ /** ++ * Sets the value of the flag property. ++ * ++ * @param value ++ * allowed object is ++ * {@link FlagType } ++ * ++ */ ++ public void setFlag(FlagType value) { ++ this.flag = value; ++ } ++ ++ /** ++ * Gets the value of the city property. ++ * ++ * @return ++ * possible object is ++ * {@link Object } ++ * ++ */ ++ public Object getCity() { ++ return city; ++ } ++ ++ /** ++ * Sets the value of the city property. ++ * ++ * @param value ++ * allowed object is ++ * {@link Object } ++ * ++ */ ++ public void setCity(Object value) { ++ this.city = value; ++ } ++ ++} +Index: src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java (revision ) +@@ -0,0 +1,54 @@ ++ ++package ru.javaops.masterjava.xml.schema; ++ ++import javax.xml.bind.annotation.XmlEnum; ++import javax.xml.bind.annotation.XmlEnumValue; ++import javax.xml.bind.annotation.XmlType; ++ ++ ++/** ++ *

Java class for flagType. ++ * ++ *

The following schema fragment specifies the expected content contained within this class. ++ *

++ *

++ * <simpleType name="flagType">
++ *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
++ *     <enumeration value="active"/>
++ *     <enumeration value="deleted"/>
++ *     <enumeration value="superuser"/>
++ *   </restriction>
++ * </simpleType>
++ * 
++ * ++ */ ++@XmlType(name = "flagType", namespace = "http://javaops.ru") ++@XmlEnum ++public enum FlagType { ++ ++ @XmlEnumValue("active") ++ ACTIVE("active"), ++ @XmlEnumValue("deleted") ++ DELETED("deleted"), ++ @XmlEnumValue("superuser") ++ SUPERUSER("superuser"); ++ private final String value; ++ ++ FlagType(String v) { ++ value = v; ++ } ++ ++ public String value() { ++ return value; ++ } ++ ++ public static FlagType fromValue(String v) { ++ for (FlagType c: FlagType.values()) { ++ if (c.value.equals(v)) { ++ return c; ++ } ++ } ++ throw new IllegalArgumentException(v); ++ } ++ ++} +Index: src/test/resources/payload.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/resources/payload.xml (revision ) ++++ src/test/resources/payload.xml (revision ) +@@ -0,0 +1,23 @@ ++ ++ ++ ++ gmail@gmail.com ++ Full Name ++ ++ ++ admin@javaops.ru ++ Admin ++ ++ ++ mail@yandex.ru ++ Deleted ++ ++ ++ ++ Санкт-Петербург ++ Киев ++ Минск ++ ++ +\ No newline at end of file +Index: src/main/java/ru/javaops/masterjava/xml/schema/CityType.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/CityType.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/schema/CityType.java (revision ) +@@ -0,0 +1,94 @@ ++ ++package ru.javaops.masterjava.xml.schema; ++ ++import javax.xml.bind.annotation.XmlAccessType; ++import javax.xml.bind.annotation.XmlAccessorType; ++import javax.xml.bind.annotation.XmlAttribute; ++import javax.xml.bind.annotation.XmlID; ++import javax.xml.bind.annotation.XmlSchemaType; ++import javax.xml.bind.annotation.XmlType; ++import javax.xml.bind.annotation.XmlValue; ++import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; ++import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; ++ ++ ++/** ++ *

Java class for cityType complex type. ++ * ++ *

The following schema fragment specifies the expected content contained within this class. ++ * ++ *

++ * <complexType name="cityType">
++ *   <simpleContent>
++ *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
++ *       <attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
++ *     </extension>
++ *   </simpleContent>
++ * </complexType>
++ * 
++ * ++ * ++ */ ++@XmlAccessorType(XmlAccessType.FIELD) ++@XmlType(name = "cityType", namespace = "http://javaops.ru", propOrder = { ++ "value" ++}) ++public class CityType { ++ ++ @XmlValue ++ protected String value; ++ @XmlAttribute(name = "id", required = true) ++ @XmlJavaTypeAdapter(CollapsedStringAdapter.class) ++ @XmlID ++ @XmlSchemaType(name = "ID") ++ protected String id; ++ ++ /** ++ * Gets the value of the value property. ++ * ++ * @return ++ * possible object is ++ * {@link String } ++ * ++ */ ++ public String getValue() { ++ return value; ++ } ++ ++ /** ++ * Sets the value of the value property. ++ * ++ * @param value ++ * allowed object is ++ * {@link String } ++ * ++ */ ++ public void setValue(String value) { ++ this.value = value; ++ } ++ ++ /** ++ * Gets the value of the id property. ++ * ++ * @return ++ * possible object is ++ * {@link String } ++ * ++ */ ++ public String getId() { ++ return id; ++ } ++ ++ /** ++ * Sets the value of the id property. ++ * ++ * @param value ++ * allowed object is ++ * {@link String } ++ * ++ */ ++ public void setId(String value) { ++ this.id = value; ++ } ++ ++} +Index: src/main/resources/payload.xsd +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/payload.xsd (revision ) ++++ src/main/resources/payload.xsd (revision ) +@@ -0,0 +1,56 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +\ No newline at end of file diff --git a/2_07_JAXB.patch b/2_07_JAXB.patch new file mode 100644 index 000000000..5dfafecc9 --- /dev/null +++ b/2_07_JAXB.patch @@ -0,0 +1,342 @@ +Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (revision ) +@@ -0,0 +1,39 @@ ++package ru.javaops.masterjava.xml.util; ++ ++import javax.xml.bind.JAXBContext; ++import javax.xml.bind.JAXBException; ++import javax.xml.bind.Marshaller; ++import javax.xml.bind.PropertyException; ++import javax.xml.validation.Schema; ++import java.io.StringWriter; ++import java.io.Writer; ++ ++public class JaxbMarshaller { ++ private Marshaller marshaller; ++ ++ public JaxbMarshaller(JAXBContext ctx) throws JAXBException { ++ marshaller = ctx.createMarshaller(); ++ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); ++ marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); ++ marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); ++ } ++ ++ public void setProperty(String prop, Object value) throws PropertyException { ++ marshaller.setProperty(prop, value); ++ } ++ ++ public synchronized void setSchema(Schema schema) { ++ marshaller.setSchema(schema); ++ } ++ ++ public String marshal(Object instance) throws JAXBException { ++ StringWriter sw = new StringWriter(); ++ marshal(instance, sw); ++ return sw.toString(); ++ } ++ ++ public synchronized void marshal(Object instance, Writer writer) throws JAXBException { ++ marshaller.marshal(instance, writer); ++ } ++ ++} +Index: src/main/java/ru/javaops/masterjava/xml/util/Schemas.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/Schemas.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/util/Schemas.java (revision ) +@@ -0,0 +1,48 @@ ++package ru.javaops.masterjava.xml.util; ++ ++import com.google.common.io.Resources; ++import org.xml.sax.SAXException; ++ ++import javax.xml.XMLConstants; ++import javax.xml.transform.stream.StreamSource; ++import javax.xml.validation.Schema; ++import javax.xml.validation.SchemaFactory; ++import java.io.File; ++import java.io.StringReader; ++import java.net.URL; ++ ++ ++public class Schemas { ++ ++ // SchemaFactory is not thread-safe ++ private static final SchemaFactory SCHEMA_FACTORY = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); ++ ++ public static synchronized Schema ofString(String xsd) { ++ try { ++ return SCHEMA_FACTORY.newSchema(new StreamSource(new StringReader(xsd))); ++ } catch (SAXException e) { ++ throw new IllegalArgumentException(e); ++ } ++ } ++ ++ public static synchronized Schema ofClasspath(String resource) { ++ // http://digitalsanctum.com/2012/11/30/how-to-read-file-contents-in-java-the-easy-way-with-guava/ ++ return ofURL(Resources.getResource(resource)); ++ } ++ ++ public static synchronized Schema ofURL(URL url) { ++ try { ++ return SCHEMA_FACTORY.newSchema(url); ++ } catch (SAXException e) { ++ throw new IllegalArgumentException(e); ++ } ++ } ++ ++ public static synchronized Schema ofFile(File file) { ++ try { ++ return SCHEMA_FACTORY.newSchema(file); ++ } catch (SAXException e) { ++ throw new IllegalArgumentException(e); ++ } ++ } ++} +Index: src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (revision ) ++++ src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (revision ) +@@ -0,0 +1,40 @@ ++package ru.javaops.masterjava.xml.util; ++ ++import com.google.common.io.Resources; ++import org.junit.Test; ++import ru.javaops.masterjava.xml.schema.CityType; ++import ru.javaops.masterjava.xml.schema.ObjectFactory; ++import ru.javaops.masterjava.xml.schema.Payload; ++ ++import javax.xml.bind.JAXBElement; ++import javax.xml.namespace.QName; ++ ++public class JaxbParserTest { ++ private static final JaxbParser JAXB_PARSER = new JaxbParser(ObjectFactory.class); ++ ++ static { ++ JAXB_PARSER.setSchema(Schemas.ofClasspath("payload.xsd")); ++ } ++ ++ @Test ++ public void testPayload() throws Exception { ++// JaxbParserTest.class.getResourceAsStream("/city.xml") ++ Payload payload = JAXB_PARSER.unmarshal( ++ Resources.getResource("payload.xml").openStream()); ++ String strPayload = JAXB_PARSER.marshal(payload); ++ JAXB_PARSER.validate(strPayload); ++ System.out.println(strPayload); ++ } ++ ++ @Test ++ public void testCity() throws Exception { ++ JAXBElement cityElement = JAXB_PARSER.unmarshal( ++ Resources.getResource("city.xml").openStream()); ++ CityType city = cityElement.getValue(); ++ JAXBElement cityElement2 = ++ new JAXBElement<>(new QName("http://javaops.ru", "City"), CityType.class, city); ++ String strCity = JAXB_PARSER.marshal(cityElement2); ++ JAXB_PARSER.validate(strCity); ++ System.out.println(strCity); ++ } ++} +\ No newline at end of file +Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision ) +@@ -0,0 +1,88 @@ ++package ru.javaops.masterjava.xml.util; ++ ++import org.xml.sax.SAXException; ++ ++import javax.xml.bind.JAXBContext; ++import javax.xml.bind.JAXBException; ++import javax.xml.bind.PropertyException; ++import javax.xml.transform.stream.StreamSource; ++import javax.xml.validation.Schema; ++import java.io.*; ++ ++ ++/** ++ * Marshalling/Unmarshalling JAXB helper ++ * XML Facade ++ */ ++public class JaxbParser { ++ ++ protected JaxbMarshaller jaxbMarshaller; ++ protected JaxbUnmarshaller jaxbUnmarshaller; ++ protected Schema schema; ++ ++ public JaxbParser(Class... classesToBeBound) { ++ try { ++ init(JAXBContext.newInstance(classesToBeBound)); ++ } catch (JAXBException e) { ++ throw new IllegalArgumentException(e); ++ } ++ } ++ ++ // http://stackoverflow.com/questions/30643802/what-is-jaxbcontext-newinstancestring-contextpath ++ public JaxbParser(String context) { ++ try { ++ init(JAXBContext.newInstance(context)); ++ } catch (JAXBException e) { ++ throw new IllegalArgumentException(e); ++ } ++ } ++ ++ private void init(JAXBContext ctx) throws JAXBException { ++ jaxbMarshaller = new JaxbMarshaller(ctx); ++ jaxbUnmarshaller = new JaxbUnmarshaller(ctx); ++ } ++ ++ // Unmarshaller ++ public T unmarshal(InputStream is) throws JAXBException { ++ return (T) jaxbUnmarshaller.unmarshal(is); ++ } ++ ++ public T unmarshal(Reader reader) throws JAXBException { ++ return (T) jaxbUnmarshaller.unmarshal(reader); ++ } ++ ++ public T unmarshal(String str) throws JAXBException { ++ return (T) jaxbUnmarshaller.unmarshal(str); ++ } ++ ++ // Marshaller ++ public void setMarshallerProperty(String prop, Object value) { ++ try { ++ jaxbMarshaller.setProperty(prop, value); ++ } catch (PropertyException e) { ++ throw new IllegalArgumentException(e); ++ } ++ } ++ ++ public String marshal(Object instance) throws JAXBException { ++ return jaxbMarshaller.marshal(instance); ++ } ++ ++ public void marshal(Object instance, Writer writer) throws JAXBException { ++ jaxbMarshaller.marshal(instance, writer); ++ } ++ ++ public void setSchema(Schema schema) { ++ this.schema = schema; ++ jaxbUnmarshaller.setSchema(schema); ++ jaxbMarshaller.setSchema(schema); ++ } ++ ++ public void validate(String str) throws IOException, SAXException { ++ validate(new StringReader(str)); ++ } ++ ++ public void validate(Reader reader) throws IOException, SAXException { ++ schema.newValidator().validate(new StreamSource(reader)); ++ } ++} +Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision ) +@@ -0,0 +1,33 @@ ++package ru.javaops.masterjava.xml.util; ++ ++import javax.xml.bind.JAXBContext; ++import javax.xml.bind.JAXBException; ++import javax.xml.bind.Unmarshaller; ++import javax.xml.validation.Schema; ++import java.io.InputStream; ++import java.io.Reader; ++import java.io.StringReader; ++ ++public class JaxbUnmarshaller { ++ private Unmarshaller unmarshaller; ++ ++ public JaxbUnmarshaller(JAXBContext ctx) throws JAXBException { ++ unmarshaller = ctx.createUnmarshaller(); ++ } ++ ++ public synchronized void setSchema(Schema schema) { ++ unmarshaller.setSchema(schema); ++ } ++ ++ public synchronized Object unmarshal(InputStream is) throws JAXBException { ++ return unmarshaller.unmarshal(is); ++ } ++ ++ public synchronized Object unmarshal(Reader reader) throws JAXBException { ++ return unmarshaller.unmarshal(reader); ++ } ++ ++ public Object unmarshal(String str) throws JAXBException { ++ return unmarshal(new StringReader(str)); ++ } ++} +Index: src/test/resources/city.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/resources/city.xml (revision ) ++++ src/test/resources/city.xml (revision ) +@@ -0,0 +1,4 @@ ++Санкт-Петербург ++ +\ No newline at end of file +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1508793189000) ++++ pom.xml (revision ) +@@ -32,6 +32,14 @@ + + + org.apache.maven.plugins ++ maven-surefire-plugin ++ 2.20.1 ++ ++ -Dfile.encoding=UTF-8 ++ ++ ++ ++ org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + +@@ -79,6 +87,17 @@ + jmh-generator-annprocess + RELEASE + provided ++ ++ ++ com.google.guava ++ guava ++ 21.0 ++ ++ ++ junit ++ junit ++ 4.12 ++ test + + + diff --git a/2_08_StAX.patch b/2_08_StAX.patch new file mode 100644 index 000000000..228cca7b1 --- /dev/null +++ b/2_08_StAX.patch @@ -0,0 +1,109 @@ +Index: src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision ) +@@ -0,0 +1,56 @@ ++package ru.javaops.masterjava.xml.util; ++ ++import javax.xml.stream.XMLInputFactory; ++import javax.xml.stream.XMLStreamException; ++import javax.xml.stream.XMLStreamReader; ++import javax.xml.stream.events.XMLEvent; ++import java.io.InputStream; ++ ++public class StaxStreamProcessor implements AutoCloseable { ++ private static final XMLInputFactory FACTORY = XMLInputFactory.newInstance(); ++ ++ private final XMLStreamReader reader; ++ ++ public StaxStreamProcessor(InputStream is) throws XMLStreamException { ++ reader = FACTORY.createXMLStreamReader(is); ++ } ++ ++ public XMLStreamReader getReader() { ++ return reader; ++ } ++ ++ public boolean doUntil(int stopEvent, String value) throws XMLStreamException { ++ while (reader.hasNext()) { ++ int event = reader.next(); ++ if (event == stopEvent) { ++ if (value.equals(getValue(event))) { ++ return true; ++ } ++ } ++ } ++ return false; ++ } ++ ++ public String getValue(int event) throws XMLStreamException { ++ return (event == XMLEvent.CHARACTERS) ? reader.getText() : reader.getLocalName(); ++ } ++ ++ public String getElementValue(String element) throws XMLStreamException { ++ return doUntil(XMLEvent.START_ELEMENT, element) ? reader.getElementText() : null; ++ } ++ ++ public String getText() throws XMLStreamException { ++ return reader.getElementText(); ++ } ++ ++ @Override ++ public void close() { ++ if (reader != null) { ++ try { ++ reader.close(); ++ } catch (XMLStreamException e) { ++ // empty ++ } ++ } ++ } ++} +Index: src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java (revision ) ++++ src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java (revision ) +@@ -0,0 +1,36 @@ ++package ru.javaops.masterjava.xml.util; ++ ++import com.google.common.io.Resources; ++import org.junit.Test; ++ ++import javax.xml.stream.XMLStreamReader; ++import javax.xml.stream.events.XMLEvent; ++ ++public class StaxStreamProcessorTest { ++ @Test ++ public void readCities() throws Exception { ++ try (StaxStreamProcessor processor = ++ new StaxStreamProcessor(Resources.getResource("payload.xml").openStream())) { ++ XMLStreamReader reader = processor.getReader(); ++ while (reader.hasNext()) { ++ int event = reader.next(); ++ if (event == XMLEvent.START_ELEMENT) { ++ if ("City".equals(reader.getLocalName())) { ++ System.out.println(reader.getElementText()); ++ } ++ } ++ } ++ } ++ } ++ ++ @Test ++ public void readCities2() throws Exception { ++ try (StaxStreamProcessor processor = ++ new StaxStreamProcessor(Resources.getResource("payload.xml").openStream())) { ++ String city; ++ while ((city = processor.getElementValue("City")) != null) { ++ System.out.println(city); ++ } ++ } ++ } ++} +\ No newline at end of file diff --git a/2_09_XPath.patch b/2_09_XPath.patch new file mode 100644 index 000000000..f662f3b82 --- /dev/null +++ b/2_09_XPath.patch @@ -0,0 +1,101 @@ +Index: src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java (revision ) +@@ -0,0 +1,58 @@ ++package ru.javaops.masterjava.xml.util; ++ ++import org.w3c.dom.Document; ++import org.xml.sax.SAXException; ++ ++import javax.xml.namespace.QName; ++import javax.xml.parsers.DocumentBuilder; ++import javax.xml.parsers.DocumentBuilderFactory; ++import javax.xml.parsers.ParserConfigurationException; ++import javax.xml.xpath.XPath; ++import javax.xml.xpath.XPathExpression; ++import javax.xml.xpath.XPathExpressionException; ++import javax.xml.xpath.XPathFactory; ++import java.io.IOException; ++import java.io.InputStream; ++ ++public class XPathProcessor { ++ private static final DocumentBuilderFactory DOCUMENT_FACTORY = DocumentBuilderFactory.newInstance(); ++ private static final DocumentBuilder DOCUMENT_BUILDER; ++ ++ private static final XPathFactory XPATH_FACTORY = XPathFactory.newInstance(); ++ private static final XPath XPATH = XPATH_FACTORY.newXPath(); ++ ++ static { ++ DOCUMENT_FACTORY.setNamespaceAware(true); ++ try { ++ DOCUMENT_BUILDER = DOCUMENT_FACTORY.newDocumentBuilder(); ++ } catch (ParserConfigurationException e) { ++ throw new IllegalStateException(e); ++ } ++ } ++ ++ private final Document doc; ++ ++ public XPathProcessor(InputStream is) { ++ try { ++ doc = DOCUMENT_BUILDER.parse(is); ++ } catch (SAXException | IOException e) { ++ throw new IllegalArgumentException(e); ++ } ++ } ++ ++ public static synchronized XPathExpression getExpression(String exp) { ++ try { ++ return XPATH.compile(exp); ++ } catch (XPathExpressionException e) { ++ throw new IllegalArgumentException(e); ++ } ++ } ++ ++ public T evaluate(XPathExpression expression, QName type) { ++ try { ++ return (T) expression.evaluate(doc, type); ++ } catch (XPathExpressionException e) { ++ throw new IllegalArgumentException(e); ++ } ++ } ++} +Index: src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java (revision ) ++++ src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java (revision ) +@@ -0,0 +1,26 @@ ++package ru.javaops.masterjava.xml.util; ++ ++import com.google.common.io.Resources; ++import org.junit.Test; ++import org.w3c.dom.NodeList; ++ ++import javax.xml.xpath.XPathConstants; ++import javax.xml.xpath.XPathExpression; ++import java.io.InputStream; ++import java.util.stream.IntStream; ++ ++public class XPathProcessorTest { ++ @Test ++ public void getCities() throws Exception { ++ try (InputStream is = ++ Resources.getResource("payload.xml").openStream()) { ++ XPathProcessor processor = new XPathProcessor(is); ++ XPathExpression expression = ++ XPathProcessor.getExpression("/*[name()='Payload']/*[name()='Cities']/*[name()='City']/text()"); ++ NodeList nodes = processor.evaluate(expression, XPathConstants.NODESET); ++ IntStream.range(0, nodes.getLength()).forEach( ++ i -> System.out.println(nodes.item(i).getNodeValue()) ++ ); ++ } ++ } ++} +\ No newline at end of file diff --git a/2_10_Xslt.patch b/2_10_Xslt.patch new file mode 100644 index 000000000..fceab9e55 --- /dev/null +++ b/2_10_Xslt.patch @@ -0,0 +1,95 @@ +Index: src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (revision ) +@@ -0,0 +1,43 @@ ++package ru.javaops.masterjava.xml.util; ++ ++import javax.xml.transform.*; ++import javax.xml.transform.stream.StreamResult; ++import javax.xml.transform.stream.StreamSource; ++import java.io.*; ++import java.nio.charset.StandardCharsets; ++ ++public class XsltProcessor { ++ private static TransformerFactory FACTORY = TransformerFactory.newInstance(); ++ private final Transformer xformer; ++ ++ public XsltProcessor(InputStream xslInputStream) { ++ this(new BufferedReader(new InputStreamReader(xslInputStream, StandardCharsets.UTF_8))); ++ } ++ ++ public XsltProcessor(Reader xslReader) { ++ try { ++ Templates template = FACTORY.newTemplates(new StreamSource(xslReader)); ++ xformer = template.newTransformer(); ++ } catch (TransformerConfigurationException e) { ++ throw new IllegalStateException("XSLT transformer creation failed: " + e.toString(), e); ++ } ++ } ++ ++ public String transform(InputStream xmlInputStream) throws TransformerException { ++ StringWriter out = new StringWriter(); ++ transform(xmlInputStream, out); ++ return out.getBuffer().toString(); ++ } ++ ++ public void transform(InputStream xmlInputStream, Writer result) throws TransformerException { ++ transform(new BufferedReader(new InputStreamReader(xmlInputStream, StandardCharsets.UTF_8)), result); ++ } ++ ++ public void transform(Reader sourceReader, Writer result) throws TransformerException { ++ xformer.transform(new StreamSource(sourceReader), new StreamResult(result)); ++ } ++ ++ public static String getXsltHeader(String xslt) { ++ return "\n"; ++ } ++} +Index: src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java (revision ) ++++ src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java (revision ) +@@ -0,0 +1,18 @@ ++package ru.javaops.masterjava.xml.util; ++ ++import com.google.common.io.Resources; ++import org.junit.Test; ++ ++import java.io.InputStream; ++ ++public class XsltProcessorTest { ++ @Test ++ public void transform() throws Exception { ++ try (InputStream xslInputStream = Resources.getResource("cities.xsl").openStream(); ++ InputStream xmlInputStream = Resources.getResource("payload.xml").openStream()) { ++ ++ XsltProcessor processor = new XsltProcessor(xslInputStream); ++ System.out.println(processor.transform(xmlInputStream)); ++ } ++ } ++} +Index: src/main/resources/cities.xsl +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/cities.xsl (revision ) ++++ src/main/resources/cities.xsl (revision ) +@@ -0,0 +1,9 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ +\ No newline at end of file diff --git a/3_1_HW2_schema.patch b/3_1_HW2_schema.patch new file mode 100644 index 000000000..a105e2de6 --- /dev/null +++ b/3_1_HW2_schema.patch @@ -0,0 +1,815 @@ +Index: src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (revision 1819bf210a3125dd3597a87c3bbcfd584ad7a254) ++++ src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (revision ) +@@ -33,6 +33,14 @@ + public ObjectFactory() { + } + ++ /** ++ * Create an instance of {@link Project } ++ * ++ */ ++ public Project createProject() { ++ return new Project(); ++ } ++ + /** + * Create an instance of {@link Payload } + * +@@ -41,6 +49,14 @@ + return new Payload(); + } + ++ /** ++ * Create an instance of {@link Project.Group } ++ * ++ */ ++ public Project.Group createProjectGroup() { ++ return new Project.Group(); ++ } ++ + /** + * Create an instance of {@link User } + * +@@ -49,6 +65,14 @@ + return new User(); + } + ++ /** ++ * Create an instance of {@link Payload.Projects } ++ * ++ */ ++ public Payload.Projects createPayloadProjects() { ++ return new Payload.Projects(); ++ } ++ + /** + * Create an instance of {@link Payload.Cities } + * +Index: src/test/resources/payload.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/resources/payload.xml (revision 1819bf210a3125dd3597a87c3bbcfd584ad7a254) ++++ src/test/resources/payload.xml (revision ) +@@ -1,23 +1,31 @@ + +- +- +- gmail@gmail.com +- Full Name +- +- +- admin@javaops.ru +- Admin +- +- +- mail@yandex.ru +- Deleted +- +- ++ ++ ++ ++ Topjava ++ ++ ++ ++ ++ ++ Masterjava ++ ++ ++ + + Санкт-Петербург ++ Москва + Киев + Минск + ++ ++ Full Name ++ Admin ++ Deleted ++ User1 ++ User2 ++ User3 ++ + +\ No newline at end of file +Index: src/main/java/ru/javaops/masterjava/xml/schema/Payload.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (revision 1819bf210a3125dd3597a87c3bbcfd584ad7a254) ++++ src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (revision ) +@@ -1,13 +1,9 @@ + + package ru.javaops.masterjava.xml.schema; + ++import javax.xml.bind.annotation.*; + import java.util.ArrayList; + import java.util.List; +-import javax.xml.bind.annotation.XmlAccessType; +-import javax.xml.bind.annotation.XmlAccessorType; +-import javax.xml.bind.annotation.XmlElement; +-import javax.xml.bind.annotation.XmlRootElement; +-import javax.xml.bind.annotation.XmlType; + + + /** +@@ -19,7 +15,18 @@ + * <complexType> + * <complexContent> + * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> +- * <all> ++ * <sequence> ++ * <element name="Projects"> ++ * <complexType> ++ * <complexContent> ++ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> ++ * <sequence maxOccurs="unbounded"> ++ * <element ref="{http://javaops.ru}Project"/> ++ * </sequence> ++ * </restriction> ++ * </complexContent> ++ * </complexType> ++ * </element> + * <element name="Cities"> + * <complexType> + * <complexContent> +@@ -42,7 +49,7 @@ + * </complexContent> + * </complexType> + * </element> +- * </all> ++ * </sequence> + * </restriction> + * </complexContent> + * </complexType> +@@ -52,16 +59,44 @@ + */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = { +- ++ "projects", ++ "cities", ++ "users" + }) + @XmlRootElement(name = "Payload", namespace = "http://javaops.ru") + public class Payload { + ++ @XmlElement(name = "Projects", namespace = "http://javaops.ru", required = true) ++ protected Payload.Projects projects; + @XmlElement(name = "Cities", namespace = "http://javaops.ru", required = true) + protected Payload.Cities cities; + @XmlElement(name = "Users", namespace = "http://javaops.ru", required = true) + protected Payload.Users users; + ++ /** ++ * Gets the value of the projects property. ++ * ++ * @return ++ * possible object is ++ * {@link Payload.Projects } ++ * ++ */ ++ public Payload.Projects getProjects() { ++ return projects; ++ } ++ ++ /** ++ * Sets the value of the projects property. ++ * ++ * @param value ++ * allowed object is ++ * {@link Payload.Projects } ++ * ++ */ ++ public void setProjects(Payload.Projects value) { ++ this.projects = value; ++ } ++ + /** + * Gets the value of the cities property. + * +@@ -171,6 +206,66 @@ + } + + ++ /** ++ *

Java class for anonymous complex type. ++ * ++ *

The following schema fragment specifies the expected content contained within this class. ++ * ++ *

++     * <complexType>
++     *   <complexContent>
++     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
++     *       <sequence maxOccurs="unbounded">
++     *         <element ref="{http://javaops.ru}Project"/>
++     *       </sequence>
++     *     </restriction>
++     *   </complexContent>
++     * </complexType>
++     * 
++ * ++ * ++ */ ++ @XmlAccessorType(XmlAccessType.FIELD) ++ @XmlType(name = "", propOrder = { ++ "project" ++ }) ++ public static class Projects { ++ ++ @XmlElement(name = "Project", namespace = "http://javaops.ru", required = true) ++ protected List project; ++ ++ /** ++ * Gets the value of the project property. ++ * ++ *

++ * This accessor method returns a reference to the live list, ++ * not a snapshot. Therefore any modification you make to the ++ * returned list will be present inside the JAXB object. ++ * This is why there is not a set method for the project property. ++ * ++ *

++ * For example, to add a new item, do as follows: ++ *

++         *    getProject().add(newItem);
++         * 
++ * ++ * ++ *

++ * Objects of the following type(s) are allowed in the list ++ * {@link Project } ++ * ++ * ++ */ ++ public List getProject() { ++ if (project == null) { ++ project = new ArrayList(); ++ } ++ return this.project; ++ } ++ ++ } ++ ++ + /** + *

Java class for anonymous complex type. + * +Index: src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java (revision ) +@@ -0,0 +1,40 @@ ++ ++package ru.javaops.masterjava.xml.schema; ++ ++import javax.xml.bind.annotation.XmlEnum; ++import javax.xml.bind.annotation.XmlType; ++ ++ ++/** ++ *

Java class for groupType. ++ * ++ *

The following schema fragment specifies the expected content contained within this class. ++ *

++ *

++ * <simpleType name="groupType">
++ *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
++ *     <enumeration value="REGISTERING"/>
++ *     <enumeration value="CURRENT"/>
++ *     <enumeration value="FINISHED"/>
++ *   </restriction>
++ * </simpleType>
++ * 
++ * ++ */ ++@XmlType(name = "groupType", namespace = "http://javaops.ru") ++@XmlEnum ++public enum GroupType { ++ ++ REGISTERING, ++ CURRENT, ++ FINISHED; ++ ++ public String value() { ++ return name(); ++ } ++ ++ public static GroupType fromValue(String v) { ++ return valueOf(v); ++ } ++ ++} +Index: src/main/java/ru/javaops/masterjava/xml/schema/Project.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/Project.java (revision ) ++++ src/main/java/ru/javaops/masterjava/xml/schema/Project.java (revision ) +@@ -0,0 +1,216 @@ ++ ++package ru.javaops.masterjava.xml.schema; ++ ++import javax.xml.bind.annotation.*; ++import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; ++import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; ++import java.util.ArrayList; ++import java.util.List; ++ ++ ++/** ++ *

Java class for anonymous complex type. ++ * ++ *

The following schema fragment specifies the expected content contained within this class. ++ * ++ *

++ * <complexType>
++ *   <complexContent>
++ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
++ *       <sequence>
++ *         <element name="description" type="{http://www.w3.org/2001/XMLSchema}string"/>
++ *         <sequence maxOccurs="unbounded">
++ *           <element name="Group">
++ *             <complexType>
++ *               <complexContent>
++ *                 <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
++ *                   <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
++ *                   <attribute name="type" use="required" type="{http://javaops.ru}groupType" />
++ *                 </restriction>
++ *               </complexContent>
++ *             </complexType>
++ *           </element>
++ *         </sequence>
++ *       </sequence>
++ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
++ *     </restriction>
++ *   </complexContent>
++ * </complexType>
++ * 
++ * ++ * ++ */ ++@XmlAccessorType(XmlAccessType.FIELD) ++@XmlType(name = "", propOrder = { ++ "description", ++ "group" ++}) ++@XmlRootElement(name = "Project", namespace = "http://javaops.ru") ++public class Project { ++ ++ @XmlElement(namespace = "http://javaops.ru", required = true) ++ protected String description; ++ @XmlElement(name = "Group", namespace = "http://javaops.ru", required = true) ++ protected List group; ++ @XmlAttribute(name = "name", required = true) ++ protected String name; ++ ++ /** ++ * Gets the value of the description property. ++ * ++ * @return ++ * possible object is ++ * {@link String } ++ * ++ */ ++ public String getDescription() { ++ return description; ++ } ++ ++ /** ++ * Sets the value of the description property. ++ * ++ * @param value ++ * allowed object is ++ * {@link String } ++ * ++ */ ++ public void setDescription(String value) { ++ this.description = value; ++ } ++ ++ /** ++ * Gets the value of the group property. ++ * ++ *

++ * This accessor method returns a reference to the live list, ++ * not a snapshot. Therefore any modification you make to the ++ * returned list will be present inside the JAXB object. ++ * This is why there is not a set method for the group property. ++ * ++ *

++ * For example, to add a new item, do as follows: ++ *

++     *    getGroup().add(newItem);
++     * 
++ * ++ * ++ *

++ * Objects of the following type(s) are allowed in the list ++ * {@link Project.Group } ++ * ++ * ++ */ ++ public List getGroup() { ++ if (group == null) { ++ group = new ArrayList(); ++ } ++ return this.group; ++ } ++ ++ /** ++ * Gets the value of the name property. ++ * ++ * @return ++ * possible object is ++ * {@link String } ++ * ++ */ ++ public String getName() { ++ return name; ++ } ++ ++ /** ++ * Sets the value of the name property. ++ * ++ * @param value ++ * allowed object is ++ * {@link String } ++ * ++ */ ++ public void setName(String value) { ++ this.name = value; ++ } ++ ++ ++ /** ++ *

Java class for anonymous complex type. ++ * ++ *

The following schema fragment specifies the expected content contained within this class. ++ * ++ *

++     * <complexType>
++     *   <complexContent>
++     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
++     *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
++     *       <attribute name="type" use="required" type="{http://javaops.ru}groupType" />
++     *     </restriction>
++     *   </complexContent>
++     * </complexType>
++     * 
++ * ++ * ++ */ ++ @XmlAccessorType(XmlAccessType.FIELD) ++ @XmlType(name = "") ++ public static class Group { ++ ++ @XmlAttribute(name = "name", required = true) ++ @XmlJavaTypeAdapter(CollapsedStringAdapter.class) ++ @XmlID ++ @XmlSchemaType(name = "ID") ++ protected String name; ++ @XmlAttribute(name = "type", required = true) ++ protected GroupType type; ++ ++ /** ++ * Gets the value of the name property. ++ * ++ * @return ++ * possible object is ++ * {@link String } ++ * ++ */ ++ public String getName() { ++ return name; ++ } ++ ++ /** ++ * Sets the value of the name property. ++ * ++ * @param value ++ * allowed object is ++ * {@link String } ++ * ++ */ ++ public void setName(String value) { ++ this.name = value; ++ } ++ ++ /** ++ * Gets the value of the type property. ++ * ++ * @return ++ * possible object is ++ * {@link GroupType } ++ * ++ */ ++ public GroupType getType() { ++ return type; ++ } ++ ++ /** ++ * Sets the value of the type property. ++ * ++ * @param value ++ * allowed object is ++ * {@link GroupType } ++ * ++ */ ++ public void setType(GroupType value) { ++ this.type = value; ++ } ++ ++ } ++ ++} +Index: src/main/resources/payload.xsd +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/payload.xsd (revision 1819bf210a3125dd3597a87c3bbcfd584ad7a254) ++++ src/main/resources/payload.xsd (revision ) +@@ -6,7 +6,14 @@ + + + +- ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -21,18 +28,39 @@ + + + +- ++ + + + +- ++ + + +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ + +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + +@@ -44,7 +72,13 @@ + + + +- ++ ++ ++ ++ ++ ++ ++ + + + +@@ -53,4 +87,11 @@ + + + ++ ++ ++ ++ ++ ++ ++ + +\ No newline at end of file +Index: src/main/java/ru/javaops/masterjava/xml/schema/User.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/User.java (revision 1819bf210a3125dd3597a87c3bbcfd584ad7a254) ++++ src/main/java/ru/javaops/masterjava/xml/schema/User.java (revision ) +@@ -1,14 +1,9 @@ + + package ru.javaops.masterjava.xml.schema; + +-import javax.xml.bind.annotation.XmlAccessType; +-import javax.xml.bind.annotation.XmlAccessorType; +-import javax.xml.bind.annotation.XmlAttribute; +-import javax.xml.bind.annotation.XmlElement; +-import javax.xml.bind.annotation.XmlIDREF; +-import javax.xml.bind.annotation.XmlRootElement; +-import javax.xml.bind.annotation.XmlSchemaType; +-import javax.xml.bind.annotation.XmlType; ++import javax.xml.bind.annotation.*; ++import java.util.ArrayList; ++import java.util.List; + + + /** +@@ -18,16 +13,14 @@ + * + *
+  * <complexType>
+- *   <complexContent>
+- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+- *       <sequence>
+- *         <element name="email" type="{http://www.w3.org/2001/XMLSchema}string"/>
+- *         <element name="fullName" type="{http://www.w3.org/2001/XMLSchema}string"/>
+- *       </sequence>
++ *   <simpleContent>
++ *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
++ *       <attribute name="email" type="{http://javaops.ru}emailAddressType" />
+  *       <attribute name="flag" use="required" type="{http://javaops.ru}flagType" />
+  *       <attribute name="city" use="required" type="{http://www.w3.org/2001/XMLSchema}IDREF" />
+- *     </restriction>
+- *   </complexContent>
++ *       <attribute name="groupRefs" type="{http://www.w3.org/2001/XMLSchema}IDREFS" />
++ *     </extension>
++ *   </simpleContent>
+  * </complexType>
+  * 
+ * +@@ -35,69 +28,72 @@ + */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = { +- "email", +- "fullName" ++ "value" + }) + @XmlRootElement(name = "User", namespace = "http://javaops.ru") + public class User { + +- @XmlElement(namespace = "http://javaops.ru", required = true) ++ @XmlValue ++ protected String value; ++ @XmlAttribute(name = "email") + protected String email; +- @XmlElement(namespace = "http://javaops.ru", required = true) +- protected String fullName; + @XmlAttribute(name = "flag", required = true) + protected FlagType flag; + @XmlAttribute(name = "city", required = true) + @XmlIDREF + @XmlSchemaType(name = "IDREF") + protected Object city; ++ @XmlAttribute(name = "groupRefs") ++ @XmlIDREF ++ @XmlSchemaType(name = "IDREFS") ++ protected List groupRefs; + + /** +- * Gets the value of the email property. ++ * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ +- public String getEmail() { +- return email; ++ public String getValue() { ++ return value; + } + + /** +- * Sets the value of the email property. ++ * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ +- public void setEmail(String value) { +- this.email = value; ++ public void setValue(String value) { ++ this.value = value; + } + + /** +- * Gets the value of the fullName property. ++ * Gets the value of the email property. + * + * @return + * possible object is + * {@link String } + * + */ +- public String getFullName() { +- return fullName; ++ public String getEmail() { ++ return email; + } + + /** +- * Sets the value of the fullName property. ++ * Sets the value of the email property. + * + * @param value + * allowed object is + * {@link String } + * + */ +- public void setFullName(String value) { +- this.fullName = value; ++ public void setEmail(String value) { ++ this.email = value; + } + + /** +@@ -148,4 +144,37 @@ + this.city = value; + } + ++ /** ++ * Gets the value of the groupRefs property. ++ * ++ *

++ * This accessor method returns a reference to the live list, ++ * not a snapshot. Therefore any modification you make to the ++ * returned list will be present inside the JAXB object. ++ * This is why there is not a set method for the groupRefs property. ++ * ++ *

++ * For example, to add a new item, do as follows: ++ *

++     *    getGroupRefs().add(newItem);
++     * 
++ * ++ * ++ *

++ * Objects of the following type(s) are allowed in the list ++ * {@link Object } ++ * ++ * ++ */ ++ public List getGroupRefs() { ++ if (groupRefs == null) { ++ groupRefs = new ArrayList(); ++ } ++ return this.groupRefs; ++ } ++ ++ @Override ++ public String toString() { ++ return value + '(' + email + ')'; ++ } + } diff --git a/3_2_HW2_JAXB_HTML.patch b/3_2_HW2_JAXB_HTML.patch new file mode 100644 index 000000000..dc83677a1 --- /dev/null +++ b/3_2_HW2_JAXB_HTML.patch @@ -0,0 +1,132 @@ +Index: src/test/java/ru/javaops/masterjava/MainXml.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javaops/masterjava/MainXml.java (revision ) ++++ src/test/java/ru/javaops/masterjava/MainXml.java (revision ) +@@ -0,0 +1,78 @@ ++package ru.javaops.masterjava; ++ ++import com.google.common.io.Resources; ++import j2html.tags.ContainerTag; ++import one.util.streamex.StreamEx; ++import ru.javaops.masterjava.xml.schema.ObjectFactory; ++import ru.javaops.masterjava.xml.schema.Payload; ++import ru.javaops.masterjava.xml.schema.Project; ++import ru.javaops.masterjava.xml.schema.User; ++import ru.javaops.masterjava.xml.util.JaxbParser; ++import ru.javaops.masterjava.xml.util.Schemas; ++ ++import java.io.InputStream; ++import java.io.Writer; ++import java.net.URL; ++import java.nio.file.Files; ++import java.nio.file.Paths; ++import java.util.*; ++import java.util.stream.Collectors; ++ ++import static j2html.TagCreator.*; ++ ++public class MainXml { ++ ++ public static void main(String[] args) throws Exception { ++ if (args.length != 1) { ++ System.out.println("Format: projectName"); ++ System.exit(1); ++ } ++ String projectName = args[0]; ++ URL payloadUrl = Resources.getResource("payload.xml"); ++ ++ Set users = parseByJaxb(projectName, payloadUrl); ++ users.forEach(System.out::println); ++ ++ String html = toHtml(users, projectName); ++ System.out.println(html); ++ try (Writer writer = Files.newBufferedWriter(Paths.get("out/users.html"))) { ++ writer.write(html); ++ } ++ } ++ ++ private static Set parseByJaxb(String projectName, URL payloadUrl) throws Exception { ++ JaxbParser parser = new JaxbParser(ObjectFactory.class); ++ parser.setSchema(Schemas.ofClasspath("payload.xsd")); ++ Payload payload; ++ try (InputStream is = payloadUrl.openStream()) { ++ payload = parser.unmarshal(is); ++ } ++ ++ Project project = StreamEx.of(payload.getProjects().getProject()) ++ .filter(p -> p.getName().equals(projectName)) ++ .findAny() ++ .orElseThrow(() -> new IllegalArgumentException("Invalid project name '" + projectName + '\'')); ++ ++ final Set groups = new HashSet<>(project.getGroup()); // identity compare ++ return StreamEx.of(payload.getUsers().getUser()) ++ .filter(u -> !Collections.disjoint(groups, u.getGroupRefs())) ++ .collect( ++ Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getValue).thenComparing(User::getEmail))) ++ ); ++ } ++ ++ private static String toHtml(Set users, String projectName) { ++ final ContainerTag table = table().with( ++ tr().with(th("FullName"), th("email"))) ++ .attr("border", "1") ++ .attr("cellpadding", "8") ++ .attr("cellspacing", "0"); ++ ++ users.forEach(u -> table.with(tr().with(td(u.getValue()), td(u.getEmail())))); ++ ++ return html().with( ++ head().with(title(projectName + " users")), ++ body().with(h1(projectName + " users"), table) ++ ).render(); ++ } ++} +Index: src/main/java/ru/javaops/masterjava/Main.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/Main.java (date 1509203382000) ++++ src/main/java/ru/javaops/masterjava/Main.java (date 1509203382000) +@@ -1,14 +0,0 @@ +-package ru.javaops.masterjava; +- +-/** +- * User: gkislin +- * Date: 05.08.2015 +- * +- * @link http://caloriesmng.herokuapp.com/ +- * @link https://github.com/JavaOPs/topjava +- */ +-public class Main { +- public static void main(String[] args) { +- System.out.format("Hello MasterJava!"); +- } +-} +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1509203382000) ++++ pom.xml (revision ) +@@ -94,6 +94,19 @@ + 21.0 + + ++ one.util ++ streamex ++ RELEASE ++ ++ ++ ++ com.j2html ++ j2html ++ RELEASE ++ ++ ++ ++ + junit + junit + 4.12 diff --git a/3_3_HW2_StAX.patch b/3_3_HW2_StAX.patch new file mode 100644 index 000000000..5562a232e --- /dev/null +++ b/3_3_HW2_StAX.patch @@ -0,0 +1,147 @@ +Index: src/test/java/ru/javaops/masterjava/MainXml.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javaops/masterjava/MainXml.java (date 1509203657000) ++++ src/test/java/ru/javaops/masterjava/MainXml.java (revision ) +@@ -1,5 +1,6 @@ + package ru.javaops.masterjava; + ++import com.google.common.base.Splitter; + import com.google.common.io.Resources; + import j2html.tags.ContainerTag; + import one.util.streamex.StreamEx; +@@ -9,7 +10,9 @@ + import ru.javaops.masterjava.xml.schema.User; + import ru.javaops.masterjava.xml.util.JaxbParser; + import ru.javaops.masterjava.xml.util.Schemas; ++import ru.javaops.masterjava.xml.util.StaxStreamProcessor; + ++import javax.xml.stream.events.XMLEvent; + import java.io.InputStream; + import java.io.Writer; + import java.net.URL; +@@ -18,13 +21,16 @@ + import java.util.*; + import java.util.stream.Collectors; + ++import static com.google.common.base.Strings.nullToEmpty; + import static j2html.TagCreator.*; + + public class MainXml { + ++ private static final Comparator USER_COMPARATOR = Comparator.comparing(User::getValue).thenComparing(User::getEmail); ++ + public static void main(String[] args) throws Exception { + if (args.length != 1) { +- System.out.println("Format: projectName"); ++ System.out.println("Required argument: projectName"); + System.exit(1); + } + String projectName = args[0]; +@@ -33,11 +39,16 @@ + Set users = parseByJaxb(projectName, payloadUrl); + users.forEach(System.out::println); + ++ System.out.println(); + String html = toHtml(users, projectName); + System.out.println(html); + try (Writer writer = Files.newBufferedWriter(Paths.get("out/users.html"))) { + writer.write(html); + } ++ ++ System.out.println(); ++ users = processByStax(projectName, payloadUrl); ++ users.forEach(System.out::println); + } + + private static Set parseByJaxb(String projectName, URL payloadUrl) throws Exception { +@@ -57,9 +68,49 @@ + return StreamEx.of(payload.getUsers().getUser()) + .filter(u -> !Collections.disjoint(groups, u.getGroupRefs())) + .collect( +- Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getValue).thenComparing(User::getEmail))) ++ Collectors.toCollection(() -> new TreeSet<>(USER_COMPARATOR)) + ); + } ++ ++ private static Set processByStax(String projectName, URL payloadUrl) throws Exception { ++ ++ try (InputStream is = payloadUrl.openStream()) { ++ StaxStreamProcessor processor = new StaxStreamProcessor(is); ++ final Set groupNames = new HashSet<>(); ++ ++ // Projects loop ++ projects: ++ while (processor.doUntil(XMLEvent.START_ELEMENT, "Project")) { ++ if (projectName.equals(processor.getAttribute("name"))) { ++ // Groups loop ++ String element; ++ while ((element = processor.doUntilAny(XMLEvent.START_ELEMENT, "Project", "Group", "Users")) != null) { ++ if (!element.equals("Group")) { ++ break projects; ++ } ++ groupNames.add(processor.getAttribute("name")); ++ } ++ } ++ } ++ if (groupNames.isEmpty()) { ++ throw new IllegalArgumentException("Invalid " + projectName + " or no groups"); ++ } ++ ++ // Users loop ++ Set users = new TreeSet<>(USER_COMPARATOR); ++ ++ while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { ++ String groupRefs = processor.getAttribute("groupRefs"); ++ if (!Collections.disjoint(groupNames, Splitter.on(' ').splitToList(nullToEmpty(groupRefs)))) { ++ User user = new User(); ++ user.setEmail(processor.getAttribute("email")); ++ user.setValue(processor.getText()); ++ users.add(user); ++ } ++ } ++ return users; ++ } ++ } + + private static String toHtml(Set users, String projectName) { + final ContainerTag table = table().with( +Index: src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (date 1509203657000) ++++ src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision ) +@@ -20,15 +20,26 @@ + } + + public boolean doUntil(int stopEvent, String value) throws XMLStreamException { ++ return doUntilAny(stopEvent, value) != null; ++ } ++ ++ public String getAttribute(String name) throws XMLStreamException { ++ return reader.getAttributeValue(null, name); ++ } ++ ++ public String doUntilAny(int stopEvent, String... values) throws XMLStreamException { + while (reader.hasNext()) { + int event = reader.next(); + if (event == stopEvent) { +- if (value.equals(getValue(event))) { +- return true; ++ String xmlValue = getValue(event); ++ for (String value : values) { ++ if (value.equals(xmlValue)) { ++ return xmlValue; ++ } + } + } + } +- return false; ++ return null; + } + + public String getValue(int event) throws XMLStreamException { diff --git a/3_4_StAX_refactoring.patch b/3_4_StAX_refactoring.patch new file mode 100644 index 000000000..168b15d64 --- /dev/null +++ b/3_4_StAX_refactoring.patch @@ -0,0 +1,158 @@ +Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision 52e6136915e10695a7f83412a9fd977bc2389d7b) ++++ src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision 5918da0d89f8a9146dba4d9e1ca41211807d7d4b) +@@ -5,6 +5,7 @@ + import javax.xml.bind.JAXBContext; + import javax.xml.bind.JAXBException; + import javax.xml.bind.PropertyException; ++import javax.xml.stream.XMLStreamReader; + import javax.xml.transform.stream.StreamSource; + import javax.xml.validation.Schema; + import java.io.*; +@@ -55,6 +56,10 @@ + return (T) jaxbUnmarshaller.unmarshal(str); + } + ++ public T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { ++ return jaxbUnmarshaller.unmarshal(reader, elementClass); ++ } ++ + // Marshaller + public void setMarshallerProperty(String prop, Object value) { + try { +Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision 52e6136915e10695a7f83412a9fd977bc2389d7b) ++++ src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision 5918da0d89f8a9146dba4d9e1ca41211807d7d4b) +@@ -3,6 +3,7 @@ + import javax.xml.bind.JAXBContext; + import javax.xml.bind.JAXBException; + import javax.xml.bind.Unmarshaller; ++import javax.xml.stream.XMLStreamReader; + import javax.xml.validation.Schema; + import java.io.InputStream; + import java.io.Reader; +@@ -30,4 +31,8 @@ + public Object unmarshal(String str) throws JAXBException { + return unmarshal(new StringReader(str)); + } +-} ++ ++ public synchronized T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { ++ return unmarshaller.unmarshal(reader, elementClass).getValue(); ++ } ++} +\ No newline at end of file +Index: src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision 52e6136915e10695a7f83412a9fd977bc2389d7b) ++++ src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision 5918da0d89f8a9146dba4d9e1ca41211807d7d4b) +@@ -15,31 +15,43 @@ + reader = FACTORY.createXMLStreamReader(is); + } + ++ public boolean startElement(String element, String parent) throws XMLStreamException { ++ while (reader.hasNext()) { ++ int event = reader.next(); ++ if (parent != null && isElementEnd(event, parent)) { ++ return false; ++ } ++ if (isElementStart(event, element)) { ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ private boolean isElementStart(int event, String el) { ++ return event == XMLEvent.START_ELEMENT && el.equals(reader.getLocalName()); ++ } ++ ++ private boolean isElementEnd(int event, String el) { ++ return event == XMLEvent.END_ELEMENT && el.equals(reader.getLocalName()); ++ } ++ + public XMLStreamReader getReader() { + return reader; + } + +- public boolean doUntil(int stopEvent, String value) throws XMLStreamException { +- return doUntilAny(stopEvent, value) != null; +- } +- + public String getAttribute(String name) throws XMLStreamException { + return reader.getAttributeValue(null, name); + } + +- public String doUntilAny(int stopEvent, String... values) throws XMLStreamException { ++ public boolean doUntil(int stopEvent, String value) throws XMLStreamException { + while (reader.hasNext()) { + int event = reader.next(); +- if (event == stopEvent) { +- String xmlValue = getValue(event); +- for (String value : values) { +- if (value.equals(xmlValue)) { +- return xmlValue; +- } +- } ++ if (event == stopEvent && value.equals(getValue(event))) { ++ return true; + } + } +- return null; ++ return false; + } + + public String getValue(int event) throws XMLStreamException { +Index: src/test/java/ru/javaops/masterjava/MainXml.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javaops/masterjava/MainXml.java (revision 52e6136915e10695a7f83412a9fd977bc2389d7b) ++++ src/test/java/ru/javaops/masterjava/MainXml.java (revision 5918da0d89f8a9146dba4d9e1ca41211807d7d4b) +@@ -80,16 +80,12 @@ + + // Projects loop + projects: +- while (processor.doUntil(XMLEvent.START_ELEMENT, "Project")) { ++ while (processor.startElement("Project", "Projects")) { + if (projectName.equals(processor.getAttribute("name"))) { +- // Groups loop +- String element; +- while ((element = processor.doUntilAny(XMLEvent.START_ELEMENT, "Project", "Group", "Users")) != null) { +- if (!element.equals("Group")) { +- break projects; +- } ++ while (processor.startElement("Group", "Project")) { + groupNames.add(processor.getAttribute("name")); + } ++ break; + } + } + if (groupNames.isEmpty()) { +@@ -99,12 +95,11 @@ + // Users loop + Set users = new TreeSet<>(USER_COMPARATOR); + ++ JaxbParser parser = new JaxbParser(User.class); + while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { + String groupRefs = processor.getAttribute("groupRefs"); + if (!Collections.disjoint(groupNames, Splitter.on(' ').splitToList(nullToEmpty(groupRefs)))) { +- User user = new User(); +- user.setEmail(processor.getAttribute("email")); +- user.setValue(processor.getText()); ++ User user = parser.unmarshal(processor.getReader(), User.class); + users.add(user); + } + } diff --git a/3_5_HW2_xslt.patch b/3_5_HW2_xslt.patch new file mode 100644 index 000000000..e7ea65589 --- /dev/null +++ b/3_5_HW2_xslt.patch @@ -0,0 +1,104 @@ +Index: src/main/resources/groups.xsl +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/resources/groups.xsl (revision ) ++++ src/main/resources/groups.xsl (revision ) +@@ -0,0 +1,37 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ <xsl:value-of select="$projectName"/> groups ++ ++ ++ ++

++ groups ++

++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
GroupType
++ ++ ++ ++
++ ++ ++
++
+\ No newline at end of file +Index: src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (date 1509357844000) ++++ src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (revision ) +@@ -40,4 +40,8 @@ + public static String getXsltHeader(String xslt) { + return "\n"; + } ++ ++ public void setParameter(String name, String value) { ++ xformer.setParameter(name, value); ++ } + } +Index: src/test/java/ru/javaops/masterjava/MainXml.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- src/test/java/ru/javaops/masterjava/MainXml.java (date 1509357844000) ++++ src/test/java/ru/javaops/masterjava/MainXml.java (revision ) +@@ -11,6 +11,7 @@ + import ru.javaops.masterjava.xml.util.JaxbParser; + import ru.javaops.masterjava.xml.util.Schemas; + import ru.javaops.masterjava.xml.util.StaxStreamProcessor; ++import ru.javaops.masterjava.xml.util.XsltProcessor; + + import java.io.InputStream; + import java.io.Writer; +@@ -48,6 +49,12 @@ + System.out.println(); + users = processByStax(projectName, payloadUrl); + users.forEach(System.out::println); ++ ++ System.out.println(); ++ html = transform(projectName, payloadUrl); ++ try (Writer writer = Files.newBufferedWriter(Paths.get("out/groups.html"))) { ++ writer.write(html); ++ } + } + + private static Set parseByJaxb(String projectName, URL payloadUrl) throws Exception { +@@ -119,4 +126,13 @@ + body().with(h1(projectName + " users"), table) + ).render(); + } ++ ++ private static String transform(String projectName, URL payloadUrl) throws Exception { ++ URL xsl = Resources.getResource("groups.xsl"); ++ try (InputStream xmlStream = payloadUrl.openStream(); InputStream xslStream = xsl.openStream()) { ++ XsltProcessor processor = new XsltProcessor(xslStream); ++ processor.setParameter("projectName", projectName); ++ return processor.transform(xmlStream); ++ } ++ } + } diff --git a/3_6_multimodule.patch b/3_6_multimodule.patch new file mode 100644 index 000000000..87522e64f --- /dev/null +++ b/3_6_multimodule.patch @@ -0,0 +1,294 @@ +Index: common/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- common/pom.xml (revision ) ++++ common/pom.xml (revision ) +@@ -0,0 +1,21 @@ ++ ++ ++ 4.0.0 ++ ++ ++ ru.javaops ++ parent ++ ../parent/pom.xml ++ 1.0-SNAPSHOT ++ ++ ++ common ++ 1.0-SNAPSHOT ++ jar ++ Common ++ ++ ++ ++ +\ No newline at end of file +Index: parent/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- parent/pom.xml (revision ) ++++ parent/pom.xml (revision ) +@@ -0,0 +1,69 @@ ++ ++ ++ 4.0.0 ++ ++ ru.javaops ++ parent ++ pom ++ 1.0-SNAPSHOT ++ Parent ++ ++ ++ 1.8 ++ UTF-8 ++ UTF-8 ++ ++ ++ ++ install ++ ++ ++ org.apache.maven.plugins ++ maven-compiler-plugin ++ 3.7.0 ++ ++ ${java.version} ++ ${java.version} ++ ++ ++ ++ org.apache.maven.plugins ++ maven-surefire-plugin ++ 2.20.1 ++ ++ -Dfile.encoding=UTF-8 ++ ++ ++ ++ ++ ++ ++ ++ com.google.guava ++ guava ++ 23.3-jre ++ ++ ++ one.util ++ streamex ++ RELEASE ++ ++ ++ ++ ++ junit ++ junit ++ 4.12 ++ test ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +\ No newline at end of file +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (revision 9ee8ecec87012db4d0e272f8651cf4fdbe83b520) ++++ pom.xml (revision ) +@@ -4,119 +4,21 @@ + + ru.javaops + masterjava +- jar ++ pom + + 1.0-SNAPSHOT + + Master Java + https://github.com/JavaOPs/masterjava + +- +- 1.8 +- UTF-8 +- UTF-8 +- +- +- +- masterjava +- install +- +- +- org.apache.maven.plugins +- maven-compiler-plugin +- 3.7.0 +- +- ${java.version} +- ${java.version} +- +- +- +- org.apache.maven.plugins +- maven-surefire-plugin +- 2.20.1 +- +- -Dfile.encoding=UTF-8 +- +- +- +- org.apache.maven.plugins +- maven-shade-plugin +- 3.1.0 +- +- +- package +- +- shade +- +- +- benchmarks +- +- +- org.openjdk.jmh.Main +- +- +- +- +- +- *:* +- +- META-INF/*.SF +- META-INF/*.DSA +- META-INF/*.RSA +- +- +- +- +- +- +- +- +- +- +- +- +- org.openjdk.jmh +- jmh-core +- RELEASE +- +- +- org.openjdk.jmh +- jmh-generator-annprocess +- RELEASE +- provided +- +- +- com.google.guava +- guava +- 21.0 +- +- +- one.util +- streamex +- RELEASE +- +- +- +- com.j2html +- j2html +- RELEASE +- +- +- +- +- junit +- junit +- 4.12 +- test +- +- +- +- +- +- +- +- ++ ++ upload ++ common ++ ++ + +Index: upload/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- upload/pom.xml (revision ) ++++ upload/pom.xml (revision ) +@@ -0,0 +1,39 @@ ++ ++ ++ 4.0.0 ++ ++ ++ ru.javaops ++ parent ++ ../parent/pom.xml ++ 1.0-SNAPSHOT ++ ++ ++ upload ++ 1.0-SNAPSHOT ++ war ++ Upload ++ ++ ++ ++ ++ org.apache.maven.plugins ++ maven-war-plugin ++ 3.2.0 ++ ++ false ++ ++ ++ ++ ++ ++ ++ ++ ru.javaops ++ common ++ ${project.version} ++ ++ ++ +\ No newline at end of file diff --git a/4_10_persist.patch b/4_10_persist.patch new file mode 100644 index 000000000..403395714 --- /dev/null +++ b/4_10_persist.patch @@ -0,0 +1,552 @@ +Index: persist/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- persist/pom.xml (revision ) ++++ persist/pom.xml (revision ) +@@ -0,0 +1,46 @@ ++ ++ ++ 4.0.0 ++ ++ ++ ru.javaops ++ parent ++ ../parent/pom.xml ++ 1.0-SNAPSHOT ++ ++ ++ persist ++ 1.0-SNAPSHOT ++ Persist ++ ++ ++ ++ ${project.groupId} ++ common ++ ${project.version} ++ ++ ++ org.jdbi ++ jdbi ++ 2.78 ++ ++ ++ com.bertoncelj.jdbi.entitymapper ++ jdbi-entity-mapper ++ 1.0.0 ++ ++ ++ org.jdbi ++ jdbi ++ ++ ++ ++ ++ org.postgresql ++ postgresql ++ 42.1.4 ++ ++ ++ +\ No newline at end of file +Index: persist/src/main/java/ru/javaops/masterjava/persist/dao/UserDao.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- persist/src/main/java/ru/javaops/masterjava/persist/dao/UserDao.java (revision ) ++++ persist/src/main/java/ru/javaops/masterjava/persist/dao/UserDao.java (revision ) +@@ -0,0 +1,37 @@ ++package ru.javaops.masterjava.persist.dao; ++ ++import com.bertoncelj.jdbi.entitymapper.EntityMapperFactory; ++import org.skife.jdbi.v2.sqlobject.*; ++import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapperFactory; ++import ru.javaops.masterjava.persist.model.User; ++ ++import java.util.List; ++ ++@RegisterMapperFactory(EntityMapperFactory.class) ++public abstract class UserDao implements AbstractDao { ++ ++ public User insert(User user) { ++ if (user.isNew()) { ++ int id = insertGeneratedId(user); ++ user.setId(id); ++ } else { ++ insertWitId(user); ++ } ++ return user; ++ } ++ ++ @SqlUpdate("INSERT INTO users (full_name, email, flag) VALUES (:fullName, :email, CAST(:flag AS user_flag)) ") ++ @GetGeneratedKeys ++ abstract int insertGeneratedId(@BindBean User user); ++ ++ @SqlUpdate("INSERT INTO users (id, full_name, email, flag) VALUES (:id, :fullName, :email, CAST(:flag AS user_flag)) ") ++ abstract void insertWitId(@BindBean User user); ++ ++ @SqlQuery("SELECT * FROM users ORDER BY full_name, email LIMIT :it") ++ public abstract List getWithLimit(@Bind int limit); ++ ++ // http://stackoverflow.com/questions/13223820/postgresql-delete-all-content ++ @SqlUpdate("TRUNCATE users") ++ @Override ++ public abstract void clean(); ++} +Index: persist/src/test/java/ru/javaops/masterjava/persist/UserTestData.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- persist/src/test/java/ru/javaops/masterjava/persist/UserTestData.java (revision ) ++++ persist/src/test/java/ru/javaops/masterjava/persist/UserTestData.java (revision ) +@@ -0,0 +1,37 @@ ++package ru.javaops.masterjava.persist; ++ ++import com.google.common.collect.ImmutableList; ++import ru.javaops.masterjava.persist.dao.UserDao; ++import ru.javaops.masterjava.persist.model.User; ++import ru.javaops.masterjava.persist.model.UserFlag; ++ ++import java.util.List; ++ ++public class UserTestData { ++ public static User ADMIN; ++ public static User DELETED; ++ public static User FULL_NAME; ++ public static User USER1; ++ public static User USER2; ++ public static User USER3; ++ public static List FIST5_USERS; ++ ++ public static void init() { ++ ADMIN = new User("Admin", "admin@javaops.ru", UserFlag.superuser); ++ DELETED = new User("Deleted", "deleted@yandex.ru", UserFlag.deleted); ++ FULL_NAME = new User("Full Name", "gmail@gmail.com", UserFlag.active); ++ USER1 = new User("User1", "user1@gmail.com", UserFlag.active); ++ USER2 = new User("User2", "user2@yandex.ru", UserFlag.active); ++ USER3 = new User("User3", "user3@yandex.ru", UserFlag.active); ++ FIST5_USERS = ImmutableList.of(ADMIN, DELETED, FULL_NAME, USER1, USER2); ++ } ++ ++ public static void setUp() { ++ UserDao dao = DBIProvider.getDao(UserDao.class); ++ dao.clean(); ++ DBIProvider.getDBI().useTransaction((conn, status) -> { ++ FIST5_USERS.forEach(dao::insert); ++ dao.insert(USER3); ++ }); ++ } ++} +Index: config_templates/sql/initDB.sql +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- config_templates/sql/initDB.sql (revision ) ++++ config_templates/sql/initDB.sql (revision ) +@@ -0,0 +1,15 @@ ++DROP TABLE IF EXISTS users; ++DROP SEQUENCE IF EXISTS user_seq; ++DROP TYPE IF EXISTS user_flag; ++ ++CREATE TYPE user_flag AS ENUM ('active', 'deleted', 'superuser'); ++ ++CREATE SEQUENCE user_seq START 100000; ++ ++CREATE TABLE users ( ++ id INTEGER PRIMARY KEY DEFAULT nextval('user_seq'), ++ full_name TEXT NOT NULL, ++ email TEXT NOT NULL, ++ flag user_flag NOT NULL ++); ++ +Index: persist/src/test/java/ru/javaops/masterjava/persist/dao/AbstractDaoTest.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- persist/src/test/java/ru/javaops/masterjava/persist/dao/AbstractDaoTest.java (revision ) ++++ persist/src/test/java/ru/javaops/masterjava/persist/dao/AbstractDaoTest.java (revision ) +@@ -0,0 +1,16 @@ ++package ru.javaops.masterjava.persist.dao; ++ ++import ru.javaops.masterjava.persist.DBIProvider; ++import ru.javaops.masterjava.persist.DBITestProvider; ++ ++public abstract class AbstractDaoTest { ++ static { ++ DBITestProvider.initDBI(); ++ } ++ ++ protected DAO dao; ++ ++ protected AbstractDaoTest(Class daoClass) { ++ this.dao = DBIProvider.getDao(daoClass); ++ } ++} +Index: persist/src/main/java/ru/javaops/masterjava/persist/model/BaseEntity.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- persist/src/main/java/ru/javaops/masterjava/persist/model/BaseEntity.java (revision ) ++++ persist/src/main/java/ru/javaops/masterjava/persist/model/BaseEntity.java (revision ) +@@ -0,0 +1,37 @@ ++package ru.javaops.masterjava.persist.model; ++ ++abstract public class BaseEntity { ++ protected BaseEntity() { ++ } ++ ++ protected BaseEntity(Integer id) { ++ this.id = id; ++ } ++ ++ protected Integer id; ++ ++ public Integer getId() { ++ return id; ++ } ++ ++ protected void setId(Integer id) { ++ this.id = id; ++ } ++ ++ public boolean isNew() { ++ return id == null; ++ } ++ ++ @Override ++ public boolean equals(Object o) { ++ if (this == o) return true; ++ if (o == null || getClass() != o.getClass()) return false; ++ BaseEntity baseEntity = (BaseEntity) o; ++ return id != null && id.equals(baseEntity.id); ++ } ++ ++ @Override ++ public int hashCode() { ++ return id == null ? 0 : id; ++ } ++} +Index: persist/src/main/java/ru/javaops/masterjava/persist/DBIProvider.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- persist/src/main/java/ru/javaops/masterjava/persist/DBIProvider.java (revision ) ++++ persist/src/main/java/ru/javaops/masterjava/persist/DBIProvider.java (revision ) +@@ -0,0 +1,52 @@ ++package ru.javaops.masterjava.persist; ++ ++import org.skife.jdbi.v2.DBI; ++import org.skife.jdbi.v2.logging.SLF4JLog; ++import org.skife.jdbi.v2.tweak.ConnectionFactory; ++import org.slf4j.Logger; ++import ru.javaops.masterjava.persist.dao.AbstractDao; ++ ++import javax.naming.InitialContext; ++import javax.sql.DataSource; ++ ++import static org.slf4j.LoggerFactory.getLogger; ++ ++public class DBIProvider { ++ private static final Logger log = getLogger(DBIProvider.class); ++ ++ private volatile static ConnectionFactory connectionFactory = null; ++ ++ private static class DBIHolder { ++ static final DBI jDBI; ++ ++ static { ++ final DBI dbi; ++ if (connectionFactory != null) { ++ log.info("Init jDBI with connectionFactory"); ++ dbi = new DBI(connectionFactory); ++ } else { ++ try { ++ log.info("Init jDBI with JNDI"); ++ InitialContext ctx = new InitialContext(); ++ dbi = new DBI((DataSource) ctx.lookup("java:/comp/env/jdbc/masterjava")); ++ } catch (Exception ex) { ++ throw new IllegalStateException("PostgreSQL initialization failed", ex); ++ } ++ } ++ jDBI = dbi; ++ jDBI.setSQLLog(new SLF4JLog()); ++ } ++ } ++ ++ public static void init(ConnectionFactory connectionFactory) { ++ DBIProvider.connectionFactory = connectionFactory; ++ } ++ ++ public static DBI getDBI() { ++ return DBIHolder.jDBI; ++ } ++ ++ public static T getDao(Class daoClass) { ++ return DBIHolder.jDBI.onDemand(daoClass); ++ } ++} +Index: persist/src/main/java/ru/javaops/masterjava/persist/dao/AbstractDao.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- persist/src/main/java/ru/javaops/masterjava/persist/dao/AbstractDao.java (revision ) ++++ persist/src/main/java/ru/javaops/masterjava/persist/dao/AbstractDao.java (revision ) +@@ -0,0 +1,5 @@ ++package ru.javaops.masterjava.persist.dao; ++ ++public interface AbstractDao { ++ void clean(); ++} +Index: persist/src/test/java/ru/javaops/masterjava/persist/dao/UserDaoTest.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- persist/src/test/java/ru/javaops/masterjava/persist/dao/UserDaoTest.java (revision ) ++++ persist/src/test/java/ru/javaops/masterjava/persist/dao/UserDaoTest.java (revision ) +@@ -0,0 +1,35 @@ ++package ru.javaops.masterjava.persist.dao; ++ ++import org.junit.Assert; ++import org.junit.Before; ++import org.junit.BeforeClass; ++import org.junit.Test; ++import ru.javaops.masterjava.persist.UserTestData; ++import ru.javaops.masterjava.persist.model.User; ++ ++import java.util.List; ++ ++import static ru.javaops.masterjava.persist.UserTestData.FIST5_USERS; ++ ++public class UserDaoTest extends AbstractDaoTest { ++ ++ public UserDaoTest() { ++ super(UserDao.class); ++ } ++ ++ @BeforeClass ++ public static void init() throws Exception { ++ UserTestData.init(); ++ } ++ ++ @Before ++ public void setUp() throws Exception { ++ UserTestData.setUp(); ++ } ++ ++ @Test ++ public void getWithLimit() { ++ List users = dao.getWithLimit(5); ++ Assert.assertEquals(FIST5_USERS, users); ++ } ++} +\ No newline at end of file +Index: persist/src/test/java/ru/javaops/masterjava/persist/DBITestProvider.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- persist/src/test/java/ru/javaops/masterjava/persist/DBITestProvider.java (revision ) ++++ persist/src/test/java/ru/javaops/masterjava/persist/DBITestProvider.java (revision ) +@@ -0,0 +1,20 @@ ++package ru.javaops.masterjava.persist; ++ ++import java.sql.DriverManager; ++ ++public class DBITestProvider { ++ public static void initDBI() { ++ initDBI("jdbc:postgresql://localhost:5432/masterjava", "user", "password"); ++ } ++ ++ public static void initDBI(String dbUrl, String dbUser, String dbPassword) { ++ DBIProvider.init(() -> { ++ try { ++ Class.forName("org.postgresql.Driver"); ++ } catch (ClassNotFoundException e) { ++ throw new IllegalStateException("PostgreSQL driver not found", e); ++ } ++ return DriverManager.getConnection(dbUrl, dbUser, dbPassword); ++ }); ++ } ++} +\ No newline at end of file +Index: web/upload/src/main/java/ru/javaops/masterjava/model/User.java +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/model/User.java (date 1510231553000) ++++ persist/src/main/java/ru/javaops/masterjava/persist/model/User.java (revision ) +@@ -1,28 +1,31 @@ +-package ru.javaops.masterjava.model; ++package ru.javaops.masterjava.persist.model; ++ ++import com.bertoncelj.jdbi.entitymapper.Column; + + import java.util.Objects; + +-public class User { +- private final Integer id; +- private final String fullName; +- private final String email; +- private final UserFlag flag; ++public class User extends BaseEntity { ++ @Column("full_name") ++ private String fullName; ++ ++ private String email; ++ ++ private UserFlag flag; ++ ++ public User() { ++ } + + public User(String fullName, String email, UserFlag flag) { + this(null, fullName, email, flag); + } + + public User(Integer id, String fullName, String email, UserFlag flag) { +- this.id = id; ++ super(id); + this.fullName = fullName; + this.email = email; + this.flag = flag; + } + +- public Integer getId() { +- return id; +- } +- + public String getFullName() { + return fullName; + } +@@ -35,6 +38,22 @@ + return flag; + } + ++ public void setId(Integer id) { ++ this.id = id; ++ } ++ ++ public void setFullName(String fullName) { ++ this.fullName = fullName; ++ } ++ ++ public void setEmail(String email) { ++ this.email = email; ++ } ++ ++ public void setFlag(UserFlag flag) { ++ this.flag = flag; ++ } ++ + @Override + public boolean equals(Object o) { + if (this == o) return true; +@@ -60,4 +79,4 @@ + ", flag=" + flag + + ')'; + } +-} ++} +\ No newline at end of file +Index: config_templates/logback-test.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- config_templates/logback-test.xml (date 1510231553000) ++++ config_templates/logback-test.xml (revision ) +@@ -12,6 +12,7 @@ + + + ++ + + + +Index: web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java (date 1510231553000) ++++ web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java (revision ) +@@ -1,7 +1,7 @@ + package ru.javaops.masterjava.upload; + +-import ru.javaops.masterjava.model.User; +-import ru.javaops.masterjava.model.UserFlag; ++import ru.javaops.masterjava.persist.model.User; ++import ru.javaops.masterjava.persist.model.UserFlag; + import ru.javaops.masterjava.xml.util.StaxStreamProcessor; + + import javax.xml.stream.XMLStreamException; +Index: web/upload/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/pom.xml (date 1510231553000) ++++ web/upload/pom.xml (revision ) +@@ -22,6 +22,11 @@ + + + ++ ${project.groupId} ++ persist ++ ${project.version} ++ ++ + com.j2html + j2html + 1.2.0 +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1510231553000) ++++ pom.xml (revision ) +@@ -16,6 +16,7 @@ + parent-web + + common ++ persist + test + + web +Index: web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java (date 1510231553000) ++++ persist/src/main/java/ru/javaops/masterjava/persist/model/UserFlag.java (revision ) +@@ -1,4 +1,4 @@ +-package ru.javaops.masterjava.model; ++package ru.javaops.masterjava.persist.model; + + /** + * gkislin +Index: web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java (date 1510231553000) ++++ web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java (revision ) +@@ -1,7 +1,7 @@ + package ru.javaops.masterjava.upload; + + import org.thymeleaf.context.WebContext; +-import ru.javaops.masterjava.model.User; ++import ru.javaops.masterjava.persist.model.User; + + import javax.servlet.ServletException; + import javax.servlet.annotation.MultipartConfig; diff --git a/4_1_HW3_pom_structure.patch b/4_1_HW3_pom_structure.patch new file mode 100644 index 000000000..b01e8df31 --- /dev/null +++ b/4_1_HW3_pom_structure.patch @@ -0,0 +1,535 @@ +Index: services/mail-api/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- services/mail-api/pom.xml (revision ) ++++ services/mail-api/pom.xml (revision ) +@@ -0,0 +1,26 @@ ++ ++ ++ 4.0.0 ++ ++ ++ ru.javaops ++ parent ++ ../../parent/pom.xml ++ 1.0-SNAPSHOT ++ ++ ++ mail-api ++ 1.0-SNAPSHOT ++ Mail API ++ ++ ++ ++ ${project.groupId} ++ common ++ ${project.version} ++ ++ ++ ++ +\ No newline at end of file +Index: services/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- services/pom.xml (revision ) ++++ services/pom.xml (revision ) +@@ -0,0 +1,15 @@ ++ ++ 4.0.0 ++ ++ ru.javaops ++ services ++ pom ++ 1.0-SNAPSHOT ++ ++ Services ++ ++ mail-api ++ mail-service ++ ++ +Index: test/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- test/pom.xml (revision ) ++++ test/pom.xml (revision ) +@@ -0,0 +1,76 @@ ++ ++ ++ 4.0.0 ++ ++ ++ ru.javaops ++ parent ++ ../parent/pom.xml ++ 1.0-SNAPSHOT ++ ++ ++ test ++ 1.0-SNAPSHOT ++ Test ++ ++ ++ ++ ++ org.apache.maven.plugins ++ maven-shade-plugin ++ 2.2 ++ ++ ++ package ++ ++ shade ++ ++ ++ benchmarks ++ ++ ++ org.openjdk.jmh.Main ++ ++ ++ ++ ++ ++ *:* ++ ++ META-INF/*.SF ++ META-INF/*.DSA ++ META-INF/*.RSA ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ${project.groupId} ++ common ++ ${project.version} ++ ++ ++ org.openjdk.jmh ++ jmh-core ++ RELEASE ++ ++ ++ org.openjdk.jmh ++ jmh-generator-annprocess ++ RELEASE ++ provided ++ ++ ++ +\ No newline at end of file +Index: web/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/pom.xml (revision ) ++++ web/pom.xml (revision ) +@@ -0,0 +1,15 @@ ++ ++ 4.0.0 ++ ++ ru.javaops ++ web ++ pom ++ 1.0-SNAPSHOT ++ Web ++ ++ ++ upload ++ webapp ++ ++ +Index: web/webapp/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/webapp/pom.xml (revision ) ++++ web/webapp/pom.xml (revision ) +@@ -0,0 +1,30 @@ ++ ++ ++ 4.0.0 ++ ++ ++ ru.javaops ++ parent-web ++ ../../parent-web/pom.xml ++ 1.0-SNAPSHOT ++ ++ ++ webapp ++ 1.0-SNAPSHOT ++ war ++ WebApp ++ ++ ++ webapp ++ ++ ++ ++ ++ ${project.groupId} ++ common ++ ${project.version} ++ ++ ++ +\ No newline at end of file +Index: services/mail-service/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- services/mail-service/pom.xml (revision ) ++++ services/mail-service/pom.xml (revision ) +@@ -0,0 +1,26 @@ ++ ++ ++ 4.0.0 ++ ++ ++ ru.javaops ++ parent-web ++ ../../parent-web/pom.xml ++ 1.0-SNAPSHOT ++ ++ ++ mail-service ++ 1.0-SNAPSHOT ++ war ++ Mail Service ++ ++ ++ ++ ${project.groupId} ++ mail-api ++ ${project.version} ++ ++ ++ +\ No newline at end of file +Index: web/upload/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/pom.xml (revision ) ++++ web/upload/pom.xml (revision ) +@@ -0,0 +1,31 @@ ++ ++ ++ 4.0.0 ++ ++ ++ ru.javaops ++ parent-web ++ ../../parent-web/pom.xml ++ 1.0-SNAPSHOT ++ ++ ++ upload ++ 1.0-SNAPSHOT ++ war ++ Upload ++ ++ ++ upload ++ ++ ++ ++ ++ com.j2html ++ j2html ++ 1.2.0 ++ ++ ++ ++ +\ No newline at end of file +Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/xml/schema/Payload.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java +=================================================================== +--- src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java (date 1510506709000) ++++ web/upload/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/xml/schema/User.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/User.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/User.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java +=================================================================== +--- src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (date 1510506709000) ++++ web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (date 1510506709000) ++++ test/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/resources/cities.xsl +=================================================================== +--- src/main/resources/cities.xsl (date 1510506709000) ++++ web/upload/src/main/resources/cities.xsl (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/resources/groups.xsl +=================================================================== +--- src/main/resources/groups.xsl (date 1510506709000) ++++ web/upload/src/main/resources/groups.xsl (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/resources/payload.xsd +=================================================================== +--- src/main/resources/payload.xsd (date 1510506709000) ++++ web/upload/src/main/resources/payload.xsd (revision ) +@@ -1,0 +1,0 @@ +Index: upload/pom.xml +=================================================================== +--- upload/pom.xml (date 1510506709000) ++++ parent-web/pom.xml (revision ) +@@ -11,10 +11,10 @@ + 1.0-SNAPSHOT + + +- upload ++ parent-web ++ pom + 1.0-SNAPSHOT +- war +- Upload ++ Parent Web + + + +@@ -31,9 +31,16 @@ + + + +- ru.javaops +- common +- ${project.version} ++ javax.servlet ++ javax.servlet-api ++ 3.1.0 ++ provided + + ++ ++ ++ ++ ++ ++ + +\ No newline at end of file +Index: src/test/resources/payload.xml +=================================================================== +--- src/test/resources/payload.xml (date 1510506709000) ++++ web/upload/src/test/resources/payload.xml (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/xml/util/Schemas.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/Schemas.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (date 1510506709000) ++++ test/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/test/resources/city.xml +=================================================================== +--- src/test/resources/city.xml (date 1510506709000) ++++ web/upload/src/test/resources/city.xml (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java +=================================================================== +--- src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java (date 1510506709000) ++++ web/upload/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/xml/schema/Project.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/Project.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Project.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/test/java/ru/javaops/masterjava/MainXml.java +=================================================================== +--- src/test/java/ru/javaops/masterjava/MainXml.java (date 1510506709000) ++++ web/upload/src/test/java/ru/javaops/masterjava/MainXml.java (revision ) +@@ -20,7 +20,6 @@ + import java.nio.file.Files; + import java.nio.file.Paths; + import java.util.*; +-import java.util.stream.Collectors; + + import static com.google.common.base.Strings.nullToEmpty; + import static j2html.TagCreator.*; +@@ -74,9 +73,7 @@ + final Set groups = new HashSet<>(project.getGroup()); // identity compare + return StreamEx.of(payload.getUsers().getUser()) + .filter(u -> !Collections.disjoint(groups, u.getGroupRefs())) +- .collect( +- Collectors.toCollection(() -> new TreeSet<>(USER_COMPARATOR)) +- ); ++ .toCollection(() -> new TreeSet<>(USER_COMPARATOR)); + } + + private static Set processByStax(String projectName, URL payloadUrl) throws Exception { +Index: src/main/java/ru/javaops/masterjava/xml/schema/CityType.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/CityType.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java (revision ) +@@ -1,13 +1,8 @@ ++ + + package ru.javaops.masterjava.xml.schema; + +-import javax.xml.bind.annotation.XmlAccessType; +-import javax.xml.bind.annotation.XmlAccessorType; +-import javax.xml.bind.annotation.XmlAttribute; +-import javax.xml.bind.annotation.XmlID; +-import javax.xml.bind.annotation.XmlSchemaType; +-import javax.xml.bind.annotation.XmlType; +-import javax.xml.bind.annotation.XmlValue; ++import javax.xml.bind.annotation.*; + import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; + import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +Index: src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (date 1510506709000) ++++ test/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (revision ) +@@ -1,0 +1,0 @@ +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1510506709000) ++++ pom.xml (revision ) +@@ -8,17 +8,14 @@ + + 1.0-SNAPSHOT + +- Master Java ++ Masterjava Root + https://github.com/JavaOPs/masterjava + + +- upload + common +- ++ ++ web ++ services + + +Index: src/main/java/ru/javaops/masterjava/service/MailService.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/service/MailService.java (date 1510506709000) ++++ services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailServiceExecutor.java (revision ) +@@ -1,4 +1,4 @@ +-package ru.javaops.masterjava.service; ++package ru.javaops.masterjava.service.mail; + + import java.util.ArrayList; + import java.util.List; +@@ -6,7 +6,7 @@ + import java.util.concurrent.*; + import java.util.stream.Collectors; + +-public class MailService { ++public class MailServiceExecutor { + private static final String OK = "OK"; + + private static final String INTERRUPTED_BY_FAULTS_NUMBER = "+++ Interrupted by faults number"; +Index: src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java +=================================================================== +--- src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java (date 1510506709000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java (revision ) +@@ -1,0 +1,0 @@ +Index: src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java +=================================================================== +--- src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java (date 1510506709000) ++++ web/upload/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java (revision ) +@@ -1,0 +1,0 @@ diff --git a/4_2_HW3_thymeleaf_upload.patch b/4_2_HW3_thymeleaf_upload.patch new file mode 100644 index 000000000..35f72dd77 --- /dev/null +++ b/4_2_HW3_thymeleaf_upload.patch @@ -0,0 +1,425 @@ +Index: web/upload/src/main/webapp/WEB-INF/templates/result.html +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/webapp/WEB-INF/templates/result.html (revision ) ++++ web/upload/src/main/webapp/WEB-INF/templates/result.html (revision ) +@@ -0,0 +1,27 @@ ++ ++ ++ ++ Uploaded users ++ ++ ++

Upload XML

++

Uploaded users

++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
Full NameEmailFlag
++ ++ +\ No newline at end of file +Index: web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java (revision ) ++++ web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java (revision ) +@@ -0,0 +1,28 @@ ++package ru.javaops.masterjava.upload; ++ ++import ru.javaops.masterjava.model.User; ++import ru.javaops.masterjava.model.UserFlag; ++import ru.javaops.masterjava.xml.util.StaxStreamProcessor; ++ ++import javax.xml.stream.XMLStreamException; ++import javax.xml.stream.events.XMLEvent; ++import java.io.InputStream; ++import java.util.ArrayList; ++import java.util.List; ++ ++public class UserProcessor { ++ ++ public List process(final InputStream is) throws XMLStreamException { ++ final StaxStreamProcessor processor = new StaxStreamProcessor(is); ++ List users = new ArrayList<>(); ++ ++ while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { ++ final String email = processor.getAttribute("email"); ++ final UserFlag flag = UserFlag.valueOf(processor.getAttribute("flag")); ++ final String fullName = processor.getReader().getElementText(); ++ final User user = new User(fullName, email, flag); ++ users.add(user); ++ } ++ return users; ++ } ++} +Index: web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java (revision ) ++++ web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java (revision ) +@@ -0,0 +1,11 @@ ++package ru.javaops.masterjava.model; ++ ++/** ++ * gkislin ++ * 13.10.2016 ++ */ ++public enum UserFlag { ++ active, ++ deleted, ++ superuser; ++} +Index: web/upload/src/main/webapp/WEB-INF/templates/exception.html +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/webapp/WEB-INF/templates/exception.html (revision ) ++++ web/upload/src/main/webapp/WEB-INF/templates/exception.html (revision ) +@@ -0,0 +1,20 @@ ++ ++ ++ ++ Application error ++ ++ ++ ++
++
++
++

Application error:

++ ++

exception.message

++
    ++
  • ++
++
++
++ ++ +\ No newline at end of file +Index: web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafListener.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafListener.java (revision ) ++++ web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafListener.java (revision ) +@@ -0,0 +1,20 @@ ++package ru.javaops.masterjava.common.web; ++ ++import org.thymeleaf.TemplateEngine; ++ ++import javax.servlet.ServletContextEvent; ++import javax.servlet.ServletContextListener; ++import javax.servlet.annotation.WebListener; ++ ++@WebListener ++public class ThymeleafListener implements ServletContextListener { ++ ++ public static TemplateEngine engine; ++ ++ public void contextInitialized(ServletContextEvent sce) { ++ engine = ThymeleafUtil.getTemplateEngine(sce.getServletContext()); ++ } ++ ++ public void contextDestroyed(ServletContextEvent sce) { ++ } ++} +Index: web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java (revision ) ++++ web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java (revision ) +@@ -0,0 +1,56 @@ ++package ru.javaops.masterjava.upload; ++ ++import org.apache.commons.fileupload.FileItemIterator; ++import org.apache.commons.fileupload.FileItemStream; ++import org.apache.commons.fileupload.servlet.ServletFileUpload; ++import org.thymeleaf.context.WebContext; ++import ru.javaops.masterjava.model.User; ++ ++import javax.servlet.ServletException; ++import javax.servlet.annotation.WebServlet; ++import javax.servlet.http.HttpServlet; ++import javax.servlet.http.HttpServletRequest; ++import javax.servlet.http.HttpServletResponse; ++import java.io.IOException; ++import java.io.InputStream; ++import java.util.List; ++ ++import static ru.javaops.masterjava.common.web.ThymeleafListener.engine; ++ ++@WebServlet("/") ++public class UploadServlet extends HttpServlet { ++ ++ private final UserProcessor userProcessor = new UserProcessor(); ++ ++ @Override ++ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ++ final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale()); ++ engine.process("upload", webContext, resp.getWriter()); ++ } ++ ++ @Override ++ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ++ final ServletFileUpload upload = new ServletFileUpload(); ++ final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale()); ++ ++ try { ++// https://commons.apache.org/proper/commons-fileupload/streaming.html ++ ++ final FileItemIterator itemIterator = upload.getItemIterator(req); ++ while (itemIterator.hasNext()) { //expect that it's only one file ++ FileItemStream fileItemStream = itemIterator.next(); ++ if (!fileItemStream.isFormField()) { ++ try (InputStream is = fileItemStream.openStream()) { ++ List users = userProcessor.process(is); ++ webContext.setVariable("users", users); ++ engine.process("result", webContext, resp.getWriter()); ++ } ++ break; ++ } ++ } ++ } catch (Exception e) { ++ webContext.setVariable("exception", e); ++ engine.process("exception", webContext, resp.getWriter()); ++ } ++ } ++} +Index: web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java (revision ) ++++ web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java (revision ) +@@ -0,0 +1,24 @@ ++package ru.javaops.masterjava.common.web; ++ ++import org.thymeleaf.TemplateEngine; ++import org.thymeleaf.templatemode.TemplateMode; ++import org.thymeleaf.templateresolver.ServletContextTemplateResolver; ++ ++import javax.servlet.ServletContext; ++ ++public class ThymeleafUtil { ++ ++ private ThymeleafUtil() { ++ } ++ ++ public static TemplateEngine getTemplateEngine(ServletContext context) { ++ final ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(context); ++ templateResolver.setTemplateMode(TemplateMode.HTML); ++ templateResolver.setPrefix("/WEB-INF/templates/"); ++ templateResolver.setSuffix(".html"); ++ templateResolver.setCacheTTLMs(1000L); ++ final TemplateEngine engine = new TemplateEngine(); ++ engine.setTemplateResolver(templateResolver); ++ return engine; ++ } ++} +Index: web/common-web/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/common-web/pom.xml (revision ) ++++ web/common-web/pom.xml (revision ) +@@ -0,0 +1,42 @@ ++ ++ ++ 4.0.0 ++ ++ ++ ru.javaops ++ parent ++ ../../parent/pom.xml ++ 1.0-SNAPSHOT ++ ++ ++ common-web ++ 1.0-SNAPSHOT ++ Common Web ++ ++ ++ ++ ${project.groupId} ++ common ++ ${project.version} ++ ++ ++ commons-fileupload ++ commons-fileupload ++ 1.3.3 ++ ++ ++ javax.servlet ++ javax.servlet-api ++ 3.1.0 ++ provided ++ ++ ++ ++ org.thymeleaf ++ thymeleaf ++ 3.0.8.RELEASE ++ ++ ++ +\ No newline at end of file +Index: web/upload/src/main/java/ru/javaops/masterjava/model/User.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/model/User.java (revision ) ++++ web/upload/src/main/java/ru/javaops/masterjava/model/User.java (revision ) +@@ -0,0 +1,63 @@ ++package ru.javaops.masterjava.model; ++ ++import java.util.Objects; ++ ++public class User { ++ private final Integer id; ++ private final String fullName; ++ private final String email; ++ private final UserFlag flag; ++ ++ public User(String fullName, String email, UserFlag flag) { ++ this(null, fullName, email, flag); ++ } ++ ++ public User(Integer id, String fullName, String email, UserFlag flag) { ++ this.id = id; ++ this.fullName = fullName; ++ this.email = email; ++ this.flag = flag; ++ } ++ ++ public Integer getId() { ++ return id; ++ } ++ ++ public String getFullName() { ++ return fullName; ++ } ++ ++ public String getEmail() { ++ return email; ++ } ++ ++ public UserFlag getFlag() { ++ return flag; ++ } ++ ++ @Override ++ public boolean equals(Object o) { ++ if (this == o) return true; ++ if (o == null || getClass() != o.getClass()) return false; ++ User user = (User) o; ++ return Objects.equals(id, user.id) && ++ Objects.equals(fullName, user.fullName) && ++ Objects.equals(email, user.email) && ++ flag == user.flag; ++ } ++ ++ @Override ++ public int hashCode() { ++ return Objects.hash(id, fullName, email, flag); ++ } ++ ++ @Override ++ public String toString() { ++ return "User (" + ++ "id=" + id + ++ ", fullName='" + fullName + '\'' + ++ ", email='" + email + '\'' + ++ ", flag=" + flag + ++ ')'; ++ } ++} +Index: web/upload/src/main/webapp/WEB-INF/templates/upload.html +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/webapp/WEB-INF/templates/upload.html (revision ) ++++ web/upload/src/main/webapp/WEB-INF/templates/upload.html (revision ) +@@ -0,0 +1,16 @@ ++ ++ ++ Upload XML ++ ++ ++
++

Select xml file to upload

++

++
++

++

++ ++

++
++ ++ +\ No newline at end of file +Index: web/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/pom.xml (date 1509890578000) ++++ web/pom.xml (revision ) +@@ -9,6 +9,7 @@ + Web + + ++ common-web + upload + webapp + +Index: parent-web/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- parent-web/pom.xml (date 1509890578000) ++++ parent-web/pom.xml (revision ) +@@ -31,6 +31,11 @@ + + + ++ ${project.groupId} ++ common-web ++ ${project.version} ++ ++ + javax.servlet + javax.servlet-api + 3.1.0 diff --git a/4_3_HW3_upload_servlet3.patch b/4_3_HW3_upload_servlet3.patch new file mode 100644 index 000000000..28afb256c --- /dev/null +++ b/4_3_HW3_upload_servlet3.patch @@ -0,0 +1,87 @@ +Index: web/common-web/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/common-web/pom.xml (date 1510507514000) ++++ web/common-web/pom.xml (revision ) +@@ -22,11 +22,6 @@ + ${project.version} + + +- commons-fileupload +- commons-fileupload +- 1.3.3 +- +- + javax.servlet + javax.servlet-api + 3.1.0 +Index: web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java (date 1510507514000) ++++ web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java (revision ) +@@ -1,23 +1,23 @@ + package ru.javaops.masterjava.upload; + +-import org.apache.commons.fileupload.FileItemIterator; +-import org.apache.commons.fileupload.FileItemStream; +-import org.apache.commons.fileupload.servlet.ServletFileUpload; + import org.thymeleaf.context.WebContext; + import ru.javaops.masterjava.model.User; + + import javax.servlet.ServletException; ++import javax.servlet.annotation.MultipartConfig; + import javax.servlet.annotation.WebServlet; + import javax.servlet.http.HttpServlet; + import javax.servlet.http.HttpServletRequest; + import javax.servlet.http.HttpServletResponse; ++import javax.servlet.http.Part; + import java.io.IOException; + import java.io.InputStream; + import java.util.List; + + import static ru.javaops.masterjava.common.web.ThymeleafListener.engine; + +-@WebServlet("/") ++@WebServlet(urlPatterns = "/", loadOnStartup = 1) ++@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 10) //10 MB in memory limit + public class UploadServlet extends HttpServlet { + + private final UserProcessor userProcessor = new UserProcessor(); +@@ -30,23 +30,18 @@ + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { +- final ServletFileUpload upload = new ServletFileUpload(); + final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale()); + + try { +-// https://commons.apache.org/proper/commons-fileupload/streaming.html +- +- final FileItemIterator itemIterator = upload.getItemIterator(req); +- while (itemIterator.hasNext()) { //expect that it's only one file +- FileItemStream fileItemStream = itemIterator.next(); +- if (!fileItemStream.isFormField()) { +- try (InputStream is = fileItemStream.openStream()) { +- List users = userProcessor.process(is); +- webContext.setVariable("users", users); +- engine.process("result", webContext, resp.getWriter()); +- } +- break; +- } ++// http://docs.oracle.com/javaee/6/tutorial/doc/glraq.html ++ Part filePart = req.getPart("fileToUpload"); ++ if (filePart.getSize() == 0) { ++ throw new IllegalStateException("Upload file have not been selected"); ++ } ++ try (InputStream is = filePart.getInputStream()) { ++ List users = userProcessor.process(is); ++ webContext.setVariable("users", users); ++ engine.process("result", webContext, resp.getWriter()); + } + } catch (Exception e) { + webContext.setVariable("exception", e); diff --git a/4_4_HW3_jaxb_stax.patch b/4_4_HW3_jaxb_stax.patch new file mode 100644 index 000000000..59c54fd96 --- /dev/null +++ b/4_4_HW3_jaxb_stax.patch @@ -0,0 +1,341 @@ +Index: web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java (date 1510508700000) ++++ web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java (revision ) +@@ -2,8 +2,12 @@ + + import ru.javaops.masterjava.model.User; + import ru.javaops.masterjava.model.UserFlag; ++import ru.javaops.masterjava.xml.schema.ObjectFactory; ++import ru.javaops.masterjava.xml.util.JaxbParser; ++import ru.javaops.masterjava.xml.util.JaxbUnmarshaller; + import ru.javaops.masterjava.xml.util.StaxStreamProcessor; + ++import javax.xml.bind.JAXBException; + import javax.xml.stream.XMLStreamException; + import javax.xml.stream.events.XMLEvent; + import java.io.InputStream; +@@ -11,16 +15,16 @@ + import java.util.List; + + public class UserProcessor { ++ private static final JaxbParser jaxbParser = new JaxbParser(ObjectFactory.class); + +- public List process(final InputStream is) throws XMLStreamException { ++ public List process(final InputStream is) throws XMLStreamException, JAXBException { + final StaxStreamProcessor processor = new StaxStreamProcessor(is); + List users = new ArrayList<>(); + ++ JaxbUnmarshaller unmarshaller = jaxbParser.createUnmarshaller(); + while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { +- final String email = processor.getAttribute("email"); +- final UserFlag flag = UserFlag.valueOf(processor.getAttribute("flag")); +- final String fullName = processor.getReader().getElementText(); +- final User user = new User(fullName, email, flag); ++ ru.javaops.masterjava.xml.schema.User xmlUser = unmarshaller.unmarshal(processor.getReader(), ru.javaops.masterjava.xml.schema.User.class); ++ final User user = new User(xmlUser.getValue(), xmlUser.getEmail(), UserFlag.valueOf(xmlUser.getFlag().value())); + users.add(user); + } + return users; +Index: web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (date 1510508700000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision ) +@@ -16,23 +16,23 @@ + unmarshaller = ctx.createUnmarshaller(); + } + +- public synchronized void setSchema(Schema schema) { ++ public void setSchema(Schema schema) { + unmarshaller.setSchema(schema); + } + +- public synchronized Object unmarshal(InputStream is) throws JAXBException { +- return unmarshaller.unmarshal(is); ++ public T unmarshal(InputStream is) throws JAXBException { ++ return (T) unmarshaller.unmarshal(is); + } + +- public synchronized Object unmarshal(Reader reader) throws JAXBException { +- return unmarshaller.unmarshal(reader); ++ public T unmarshal(Reader reader) throws JAXBException { ++ return (T) unmarshaller.unmarshal(reader); + } + +- public Object unmarshal(String str) throws JAXBException { +- return unmarshal(new StringReader(str)); ++ public T unmarshal(String str) throws JAXBException { ++ return (T) unmarshal(new StringReader(str)); + } + +- public synchronized T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { ++ public T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { + return unmarshaller.unmarshal(reader, elementClass).getValue(); + } + } +\ No newline at end of file +Index: web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (date 1510508700000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision ) +@@ -4,28 +4,26 @@ + + import javax.xml.bind.JAXBContext; + import javax.xml.bind.JAXBException; +-import javax.xml.bind.PropertyException; +-import javax.xml.stream.XMLStreamReader; + import javax.xml.transform.stream.StreamSource; + import javax.xml.validation.Schema; +-import java.io.*; ++import java.io.IOException; ++import java.io.Reader; ++import java.io.StringReader; + + + /** +- * Marshalling/Unmarshalling JAXB helper +- * XML Facade ++ * Marshalling/Unmarshalling JAXB facade + */ + public class JaxbParser { + +- protected JaxbMarshaller jaxbMarshaller; +- protected JaxbUnmarshaller jaxbUnmarshaller; ++ private JAXBContext ctx; + protected Schema schema; + + public JaxbParser(Class... classesToBeBound) { + try { + init(JAXBContext.newInstance(classesToBeBound)); + } catch (JAXBException e) { +- throw new IllegalArgumentException(e); ++ throw new IllegalStateException(e); + } + } + +@@ -34,53 +32,42 @@ + try { + init(JAXBContext.newInstance(context)); + } catch (JAXBException e) { +- throw new IllegalArgumentException(e); ++ throw new IllegalStateException(e); + } + } + +- private void init(JAXBContext ctx) throws JAXBException { +- jaxbMarshaller = new JaxbMarshaller(ctx); +- jaxbUnmarshaller = new JaxbUnmarshaller(ctx); ++ private void init(JAXBContext ctx) { ++ this.ctx = ctx; + } + +- // Unmarshaller +- public T unmarshal(InputStream is) throws JAXBException { +- return (T) jaxbUnmarshaller.unmarshal(is); +- } +- +- public T unmarshal(Reader reader) throws JAXBException { +- return (T) jaxbUnmarshaller.unmarshal(reader); +- } +- +- public T unmarshal(String str) throws JAXBException { +- return (T) jaxbUnmarshaller.unmarshal(str); +- } +- +- public T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { +- return jaxbUnmarshaller.unmarshal(reader, elementClass); +- } +- +- // Marshaller +- public void setMarshallerProperty(String prop, Object value) { ++ // https://stackoverflow.com/a/7400735/548473 ++ public JaxbMarshaller createMarshaller() { + try { +- jaxbMarshaller.setProperty(prop, value); +- } catch (PropertyException e) { +- throw new IllegalArgumentException(e); +- } +- } +- +- public String marshal(Object instance) throws JAXBException { +- return jaxbMarshaller.marshal(instance); ++ JaxbMarshaller marshaller = new JaxbMarshaller(ctx); ++ if (schema != null) { ++ marshaller.setSchema(schema); ++ } ++ return marshaller; ++ } catch (JAXBException e) { ++ throw new IllegalStateException(e); ++ } + } + +- public void marshal(Object instance, Writer writer) throws JAXBException { +- jaxbMarshaller.marshal(instance, writer); ++ // https://stackoverflow.com/a/7400735/548473 ++ public JaxbUnmarshaller createUnmarshaller() { ++ try { ++ JaxbUnmarshaller unmarshaller = new JaxbUnmarshaller(ctx); ++ if (schema != null) { ++ unmarshaller.setSchema(schema); ++ } ++ return unmarshaller; ++ } catch (JAXBException e) { ++ throw new IllegalStateException(e); ++ } + } + + public void setSchema(Schema schema) { + this.schema = schema; +- jaxbUnmarshaller.setSchema(schema); +- jaxbMarshaller.setSchema(schema); + } + + public void validate(String str) throws IOException, SAXException { +Index: web/upload/src/test/java/ru/javaops/masterjava/MainXml.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/test/java/ru/javaops/masterjava/MainXml.java (date 1510508700000) ++++ web/upload/src/test/java/ru/javaops/masterjava/MainXml.java (revision ) +@@ -8,10 +8,7 @@ + import ru.javaops.masterjava.xml.schema.Payload; + import ru.javaops.masterjava.xml.schema.Project; + import ru.javaops.masterjava.xml.schema.User; +-import ru.javaops.masterjava.xml.util.JaxbParser; +-import ru.javaops.masterjava.xml.util.Schemas; +-import ru.javaops.masterjava.xml.util.StaxStreamProcessor; +-import ru.javaops.masterjava.xml.util.XsltProcessor; ++import ru.javaops.masterjava.xml.util.*; + + import javax.xml.stream.events.XMLEvent; + import java.io.InputStream; +@@ -59,10 +56,11 @@ + + private static Set parseByJaxb(String projectName, URL payloadUrl) throws Exception { + JaxbParser parser = new JaxbParser(ObjectFactory.class); ++ JaxbUnmarshaller unmarshaller = parser.createUnmarshaller(); + parser.setSchema(Schemas.ofClasspath("payload.xsd")); + Payload payload; + try (InputStream is = payloadUrl.openStream()) { +- payload = parser.unmarshal(is); ++ payload = unmarshaller.unmarshal(is); + } + + Project project = StreamEx.of(payload.getProjects().getProject()) +@@ -99,11 +97,12 @@ + // Users loop + Set users = new TreeSet<>(USER_COMPARATOR); + +- JaxbParser parser = new JaxbParser(User.class); ++ JaxbParser parser = new JaxbParser(ObjectFactory.class); ++ JaxbUnmarshaller unmarshaller = parser.createUnmarshaller(); + while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { + String groupRefs = processor.getAttribute("groupRefs"); + if (!Collections.disjoint(groupNames, Splitter.on(' ').splitToList(nullToEmpty(groupRefs)))) { +- User user = parser.unmarshal(processor.getReader(), User.class); ++ User user = unmarshaller.unmarshal(processor.getReader(), User.class); + users.add(user); + } + } +Index: web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (date 1510508700000) ++++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (revision ) +@@ -18,11 +18,15 @@ + marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); + } + +- public void setProperty(String prop, Object value) throws PropertyException { +- marshaller.setProperty(prop, value); ++ public void setProperty(String prop, Object value) { ++ try { ++ marshaller.setProperty(prop, value); ++ } catch (PropertyException e) { ++ throw new IllegalArgumentException(e); ++ } + } + +- public synchronized void setSchema(Schema schema) { ++ public void setSchema(Schema schema) { + marshaller.setSchema(schema); + } + +@@ -32,8 +36,7 @@ + return sw.toString(); + } + +- public synchronized void marshal(Object instance, Writer writer) throws JAXBException { ++ public void marshal(Object instance, Writer writer) throws JAXBException { + marshaller.marshal(instance, writer); + } +- +-} ++} +\ No newline at end of file +Index: web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (date 1510508700000) ++++ web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (revision ) +@@ -10,31 +10,37 @@ + import javax.xml.namespace.QName; + + public class JaxbParserTest { +- private static final JaxbParser JAXB_PARSER = new JaxbParser(ObjectFactory.class); ++ // https://google.github.io/styleguide/javaguide.html#s5.2.4-constant-names ++ private static final JaxbParser jaxbParser; ++ private static final JaxbMarshaller marshaller; ++ private static final JaxbUnmarshaller unmarshaller; + + static { +- JAXB_PARSER.setSchema(Schemas.ofClasspath("payload.xsd")); ++ jaxbParser = new JaxbParser(ObjectFactory.class); ++ jaxbParser.setSchema(Schemas.ofClasspath("payload.xsd")); ++ marshaller = jaxbParser.createMarshaller(); ++ unmarshaller = jaxbParser.createUnmarshaller(); + } + + @Test + public void testPayload() throws Exception { + // JaxbParserTest.class.getResourceAsStream("/city.xml") +- Payload payload = JAXB_PARSER.unmarshal( ++ Payload payload = unmarshaller.unmarshal( + Resources.getResource("payload.xml").openStream()); +- String strPayload = JAXB_PARSER.marshal(payload); +- JAXB_PARSER.validate(strPayload); ++ String strPayload = marshaller.marshal(payload); ++ jaxbParser.validate(strPayload); + System.out.println(strPayload); + } + + @Test + public void testCity() throws Exception { +- JAXBElement cityElement = JAXB_PARSER.unmarshal( ++ JAXBElement cityElement = unmarshaller.unmarshal( + Resources.getResource("city.xml").openStream()); + CityType city = cityElement.getValue(); + JAXBElement cityElement2 = + new JAXBElement<>(new QName("http://javaops.ru", "City"), CityType.class, city); +- String strCity = JAXB_PARSER.marshal(cityElement2); +- JAXB_PARSER.validate(strCity); ++ String strCity = marshaller.marshal(cityElement2); ++ jaxbParser.validate(strCity); + System.out.println(strCity); + } + } +\ No newline at end of file diff --git a/4_5_dependencies.patch b/4_5_dependencies.patch new file mode 100644 index 000000000..03cf7222c --- /dev/null +++ b/4_5_dependencies.patch @@ -0,0 +1,33 @@ +Index: parent/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- parent/pom.xml (date 1490101176000) ++++ parent/pom.xml (revision ) +@@ -14,6 +14,8 @@ + 1.8 + UTF-8 + UTF-8 ++ ++ false + + + +Index: pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- pom.xml (date 1490101176000) ++++ pom.xml (revision ) +@@ -12,6 +12,9 @@ + https://github.com/JavaOPs/masterjava + + ++ parent ++ parent-web ++ + common + test + diff --git a/4_6_fix_convergence.patch b/4_6_fix_convergence.patch new file mode 100644 index 000000000..06ed4939a --- /dev/null +++ b/4_6_fix_convergence.patch @@ -0,0 +1,58 @@ +Index: web/upload/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/upload/pom.xml (date 1510518837000) ++++ web/upload/pom.xml (revision ) +@@ -25,6 +25,12 @@ + com.j2html + j2html + 1.2.0 ++ ++ ++ com.google.guava ++ guava ++ ++ + + + +Index: test/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- test/pom.xml (date 1510518837000) ++++ test/pom.xml (revision ) +@@ -64,12 +64,12 @@ + + org.openjdk.jmh + jmh-core +- RELEASE ++ 1.19 + + + org.openjdk.jmh + jmh-generator-annprocess +- RELEASE ++ 1.19 + provided + +
+Index: parent/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- parent/pom.xml (date 1510518837000) ++++ parent/pom.xml (revision ) +@@ -50,7 +50,7 @@ + + one.util + streamex +- RELEASE ++ 0.6.6 + + + diff --git a/4_7_enforcer.patch b/4_7_enforcer.patch new file mode 100644 index 000000000..d9905cbce --- /dev/null +++ b/4_7_enforcer.patch @@ -0,0 +1,32 @@ +Index: parent/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- parent/pom.xml (date 1490103087000) ++++ parent/pom.xml (revision ) +@@ -38,6 +38,24 @@ + -Dfile.encoding=UTF-8 + + ++ ++ org.apache.maven.plugins ++ maven-enforcer-plugin ++ 1.4.1 ++ ++ ++ enforce ++ ++ ++ ++ ++ ++ ++ enforce ++ ++ ++ ++ + + + diff --git a/4_8_logging.patch b/4_8_logging.patch new file mode 100644 index 000000000..8ab045325 --- /dev/null +++ b/4_8_logging.patch @@ -0,0 +1,184 @@ +Index: config_templates/logback.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- config_templates/logback.xml (revision ) ++++ config_templates/logback.xml (revision ) +@@ -0,0 +1,40 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ${LOG_DIR}/${project.build.finalName}.log ++ ++ UTF-8 ++ %d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{0} [%file:%line] - %msg%n ++ ++ ++ ++ ${LOG_DIR}/archived/${project.build.finalName}.%d{yyyy-MM-dd}.%i.log ++ ++ ++ 5MB ++ ++ ++ ++ ++ ++ ++ UTF-8 ++ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} [%file:%line] - %msg%n ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +Index: config_templates/logback-test.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- config_templates/logback-test.xml (revision ) ++++ config_templates/logback-test.xml (revision ) +@@ -0,0 +1,20 @@ ++ ++ ++ ++ true ++ ++ ++ ++ ++ UTF-8 ++ %-5level %logger{0} [%file:%line] %msg%n ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +\ No newline at end of file +Index: web/common-web/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- web/common-web/pom.xml (date 1509893613000) ++++ web/common-web/pom.xml (revision ) +@@ -32,6 +32,12 @@ + org.thymeleaf + thymeleaf + 3.0.8.RELEASE ++ ++ ++ org.slf4j ++ slf4j-api ++ ++ +
+ + +\ No newline at end of file +Index: parent/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- parent/pom.xml (date 1509893613000) ++++ parent/pom.xml (revision ) +@@ -14,7 +14,11 @@ + 1.8 + UTF-8 + UTF-8 ++ ++ 1.2.3 ++ 1.7.25 + ++ /apps/masterjava/config/ + false + + +@@ -57,6 +61,18 @@ + + + ++ ++ ++ ++ ${masterjava.config} ++ ++ logback-test.xml ++ ++ ++ ++ src/test/resources ++ ++ + + + +@@ -70,6 +86,20 @@ + streamex + 0.6.6 + ++ ++ ++ ++ org.slf4j ++ jcl-over-slf4j ++ ${slf4j.version} ++ runtime ++ ++ ++ ++ ch.qos.logback ++ logback-classic ++ ${logback.version} ++ + + + +Index: parent-web/pom.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- parent-web/pom.xml (date 1509893613000) ++++ parent-web/pom.xml (revision ) +@@ -27,6 +27,19 @@ + + + ++ ++ ++ ++ ${masterjava.config} ++ true ++ ++ logback.xml ++ ++ ++ ++ src/main/resources ++ ++ + + + diff --git a/4_9_context.patch b/4_9_context.patch new file mode 100644 index 000000000..09b29d41f --- /dev/null +++ b/4_9_context.patch @@ -0,0 +1,57 @@ +Index: config_templates/context.xml +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +--- config_templates/context.xml (revision ) ++++ config_templates/context.xml (revision ) +@@ -0,0 +1,49 @@ ++ ++ ++ ++ ++ ++ ++ ++ WEB-INF/web.xml ++ ${catalina.base}/conf/web.xml ++ ++ ++ ++ ++ ++ ++ ++ ++ diff --git a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java index ec1c8a691..0695132ef 100644 --- a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java +++ b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java @@ -24,7 +24,7 @@ public static void main(String[] args) throws ExecutionException, InterruptedExc while (count < 6) { System.out.println("Pass " + count); long start = System.currentTimeMillis(); - final int[][] matrixC = MatrixUtil.singleThreadMultiply(matrixA, matrixB); + final int[][] matrixC = MatrixUtil.singleThreadMultiplyOpt(matrixA, matrixB); double duration = (System.currentTimeMillis() - start) / 1000.; out("Single thread time, sec: %.3f", duration); singleThreadSum += duration; From 0c715a0bc4d86bbb12e325c88132ae86c785db14 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:16:25 +0200 Subject: [PATCH 08/46] 2 08 StAX --- .../xml/util/StaxStreamProcessor.java | 56 +++++++++++++++++++ .../xml/util/StaxStreamProcessorTest.java | 36 ++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java create mode 100644 src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java diff --git a/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java b/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java new file mode 100644 index 000000000..921ca6aff --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java @@ -0,0 +1,56 @@ +package ru.javaops.masterjava.xml.util; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.events.XMLEvent; +import java.io.InputStream; + +public class StaxStreamProcessor implements AutoCloseable { + private static final XMLInputFactory FACTORY = XMLInputFactory.newInstance(); + + private final XMLStreamReader reader; + + public StaxStreamProcessor(InputStream is) throws XMLStreamException { + reader = FACTORY.createXMLStreamReader(is); + } + + public XMLStreamReader getReader() { + return reader; + } + + public boolean doUntil(int stopEvent, String value) throws XMLStreamException { + while (reader.hasNext()) { + int event = reader.next(); + if (event == stopEvent) { + if (value.equals(getValue(event))) { + return true; + } + } + } + return false; + } + + public String getValue(int event) throws XMLStreamException { + return (event == XMLEvent.CHARACTERS) ? reader.getText() : reader.getLocalName(); + } + + public String getElementValue(String element) throws XMLStreamException { + return doUntil(XMLEvent.START_ELEMENT, element) ? reader.getElementText() : null; + } + + public String getText() throws XMLStreamException { + return reader.getElementText(); + } + + @Override + public void close() { + if (reader != null) { + try { + reader.close(); + } catch (XMLStreamException e) { + // empty + } + } + } +} diff --git a/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java b/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java new file mode 100644 index 000000000..fd55963dd --- /dev/null +++ b/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java @@ -0,0 +1,36 @@ +package ru.javaops.masterjava.xml.util; + +import com.google.common.io.Resources; +import org.junit.Test; + +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.events.XMLEvent; + +public class StaxStreamProcessorTest { + @Test + public void readCities() throws Exception { + try (StaxStreamProcessor processor = + new StaxStreamProcessor(Resources.getResource("payload.xml").openStream())) { + XMLStreamReader reader = processor.getReader(); + while (reader.hasNext()) { + int event = reader.next(); + if (event == XMLEvent.START_ELEMENT) { + if ("City".equals(reader.getLocalName())) { + System.out.println(reader.getElementText()); + } + } + } + } + } + + @Test + public void readCities2() throws Exception { + try (StaxStreamProcessor processor = + new StaxStreamProcessor(Resources.getResource("payload.xml").openStream())) { + String city; + while ((city = processor.getElementValue("City")) != null) { + System.out.println(city); + } + } + } +} \ No newline at end of file From f43a6b7baf37d75a64837c9d0b1ae11c00ce0022 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:16:48 +0200 Subject: [PATCH 09/46] 2 02 HW1 concurrentMultiply --- src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java index 80a344ac2..a7fa79a10 100644 --- a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java +++ b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java @@ -58,4 +58,4 @@ public static boolean compare(int[][] matrixA, int[][] matrixB) { } return true; } -} +} \ No newline at end of file From 80a043e2cd4d28e05da577dac1518c9c590e2d18 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:17:07 +0200 Subject: [PATCH 10/46] 2 03 HW1 concurrentMultiply2 --- .../javaops/masterjava/matrix/MainMatrix.java | 6 +- .../javaops/masterjava/matrix/MatrixUtil.java | 122 ++++++++++++++++-- 2 files changed, 110 insertions(+), 18 deletions(-) diff --git a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java index 0695132ef..1f1380674 100644 --- a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java +++ b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java @@ -4,10 +4,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -/** - * gkislin - * 03.07.2016 - */ public class MainMatrix { private static final int MATRIX_SIZE = 1000; private static final int THREAD_NUMBER = 10; @@ -30,7 +26,7 @@ public static void main(String[] args) throws ExecutionException, InterruptedExc singleThreadSum += duration; start = System.currentTimeMillis(); - final int[][] concurrentMatrixC = MatrixUtil.concurrentMultiply(matrixA, matrixB, executor); + final int[][] concurrentMatrixC = MatrixUtil.concurrentMultiplyStreams(matrixA, matrixB, Runtime.getRuntime().availableProcessors() - 1); duration = (System.currentTimeMillis() - start) / 1000.; out("Concurrent thread time, sec: %.3f", duration); concurrentThreadSum += duration; diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java index a7fa79a10..d00a67a05 100644 --- a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java +++ b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java @@ -1,35 +1,131 @@ package ru.javaops.masterjava.matrix; +import java.util.ArrayList; +import java.util.List; import java.util.Random; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; +import java.util.concurrent.*; +import java.util.stream.IntStream; -/** - * gkislin - * 03.07.2016 - */ public class MatrixUtil { - // TODO implement parallel multiplication matrixA*matrixB - public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { + public static int[][] concurrentMultiplyStreams(int[][] matrixA, int[][] matrixB, int threadNumber) + throws InterruptedException, ExecutionException { + final int matrixSize = matrixA.length; final int[][] matrixC = new int[matrixSize][matrixSize]; + new ForkJoinPool(threadNumber).submit( + () -> IntStream.range(0, matrixSize) + .parallel() + .forEach(row -> { + final int[] rowA = matrixA[row]; + final int[] rowC = matrixC[row]; + + for (int idx = 0; idx < matrixSize; idx++) { + final int elA = rowA[idx]; + final int[] rowB = matrixB[idx]; + for (int col = 0; col < matrixSize; col++) { + rowC[col] += elA * rowB[col]; + } + } + })).get(); + return matrixC; } - // TODO optimize by https://habrahabr.ru/post/114797/ - public static int[][] singleThreadMultiply(int[][] matrixA, int[][] matrixB) { + public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { final int matrixSize = matrixA.length; - final int[][] matrixC = new int[matrixSize][matrixSize]; + final int[][] matrixC = new int[matrixSize][]; + final int[][] matrixBT = new int[matrixSize][matrixSize]; for (int i = 0; i < matrixSize; i++) { for (int j = 0; j < matrixSize; j++) { + matrixBT[i][j] = matrixB[j][i]; + } + } + + List> tasks = new ArrayList<>(matrixSize); + for (int j = 0; j < matrixSize; j++) { + final int row = j; + tasks.add(() -> { + final int[] rowC = new int[matrixSize]; + for (int col = 0; col < matrixSize; col++) { + final int[] rowA = matrixA[row]; + final int[] columnB = matrixBT[col]; + int sum = 0; + for (int k = 0; k < matrixSize; k++) { + sum += rowA[k] * columnB[k]; + } + rowC[col] = sum; + } + matrixC[row] = rowC; + return null; + }); + } + executor.invokeAll(tasks); + return matrixC; + } + + public static int[][] concurrentMultiply2(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException { + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; + final CountDownLatch latch = new CountDownLatch(matrixSize); + + for (int row = 0; row < matrixSize; row++) { + final int[] rowA = matrixA[row]; + final int[] rowC = matrixC[row]; + + executor.submit(() -> { + for (int idx = 0; idx < matrixSize; idx++) { + final int elA = rowA[idx]; + final int[] rowB = matrixB[idx]; + for (int col = 0; col < matrixSize; col++) { + rowC[col] += elA * rowB[col]; + } + } + latch.countDown(); + }); + } + latch.await(); + return matrixC; + } + + public static int[][] singleThreadMultiplyOpt(int[][] matrixA, int[][] matrixB) { + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; + + for (int col = 0; col < matrixSize; col++) { + final int[] columnB = new int[matrixSize]; + for (int k = 0; k < matrixSize; k++) { + columnB[k] = matrixB[k][col]; + } + + for (int row = 0; row < matrixSize; row++) { int sum = 0; + final int[] rowA = matrixA[row]; for (int k = 0; k < matrixSize; k++) { - sum += matrixA[i][k] * matrixB[k][j]; + sum += rowA[k] * columnB[k]; + } + matrixC[row][col] = sum; + } + } + return matrixC; + } + + public static int[][] singleThreadMultiplyOpt2(int[][] matrixA, int[][] matrixB) { + final int matrixSize = matrixA.length; + final int[][] matrixC = new int[matrixSize][matrixSize]; + + for (int row = 0; row < matrixSize; row++) { + final int[] rowA = matrixA[row]; + final int[] rowC = matrixC[row]; + + for (int idx = 0; idx < matrixSize; idx++) { + final int elA = rowA[idx]; + final int[] rowB = matrixB[idx]; + for (int col = 0; col < matrixSize; col++) { + rowC[col] += elA * rowB[col]; } - matrixC[i][j] = sum; } } return matrixC; From 69c04b9fde00036d2fa379a2b43aac5f96aeb01a Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:17:20 +0200 Subject: [PATCH 11/46] 2 04 JMH Benchmark --- pom.xml | 2 +- .../masterjava/matrix/MatrixBenchmark.java | 85 +++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java diff --git a/pom.xml b/pom.xml index 39e811e08..af2329fdb 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.1 + 3.7.0 ${java.version} ${java.version} diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java b/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java new file mode 100644 index 000000000..2df2fc674 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java @@ -0,0 +1,85 @@ +package ru.javaops.masterjava.matrix; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.runner.options.TimeValue; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +@Warmup(iterations = 10) +@Measurement(iterations = 10) +@BenchmarkMode({Mode.SingleShotTime}) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +@Threads(1) +@Fork(10) +@Timeout(time = 5, timeUnit = TimeUnit.MINUTES) +public class MatrixBenchmark { + + // Matrix size + private static final int MATRIX_SIZE = 1000; + + @Param({"3", "4", "10"}) + private int threadNumber; + + private static int[][] matrixA; + private static int[][] matrixB; + + @Setup + public void setUp() { + matrixA = MatrixUtil.create(MATRIX_SIZE); + matrixB = MatrixUtil.create(MATRIX_SIZE); + } + + private ExecutorService executor; + + public static void main(String[] args) throws RunnerException { + Options options = new OptionsBuilder() + .include(MatrixBenchmark.class.getSimpleName()) + .threads(1) + .forks(10) + .timeout(TimeValue.minutes(5)) + .build(); + new Runner(options).run(); + } + + // @Benchmark + public int[][] singleThreadMultiplyOpt() throws Exception { + return MatrixUtil.singleThreadMultiplyOpt(matrixA, matrixB); + } + + // @Benchmark + public int[][] singleThreadMultiplyOpt2() throws Exception { + return MatrixUtil.singleThreadMultiplyOpt(matrixA, matrixB); + } + + @Benchmark + public int[][] concurrentMultiplyStreams() throws Exception { + return MatrixUtil.concurrentMultiplyStreams(matrixA, matrixB, threadNumber); + } + + // @Benchmark + public int[][] concurrentMultiply() throws Exception { + return MatrixUtil.concurrentMultiply(matrixA, matrixB, executor); + } + + @Benchmark + public int[][] concurrentMultiply2() throws Exception { + return MatrixUtil.concurrentMultiply2(matrixA, matrixB, executor); + } + + @Setup + public void setup() { + executor = Executors.newFixedThreadPool(threadNumber); + } + + @TearDown + public void tearDown() { + executor.shutdown(); + } +} \ No newline at end of file From d35bfbb226207b54aca62940de2c578198f72e9b Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:17:40 +0200 Subject: [PATCH 12/46] 2 06 xml scheme --- .../masterjava/xml/schema/CityType.java | 94 +++++++ .../masterjava/xml/schema/FlagType.java | 54 ++++ .../masterjava/xml/schema/ObjectFactory.java | 85 +++++++ .../masterjava/xml/schema/Payload.java | 233 ++++++++++++++++++ .../javaops/masterjava/xml/schema/User.java | 151 ++++++++++++ src/main/resources/payload.xsd | 56 +++++ src/test/resources/payload.xml | 23 ++ 7 files changed, 696 insertions(+) create mode 100644 src/main/java/ru/javaops/masterjava/xml/schema/CityType.java create mode 100644 src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java create mode 100644 src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java create mode 100644 src/main/java/ru/javaops/masterjava/xml/schema/Payload.java create mode 100644 src/main/java/ru/javaops/masterjava/xml/schema/User.java create mode 100644 src/main/resources/payload.xsd create mode 100644 src/test/resources/payload.xml diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java b/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java new file mode 100644 index 000000000..029e352cb --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java @@ -0,0 +1,94 @@ + +package ru.javaops.masterjava.xml.schema; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlID; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + + +/** + *

Java class for cityType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="cityType">
+ *   <simpleContent>
+ *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
+ *       <attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *     </extension>
+ *   </simpleContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "cityType", namespace = "http://javaops.ru", propOrder = { + "value" +}) +public class CityType { + + @XmlValue + protected String value; + @XmlAttribute(name = "id", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + @XmlID + @XmlSchemaType(name = "ID") + protected String id; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(String value) { + this.value = value; + } + + /** + * Gets the value of the id property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getId() { + return id; + } + + /** + * Sets the value of the id property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setId(String value) { + this.id = value; + } + +} diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java b/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java new file mode 100644 index 000000000..eda39fa9a --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java @@ -0,0 +1,54 @@ + +package ru.javaops.masterjava.xml.schema; + +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlEnumValue; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for flagType. + * + *

The following schema fragment specifies the expected content contained within this class. + *

+ *

+ * <simpleType name="flagType">
+ *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     <enumeration value="active"/>
+ *     <enumeration value="deleted"/>
+ *     <enumeration value="superuser"/>
+ *   </restriction>
+ * </simpleType>
+ * 
+ * + */ +@XmlType(name = "flagType", namespace = "http://javaops.ru") +@XmlEnum +public enum FlagType { + + @XmlEnumValue("active") + ACTIVE("active"), + @XmlEnumValue("deleted") + DELETED("deleted"), + @XmlEnumValue("superuser") + SUPERUSER("superuser"); + private final String value; + + FlagType(String v) { + value = v; + } + + public String value() { + return value; + } + + public static FlagType fromValue(String v) { + for (FlagType c: FlagType.values()) { + if (c.value.equals(v)) { + return c; + } + } + throw new IllegalArgumentException(v); + } + +} diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java b/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java new file mode 100644 index 000000000..e8f105e2a --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java @@ -0,0 +1,85 @@ + +package ru.javaops.masterjava.xml.schema; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the ru.javaops.masterjava.xml.schema package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _City_QNAME = new QName("http://javaops.ru", "City"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: ru.javaops.masterjava.xml.schema + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link Payload } + * + */ + public Payload createPayload() { + return new Payload(); + } + + /** + * Create an instance of {@link User } + * + */ + public User createUser() { + return new User(); + } + + /** + * Create an instance of {@link Payload.Cities } + * + */ + public Payload.Cities createPayloadCities() { + return new Payload.Cities(); + } + + /** + * Create an instance of {@link Payload.Users } + * + */ + public Payload.Users createPayloadUsers() { + return new Payload.Users(); + } + + /** + * Create an instance of {@link CityType } + * + */ + public CityType createCityType() { + return new CityType(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link CityType }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://javaops.ru", name = "City") + public JAXBElement createCity(CityType value) { + return new JAXBElement(_City_QNAME, CityType.class, null, value); + } + +} diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java b/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java new file mode 100644 index 000000000..2a6276490 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java @@ -0,0 +1,233 @@ + +package ru.javaops.masterjava.xml.schema; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <all>
+ *         <element name="Cities">
+ *           <complexType>
+ *             <complexContent>
+ *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 <sequence maxOccurs="unbounded">
+ *                   <element ref="{http://javaops.ru}City"/>
+ *                 </sequence>
+ *               </restriction>
+ *             </complexContent>
+ *           </complexType>
+ *         </element>
+ *         <element name="Users">
+ *           <complexType>
+ *             <complexContent>
+ *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 <sequence maxOccurs="unbounded" minOccurs="0">
+ *                   <element ref="{http://javaops.ru}User"/>
+ *                 </sequence>
+ *               </restriction>
+ *             </complexContent>
+ *           </complexType>
+ *         </element>
+ *       </all>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + +}) +@XmlRootElement(name = "Payload", namespace = "http://javaops.ru") +public class Payload { + + @XmlElement(name = "Cities", namespace = "http://javaops.ru", required = true) + protected Payload.Cities cities; + @XmlElement(name = "Users", namespace = "http://javaops.ru", required = true) + protected Payload.Users users; + + /** + * Gets the value of the cities property. + * + * @return + * possible object is + * {@link Payload.Cities } + * + */ + public Payload.Cities getCities() { + return cities; + } + + /** + * Sets the value of the cities property. + * + * @param value + * allowed object is + * {@link Payload.Cities } + * + */ + public void setCities(Payload.Cities value) { + this.cities = value; + } + + /** + * Gets the value of the users property. + * + * @return + * possible object is + * {@link Payload.Users } + * + */ + public Payload.Users getUsers() { + return users; + } + + /** + * Sets the value of the users property. + * + * @param value + * allowed object is + * {@link Payload.Users } + * + */ + public void setUsers(Payload.Users value) { + this.users = value; + } + + + /** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+     * <complexType>
+     *   <complexContent>
+     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       <sequence maxOccurs="unbounded">
+     *         <element ref="{http://javaops.ru}City"/>
+     *       </sequence>
+     *     </restriction>
+     *   </complexContent>
+     * </complexType>
+     * 
+ * + * + */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = { + "city" + }) + public static class Cities { + + @XmlElement(name = "City", namespace = "http://javaops.ru", required = true) + protected List city; + + /** + * Gets the value of the city property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the city property. + * + *

+ * For example, to add a new item, do as follows: + *

+         *    getCity().add(newItem);
+         * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link CityType } + * + * + */ + public List getCity() { + if (city == null) { + city = new ArrayList(); + } + return this.city; + } + + } + + + /** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+     * <complexType>
+     *   <complexContent>
+     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       <sequence maxOccurs="unbounded" minOccurs="0">
+     *         <element ref="{http://javaops.ru}User"/>
+     *       </sequence>
+     *     </restriction>
+     *   </complexContent>
+     * </complexType>
+     * 
+ * + * + */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = { + "user" + }) + public static class Users { + + @XmlElement(name = "User", namespace = "http://javaops.ru") + protected List user; + + /** + * Gets the value of the user property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the user property. + * + *

+ * For example, to add a new item, do as follows: + *

+         *    getUser().add(newItem);
+         * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link User } + * + * + */ + public List getUser() { + if (user == null) { + user = new ArrayList(); + } + return this.user; + } + + } + +} diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/User.java b/src/main/java/ru/javaops/masterjava/xml/schema/User.java new file mode 100644 index 000000000..b3430ce71 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/schema/User.java @@ -0,0 +1,151 @@ + +package ru.javaops.masterjava.xml.schema; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlIDREF; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="email" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="fullName" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *       </sequence>
+ *       <attribute name="flag" use="required" type="{http://javaops.ru}flagType" />
+ *       <attribute name="city" use="required" type="{http://www.w3.org/2001/XMLSchema}IDREF" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "email", + "fullName" +}) +@XmlRootElement(name = "User", namespace = "http://javaops.ru") +public class User { + + @XmlElement(namespace = "http://javaops.ru", required = true) + protected String email; + @XmlElement(namespace = "http://javaops.ru", required = true) + protected String fullName; + @XmlAttribute(name = "flag", required = true) + protected FlagType flag; + @XmlAttribute(name = "city", required = true) + @XmlIDREF + @XmlSchemaType(name = "IDREF") + protected Object city; + + /** + * Gets the value of the email property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getEmail() { + return email; + } + + /** + * Sets the value of the email property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setEmail(String value) { + this.email = value; + } + + /** + * Gets the value of the fullName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getFullName() { + return fullName; + } + + /** + * Sets the value of the fullName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setFullName(String value) { + this.fullName = value; + } + + /** + * Gets the value of the flag property. + * + * @return + * possible object is + * {@link FlagType } + * + */ + public FlagType getFlag() { + return flag; + } + + /** + * Sets the value of the flag property. + * + * @param value + * allowed object is + * {@link FlagType } + * + */ + public void setFlag(FlagType value) { + this.flag = value; + } + + /** + * Gets the value of the city property. + * + * @return + * possible object is + * {@link Object } + * + */ + public Object getCity() { + return city; + } + + /** + * Sets the value of the city property. + * + * @param value + * allowed object is + * {@link Object } + * + */ + public void setCity(Object value) { + this.city = value; + } + +} diff --git a/src/main/resources/payload.xsd b/src/main/resources/payload.xsd new file mode 100644 index 000000000..9ef1e46eb --- /dev/null +++ b/src/main/resources/payload.xsd @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/payload.xml b/src/test/resources/payload.xml new file mode 100644 index 000000000..796e99cb3 --- /dev/null +++ b/src/test/resources/payload.xml @@ -0,0 +1,23 @@ + + + + gmail@gmail.com + Full Name + + + admin@javaops.ru + Admin + + + mail@yandex.ru + Deleted + + + + Санкт-Петербург + Киев + Минск + + \ No newline at end of file From 5dfcacadaccc35e38cc3520b42bd14a42e59d5ae Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:17:56 +0200 Subject: [PATCH 13/46] 2 07 JAXB --- pom.xml | 65 ++++++++++++++ .../masterjava/xml/util/JaxbMarshaller.java | 39 ++++++++ .../masterjava/xml/util/JaxbParser.java | 88 +++++++++++++++++++ .../masterjava/xml/util/JaxbUnmarshaller.java | 33 +++++++ .../javaops/masterjava/xml/util/Schemas.java | 48 ++++++++++ .../masterjava/xml/util/JaxbParserTest.java | 40 +++++++++ src/test/resources/city.xml | 4 + 7 files changed, 317 insertions(+) create mode 100644 src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java create mode 100644 src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java create mode 100644 src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java create mode 100644 src/main/java/ru/javaops/masterjava/xml/util/Schemas.java create mode 100644 src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java create mode 100644 src/test/resources/city.xml diff --git a/pom.xml b/pom.xml index af2329fdb..884be4839 100644 --- a/pom.xml +++ b/pom.xml @@ -30,10 +30,75 @@ ${java.version}
+ + org.apache.maven.plugins + maven-surefire-plugin + 2.20.1 + + -Dfile.encoding=UTF-8 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.1.0 + + + package + + shade + + + benchmarks + + + org.openjdk.jmh.Main + + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + org.openjdk.jmh + jmh-core + RELEASE + + + org.openjdk.jmh + jmh-generator-annprocess + RELEASE + provided + + + com.google.guava + guava + 21.0 + + + junit + junit + 4.12 + test + diff --git a/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java b/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java new file mode 100644 index 000000000..d6006800f --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java @@ -0,0 +1,39 @@ +package ru.javaops.masterjava.xml.util; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.PropertyException; +import javax.xml.validation.Schema; +import java.io.StringWriter; +import java.io.Writer; + +public class JaxbMarshaller { + private Marshaller marshaller; + + public JaxbMarshaller(JAXBContext ctx) throws JAXBException { + marshaller = ctx.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); + marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); + } + + public void setProperty(String prop, Object value) throws PropertyException { + marshaller.setProperty(prop, value); + } + + public synchronized void setSchema(Schema schema) { + marshaller.setSchema(schema); + } + + public String marshal(Object instance) throws JAXBException { + StringWriter sw = new StringWriter(); + marshal(instance, sw); + return sw.toString(); + } + + public synchronized void marshal(Object instance, Writer writer) throws JAXBException { + marshaller.marshal(instance, writer); + } + +} diff --git a/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java b/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java new file mode 100644 index 000000000..b3a45f66c --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java @@ -0,0 +1,88 @@ +package ru.javaops.masterjava.xml.util; + +import org.xml.sax.SAXException; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.PropertyException; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import java.io.*; + + +/** + * Marshalling/Unmarshalling JAXB helper + * XML Facade + */ +public class JaxbParser { + + protected JaxbMarshaller jaxbMarshaller; + protected JaxbUnmarshaller jaxbUnmarshaller; + protected Schema schema; + + public JaxbParser(Class... classesToBeBound) { + try { + init(JAXBContext.newInstance(classesToBeBound)); + } catch (JAXBException e) { + throw new IllegalArgumentException(e); + } + } + + // http://stackoverflow.com/questions/30643802/what-is-jaxbcontext-newinstancestring-contextpath + public JaxbParser(String context) { + try { + init(JAXBContext.newInstance(context)); + } catch (JAXBException e) { + throw new IllegalArgumentException(e); + } + } + + private void init(JAXBContext ctx) throws JAXBException { + jaxbMarshaller = new JaxbMarshaller(ctx); + jaxbUnmarshaller = new JaxbUnmarshaller(ctx); + } + + // Unmarshaller + public T unmarshal(InputStream is) throws JAXBException { + return (T) jaxbUnmarshaller.unmarshal(is); + } + + public T unmarshal(Reader reader) throws JAXBException { + return (T) jaxbUnmarshaller.unmarshal(reader); + } + + public T unmarshal(String str) throws JAXBException { + return (T) jaxbUnmarshaller.unmarshal(str); + } + + // Marshaller + public void setMarshallerProperty(String prop, Object value) { + try { + jaxbMarshaller.setProperty(prop, value); + } catch (PropertyException e) { + throw new IllegalArgumentException(e); + } + } + + public String marshal(Object instance) throws JAXBException { + return jaxbMarshaller.marshal(instance); + } + + public void marshal(Object instance, Writer writer) throws JAXBException { + jaxbMarshaller.marshal(instance, writer); + } + + public void setSchema(Schema schema) { + this.schema = schema; + jaxbUnmarshaller.setSchema(schema); + jaxbMarshaller.setSchema(schema); + } + + public void validate(String str) throws IOException, SAXException { + validate(new StringReader(str)); + } + + public void validate(Reader reader) throws IOException, SAXException { + schema.newValidator().validate(new StreamSource(reader)); + } +} diff --git a/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java b/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java new file mode 100644 index 000000000..7a3e13461 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java @@ -0,0 +1,33 @@ +package ru.javaops.masterjava.xml.util; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.validation.Schema; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; + +public class JaxbUnmarshaller { + private Unmarshaller unmarshaller; + + public JaxbUnmarshaller(JAXBContext ctx) throws JAXBException { + unmarshaller = ctx.createUnmarshaller(); + } + + public synchronized void setSchema(Schema schema) { + unmarshaller.setSchema(schema); + } + + public synchronized Object unmarshal(InputStream is) throws JAXBException { + return unmarshaller.unmarshal(is); + } + + public synchronized Object unmarshal(Reader reader) throws JAXBException { + return unmarshaller.unmarshal(reader); + } + + public Object unmarshal(String str) throws JAXBException { + return unmarshal(new StringReader(str)); + } +} diff --git a/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java b/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java new file mode 100644 index 000000000..42f41df80 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java @@ -0,0 +1,48 @@ +package ru.javaops.masterjava.xml.util; + +import com.google.common.io.Resources; +import org.xml.sax.SAXException; + +import javax.xml.XMLConstants; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import java.io.File; +import java.io.StringReader; +import java.net.URL; + + +public class Schemas { + + // SchemaFactory is not thread-safe + private static final SchemaFactory SCHEMA_FACTORY = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + + public static synchronized Schema ofString(String xsd) { + try { + return SCHEMA_FACTORY.newSchema(new StreamSource(new StringReader(xsd))); + } catch (SAXException e) { + throw new IllegalArgumentException(e); + } + } + + public static synchronized Schema ofClasspath(String resource) { + // http://digitalsanctum.com/2012/11/30/how-to-read-file-contents-in-java-the-easy-way-with-guava/ + return ofURL(Resources.getResource(resource)); + } + + public static synchronized Schema ofURL(URL url) { + try { + return SCHEMA_FACTORY.newSchema(url); + } catch (SAXException e) { + throw new IllegalArgumentException(e); + } + } + + public static synchronized Schema ofFile(File file) { + try { + return SCHEMA_FACTORY.newSchema(file); + } catch (SAXException e) { + throw new IllegalArgumentException(e); + } + } +} diff --git a/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java b/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java new file mode 100644 index 000000000..623265428 --- /dev/null +++ b/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java @@ -0,0 +1,40 @@ +package ru.javaops.masterjava.xml.util; + +import com.google.common.io.Resources; +import org.junit.Test; +import ru.javaops.masterjava.xml.schema.CityType; +import ru.javaops.masterjava.xml.schema.ObjectFactory; +import ru.javaops.masterjava.xml.schema.Payload; + +import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; + +public class JaxbParserTest { + private static final JaxbParser JAXB_PARSER = new JaxbParser(ObjectFactory.class); + + static { + JAXB_PARSER.setSchema(Schemas.ofClasspath("payload.xsd")); + } + + @Test + public void testPayload() throws Exception { +// JaxbParserTest.class.getResourceAsStream("/city.xml") + Payload payload = JAXB_PARSER.unmarshal( + Resources.getResource("payload.xml").openStream()); + String strPayload = JAXB_PARSER.marshal(payload); + JAXB_PARSER.validate(strPayload); + System.out.println(strPayload); + } + + @Test + public void testCity() throws Exception { + JAXBElement cityElement = JAXB_PARSER.unmarshal( + Resources.getResource("city.xml").openStream()); + CityType city = cityElement.getValue(); + JAXBElement cityElement2 = + new JAXBElement<>(new QName("http://javaops.ru", "City"), CityType.class, city); + String strCity = JAXB_PARSER.marshal(cityElement2); + JAXB_PARSER.validate(strCity); + System.out.println(strCity); + } +} \ No newline at end of file diff --git a/src/test/resources/city.xml b/src/test/resources/city.xml new file mode 100644 index 000000000..8b0abcf8a --- /dev/null +++ b/src/test/resources/city.xml @@ -0,0 +1,4 @@ +Санкт-Петербург + \ No newline at end of file From 1d240914d0b045c2a20e4e44e9193adcaf982a56 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:18:12 +0200 Subject: [PATCH 14/46] 2 10 Xslt --- .../masterjava/xml/util/XsltProcessor.java | 43 +++++++++++++++++++ src/main/resources/cities.xsl | 9 ++++ .../xml/util/XsltProcessorTest.java | 18 ++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java create mode 100644 src/main/resources/cities.xsl create mode 100644 src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java diff --git a/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java b/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java new file mode 100644 index 000000000..019eeed3d --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java @@ -0,0 +1,43 @@ +package ru.javaops.masterjava.xml.util; + +import javax.xml.transform.*; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import java.io.*; +import java.nio.charset.StandardCharsets; + +public class XsltProcessor { + private static TransformerFactory FACTORY = TransformerFactory.newInstance(); + private final Transformer xformer; + + public XsltProcessor(InputStream xslInputStream) { + this(new BufferedReader(new InputStreamReader(xslInputStream, StandardCharsets.UTF_8))); + } + + public XsltProcessor(Reader xslReader) { + try { + Templates template = FACTORY.newTemplates(new StreamSource(xslReader)); + xformer = template.newTransformer(); + } catch (TransformerConfigurationException e) { + throw new IllegalStateException("XSLT transformer creation failed: " + e.toString(), e); + } + } + + public String transform(InputStream xmlInputStream) throws TransformerException { + StringWriter out = new StringWriter(); + transform(xmlInputStream, out); + return out.getBuffer().toString(); + } + + public void transform(InputStream xmlInputStream, Writer result) throws TransformerException { + transform(new BufferedReader(new InputStreamReader(xmlInputStream, StandardCharsets.UTF_8)), result); + } + + public void transform(Reader sourceReader, Writer result) throws TransformerException { + xformer.transform(new StreamSource(sourceReader), new StreamResult(result)); + } + + public static String getXsltHeader(String xslt) { + return "\n"; + } +} diff --git a/src/main/resources/cities.xsl b/src/main/resources/cities.xsl new file mode 100644 index 000000000..1c509124b --- /dev/null +++ b/src/main/resources/cities.xsl @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java b/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java new file mode 100644 index 000000000..d7f42a699 --- /dev/null +++ b/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java @@ -0,0 +1,18 @@ +package ru.javaops.masterjava.xml.util; + +import com.google.common.io.Resources; +import org.junit.Test; + +import java.io.InputStream; + +public class XsltProcessorTest { + @Test + public void transform() throws Exception { + try (InputStream xslInputStream = Resources.getResource("cities.xsl").openStream(); + InputStream xmlInputStream = Resources.getResource("payload.xml").openStream()) { + + XsltProcessor processor = new XsltProcessor(xslInputStream); + System.out.println(processor.transform(xmlInputStream)); + } + } +} From 1229ed376f5592ceaa4b48612de0d7e2647d586f Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:18:28 +0200 Subject: [PATCH 15/46] 2 09 XPath --- .../masterjava/xml/util/XPathProcessor.java | 58 +++++++++++++++++++ .../xml/util/XPathProcessorTest.java | 26 +++++++++ 2 files changed, 84 insertions(+) create mode 100644 src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java create mode 100644 src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java diff --git a/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java b/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java new file mode 100644 index 000000000..63baae5d1 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java @@ -0,0 +1,58 @@ +package ru.javaops.masterjava.xml.util; + +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; +import java.io.IOException; +import java.io.InputStream; + +public class XPathProcessor { + private static final DocumentBuilderFactory DOCUMENT_FACTORY = DocumentBuilderFactory.newInstance(); + private static final DocumentBuilder DOCUMENT_BUILDER; + + private static final XPathFactory XPATH_FACTORY = XPathFactory.newInstance(); + private static final XPath XPATH = XPATH_FACTORY.newXPath(); + + static { + DOCUMENT_FACTORY.setNamespaceAware(true); + try { + DOCUMENT_BUILDER = DOCUMENT_FACTORY.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new IllegalStateException(e); + } + } + + private final Document doc; + + public XPathProcessor(InputStream is) { + try { + doc = DOCUMENT_BUILDER.parse(is); + } catch (SAXException | IOException e) { + throw new IllegalArgumentException(e); + } + } + + public static synchronized XPathExpression getExpression(String exp) { + try { + return XPATH.compile(exp); + } catch (XPathExpressionException e) { + throw new IllegalArgumentException(e); + } + } + + public T evaluate(XPathExpression expression, QName type) { + try { + return (T) expression.evaluate(doc, type); + } catch (XPathExpressionException e) { + throw new IllegalArgumentException(e); + } + } +} diff --git a/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java b/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java new file mode 100644 index 000000000..199f676a1 --- /dev/null +++ b/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java @@ -0,0 +1,26 @@ +package ru.javaops.masterjava.xml.util; + +import com.google.common.io.Resources; +import org.junit.Test; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import java.io.InputStream; +import java.util.stream.IntStream; + +public class XPathProcessorTest { + @Test + public void getCities() throws Exception { + try (InputStream is = + Resources.getResource("payload.xml").openStream()) { + XPathProcessor processor = new XPathProcessor(is); + XPathExpression expression = + XPathProcessor.getExpression("/*[name()='Payload']/*[name()='Cities']/*[name()='City']/text()"); + NodeList nodes = processor.evaluate(expression, XPathConstants.NODESET); + IntStream.range(0, nodes.getLength()).forEach( + i -> System.out.println(nodes.item(i).getNodeValue()) + ); + } + } +} \ No newline at end of file From e9f02e9023ab2a9512c3293d5e9880ee8d1878ed Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:21:33 +0200 Subject: [PATCH 16/46] 2 09 XPath --- 1_1_MailService.patch | 96 ---- 2_01_HW1_singleThreadMultiplyOpt.patch | 54 -- 2_02_HW1_concurrentMultiply.patch | 182 ------ 2_03_HW1_concurrentMultiply2.patch | 245 -------- 2_04_JMH_Benchmark.patch | 113 ---- 2_05_JMH_main_jar.patch | 85 --- 2_06_xml_scheme.patch | 754 ------------------------- 2_07_JAXB.patch | 342 ----------- 2_08_StAX.patch | 109 ---- 2_09_XPath.patch | 101 ---- 2_10_Xslt.patch | 95 ---- 11 files changed, 2176 deletions(-) delete mode 100644 1_1_MailService.patch delete mode 100644 2_01_HW1_singleThreadMultiplyOpt.patch delete mode 100644 2_02_HW1_concurrentMultiply.patch delete mode 100644 2_03_HW1_concurrentMultiply2.patch delete mode 100644 2_04_JMH_Benchmark.patch delete mode 100644 2_05_JMH_main_jar.patch delete mode 100644 2_06_xml_scheme.patch delete mode 100644 2_07_JAXB.patch delete mode 100644 2_08_StAX.patch delete mode 100644 2_09_XPath.patch delete mode 100644 2_10_Xslt.patch diff --git a/1_1_MailService.patch b/1_1_MailService.patch deleted file mode 100644 index 59985d4a9..000000000 --- a/1_1_MailService.patch +++ /dev/null @@ -1,96 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/service/MailService.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/service/MailService.java (revision 500495ec05bb1a01c3811657f6d0770347ff8a8d) -+++ src/main/java/ru/javaops/masterjava/service/MailService.java (revision ) -@@ -1,8 +1,10 @@ - package ru.javaops.masterjava.service; - --import java.util.Collections; -+import java.util.ArrayList; - import java.util.List; - import java.util.Set; -+import java.util.concurrent.*; -+import java.util.stream.Collectors; - - public class MailService { - private static final String OK = "OK"; -@@ -11,10 +13,74 @@ - private static final String INTERRUPTED_BY_TIMEOUT = "+++ Interrupted by timeout"; - private static final String INTERRUPTED_EXCEPTION = "+++ InterruptedException"; - -+ private final ExecutorService mailExecutor = Executors.newFixedThreadPool(8); -+ - public GroupResult sendToList(final String template, final Set emails) throws Exception { -- return new GroupResult(0, Collections.emptyList(), null); -- } -+ final CompletionService completionService = new ExecutorCompletionService<>(mailExecutor); -+ -+ List> futures = emails.stream() -+ .map(email -> completionService.submit(() -> sendToUser(template, email))) -+ .collect(Collectors.toList()); -+ -+ return new Callable() { -+ private int success = 0; -+ private List failed = new ArrayList<>(); -+ -+ @Override -+ public GroupResult call() { -+ while (!futures.isEmpty()) { -+ try { -+ Future future = completionService.poll(10, TimeUnit.SECONDS); -+ if (future == null) { -+ return cancelWithFail(INTERRUPTED_BY_TIMEOUT); -+ } -+ futures.remove(future); -+ MailResult mailResult = future.get(); -+ if (mailResult.isOk()) { -+ success++; -+ } else { -+ failed.add(mailResult); -+ if (failed.size() >= 5) { -+ return cancelWithFail(INTERRUPTED_BY_FAULTS_NUMBER); -+ } -+ } -+ } catch (ExecutionException e) { -+ return cancelWithFail(e.getCause().toString()); -+ } catch (InterruptedException e) { -+ return cancelWithFail(INTERRUPTED_EXCEPTION); -+ } -+ } -+/* -+ for (Future future : futures) { -+ MailResult mailResult; -+ try { -+ mailResult = future.get(10, TimeUnit.SECONDS); -+ } catch (InterruptedException e) { -+ return cancelWithFail(INTERRUPTED_EXCEPTION); -+ } catch (ExecutionException e) { -+ return cancelWithFail(e.getCause().toString()); -+ } catch (TimeoutException e) { -+ return cancelWithFail(INTERRUPTED_BY_TIMEOUT); -+ } -+ if (mailResult.isOk()) { -+ success++; -+ } else { -+ failed.add(mailResult); -+ if (failed.size() >= 5) { -+ return cancelWithFail(INTERRUPTED_BY_FAULTS_NUMBER); -+ } -+ } -+ } -+*/ -+ return new GroupResult(success, failed, null); -+ } - -+ private GroupResult cancelWithFail(String cause) { -+ futures.forEach(f -> f.cancel(true)); -+ return new GroupResult(success, failed, cause); -+ } -+ }.call(); -+ } - - // dummy realization - public MailResult sendToUser(String template, String email) throws Exception { diff --git a/2_01_HW1_singleThreadMultiplyOpt.patch b/2_01_HW1_singleThreadMultiplyOpt.patch deleted file mode 100644 index c0661a165..000000000 --- a/2_01_HW1_singleThreadMultiplyOpt.patch +++ /dev/null @@ -1,54 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (revision d9b13eb2b75334b7485b55a83399716ab1899b7e) -+++ src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (revision bbace72e8bb84842d5ca73ba331e84d8e8d5ca6c) -@@ -24,7 +24,7 @@ - while (count < 6) { - System.out.println("Pass " + count); - long start = System.currentTimeMillis(); -- final int[][] matrixC = MatrixUtil.singleThreadMultiply(matrixA, matrixB); -+ final int[][] matrixC = MatrixUtil.singleThreadMultiplyOpt(matrixA, matrixB); - double duration = (System.currentTimeMillis() - start) / 1000.; - out("Single thread time, sec: %.3f", duration); - singleThreadSum += duration; -Index: src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (revision d9b13eb2b75334b7485b55a83399716ab1899b7e) -+++ src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (revision bbace72e8bb84842d5ca73ba331e84d8e8d5ca6c) -@@ -18,18 +18,24 @@ - return matrixC; - } - -- // TODO optimize by https://habrahabr.ru/post/114797/ -- public static int[][] singleThreadMultiply(int[][] matrixA, int[][] matrixB) { -+ // Optimized by https://habrahabr.ru/post/114797/ -+ public static int[][] singleThreadMultiplyOpt(int[][] matrixA, int[][] matrixB) { - final int matrixSize = matrixA.length; - final int[][] matrixC = new int[matrixSize][matrixSize]; - -- for (int i = 0; i < matrixSize; i++) { -- for (int j = 0; j < matrixSize; j++) { -+ for (int col = 0; col < matrixSize; col++) { -+ final int[] columnB = new int[matrixSize]; -+ for (int k = 0; k < matrixSize; k++) { -+ columnB[k] = matrixB[k][col]; -+ } -+ -+ for (int row = 0; row < matrixSize; row++) { - int sum = 0; -+ final int[] rowA = matrixA[row]; - for (int k = 0; k < matrixSize; k++) { -- sum += matrixA[i][k] * matrixB[k][j]; -+ sum += rowA[k] * columnB[k]; - } -- matrixC[i][j] = sum; -+ matrixC[row][col] = sum; - } - } - return matrixC; diff --git a/2_02_HW1_concurrentMultiply.patch b/2_02_HW1_concurrentMultiply.patch deleted file mode 100644 index 125962b60..000000000 --- a/2_02_HW1_concurrentMultiply.patch +++ /dev/null @@ -1,182 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (date 1508266595000) -+++ src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (date 1508268723000) -@@ -1,8 +1,9 @@ - package ru.javaops.masterjava.matrix; - --import java.util.Random; --import java.util.concurrent.ExecutionException; --import java.util.concurrent.ExecutorService; -+import java.util.*; -+import java.util.concurrent.*; -+import java.util.stream.Collectors; -+import java.util.stream.IntStream; - - /** - * gkislin -@@ -10,11 +11,153 @@ - */ - public class MatrixUtil { - -- // TODO implement parallel multiplication matrixA*matrixB - public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { - final int matrixSize = matrixA.length; - final int[][] matrixC = new int[matrixSize][matrixSize]; - -+ class ColumnMultipleResult { -+ private final int col; -+ private final int[] columnC; -+ -+ private ColumnMultipleResult(int col, int[] columnC) { -+ this.col = col; -+ this.columnC = columnC; -+ } -+ } -+ -+ final CompletionService completionService = new ExecutorCompletionService<>(executor); -+ -+ for (int j = 0; j < matrixSize; j++) { -+ final int col = j; -+ final int[] columnB = new int[matrixSize]; -+ for (int k = 0; k < matrixSize; k++) { -+ columnB[k] = matrixB[k][col]; -+ } -+ completionService.submit(() -> { -+ final int[] columnC = new int[matrixSize]; -+ -+ for (int row = 0; row < matrixSize; row++) { -+ final int[] rowA = matrixA[row]; -+ int sum = 0; -+ for (int k = 0; k < matrixSize; k++) { -+ sum += rowA[k] * columnB[k]; -+ } -+ columnC[row] = sum; -+ } -+ return new ColumnMultipleResult(col, columnC); -+ }); -+ } -+ -+ for (int i = 0; i < matrixSize; i++) { -+ ColumnMultipleResult res = completionService.take().get(); -+ for (int k = 0; k < matrixSize; k++) { -+ matrixC[k][res.col] = res.columnC[k]; -+ } -+ } -+ return matrixC; -+ } -+ -+ public static int[][] concurrentMultiplyCayman(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { -+ final int matrixSize = matrixA.length; -+ final int[][] matrixResult = new int[matrixSize][matrixSize]; -+ final int threadCount = Runtime.getRuntime().availableProcessors(); -+ final int maxIndex = matrixSize * matrixSize; -+ final int cellsInThread = maxIndex / threadCount; -+ final int[][] matrixBFinal = new int[matrixSize][matrixSize]; -+ -+ for (int i = 0; i < matrixSize; i++) { -+ for (int j = 0; j < matrixSize; j++) { -+ matrixBFinal[i][j] = matrixB[j][i]; -+ } -+ } -+ -+ Set> threads = new HashSet<>(); -+ int fromIndex = 0; -+ for (int i = 1; i <= threadCount; i++) { -+ final int toIndex = i == threadCount ? maxIndex : fromIndex + cellsInThread; -+ final int firstIndexFinal = fromIndex; -+ threads.add(() -> { -+ for (int j = firstIndexFinal; j < toIndex; j++) { -+ final int row = j / matrixSize; -+ final int col = j % matrixSize; -+ -+ int sum = 0; -+ for (int k = 0; k < matrixSize; k++) { -+ sum += matrixA[row][k] * matrixBFinal[col][k]; -+ } -+ matrixResult[row][col] = sum; -+ } -+ return true; -+ }); -+ fromIndex = toIndex; -+ } -+ executor.invokeAll(threads); -+ return matrixResult; -+ } -+ -+ public static int[][] concurrentMultiplyDarthVader(int[][] matrixA, int[][] matrixB, ExecutorService executor) -+ throws InterruptedException, ExecutionException { -+ -+ final int matrixSize = matrixA.length; -+ final int[][] matrixC = new int[matrixSize][matrixSize]; -+ -+ List> tasks = IntStream.range(0, matrixSize) -+ .parallel() -+ .mapToObj(i -> new Callable() { -+ private final int[] tempColumn = new int[matrixSize]; -+ -+ @Override -+ public Void call() throws Exception { -+ for (int c = 0; c < matrixSize; c++) { -+ tempColumn[c] = matrixB[c][i]; -+ } -+ for (int j = 0; j < matrixSize; j++) { -+ int row[] = matrixA[j]; -+ int sum = 0; -+ for (int k = 0; k < matrixSize; k++) { -+ sum += tempColumn[k] * row[k]; -+ } -+ matrixC[j][i] = sum; -+ } -+ return null; -+ } -+ }) -+ .collect(Collectors.toList()); -+ -+ executor.invokeAll(tasks); -+ return matrixC; -+ } -+ -+ public static int[][] concurrentMultiply2(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { -+ final int matrixSize = matrixA.length; -+ final int[][] matrixC = new int[matrixSize][]; -+ -+ final int[][] matrixBT = new int[matrixSize][matrixSize]; -+ for (int i = 0; i < matrixSize; i++) { -+ for (int j = 0; j < matrixSize; j++) { -+ matrixBT[i][j] = matrixB[j][i]; -+ } -+ } -+ -+ List> tasks = new ArrayList<>(matrixSize); -+ for (int j = 0; j < matrixSize; j++) { -+ final int row = j; -+ tasks.add(() -> { -+ final int[] rowC = new int[matrixSize]; -+ for (int col = 0; col < matrixSize; col++) { -+ final int[] rowA = matrixA[row]; -+ final int[] columnB = matrixBT[col]; -+ int sum = 0; -+ for (int k = 0; k < matrixSize; k++) { -+ sum += rowA[k] * columnB[k]; -+ } -+ rowC[col] = sum; -+ } -+ matrixC[row] = rowC; -+ return null; -+ }); -+ } -+ executor.invokeAll(tasks); - return matrixC; - } - -@@ -64,4 +207,4 @@ - } - return true; - } --} -+} -\ No newline at end of file diff --git a/2_03_HW1_concurrentMultiply2.patch b/2_03_HW1_concurrentMultiply2.patch deleted file mode 100644 index 867926b60..000000000 --- a/2_03_HW1_concurrentMultiply2.patch +++ /dev/null @@ -1,245 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (date 1508268723000) -+++ src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (revision ) -@@ -1,134 +1,39 @@ - package ru.javaops.masterjava.matrix; - --import java.util.*; -+import java.util.ArrayList; -+import java.util.List; -+import java.util.Random; - import java.util.concurrent.*; --import java.util.stream.Collectors; - import java.util.stream.IntStream; - --/** -- * gkislin -- * 03.07.2016 -- */ - public class MatrixUtil { - -- public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { -- final int matrixSize = matrixA.length; -- final int[][] matrixC = new int[matrixSize][matrixSize]; -- -- class ColumnMultipleResult { -- private final int col; -- private final int[] columnC; -- -- private ColumnMultipleResult(int col, int[] columnC) { -- this.col = col; -- this.columnC = columnC; -- } -- } -- -- final CompletionService completionService = new ExecutorCompletionService<>(executor); -- -- for (int j = 0; j < matrixSize; j++) { -- final int col = j; -- final int[] columnB = new int[matrixSize]; -- for (int k = 0; k < matrixSize; k++) { -- columnB[k] = matrixB[k][col]; -- } -- completionService.submit(() -> { -- final int[] columnC = new int[matrixSize]; -- -- for (int row = 0; row < matrixSize; row++) { -- final int[] rowA = matrixA[row]; -- int sum = 0; -- for (int k = 0; k < matrixSize; k++) { -- sum += rowA[k] * columnB[k]; -- } -- columnC[row] = sum; -- } -- return new ColumnMultipleResult(col, columnC); -- }); -- } -- -- for (int i = 0; i < matrixSize; i++) { -- ColumnMultipleResult res = completionService.take().get(); -- for (int k = 0; k < matrixSize; k++) { -- matrixC[k][res.col] = res.columnC[k]; -- } -- } -- return matrixC; -- } -- -- public static int[][] concurrentMultiplyCayman(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { -- final int matrixSize = matrixA.length; -- final int[][] matrixResult = new int[matrixSize][matrixSize]; -- final int threadCount = Runtime.getRuntime().availableProcessors(); -- final int maxIndex = matrixSize * matrixSize; -- final int cellsInThread = maxIndex / threadCount; -- final int[][] matrixBFinal = new int[matrixSize][matrixSize]; -- -- for (int i = 0; i < matrixSize; i++) { -- for (int j = 0; j < matrixSize; j++) { -- matrixBFinal[i][j] = matrixB[j][i]; -- } -- } -- -- Set> threads = new HashSet<>(); -- int fromIndex = 0; -- for (int i = 1; i <= threadCount; i++) { -- final int toIndex = i == threadCount ? maxIndex : fromIndex + cellsInThread; -- final int firstIndexFinal = fromIndex; -- threads.add(() -> { -- for (int j = firstIndexFinal; j < toIndex; j++) { -- final int row = j / matrixSize; -- final int col = j % matrixSize; -- -- int sum = 0; -- for (int k = 0; k < matrixSize; k++) { -- sum += matrixA[row][k] * matrixBFinal[col][k]; -- } -- matrixResult[row][col] = sum; -- } -- return true; -- }); -- fromIndex = toIndex; -- } -- executor.invokeAll(threads); -- return matrixResult; -- } -- -- public static int[][] concurrentMultiplyDarthVader(int[][] matrixA, int[][] matrixB, ExecutorService executor) -+ public static int[][] concurrentMultiplyStreams(int[][] matrixA, int[][] matrixB, int threadNumber) - throws InterruptedException, ExecutionException { - - final int matrixSize = matrixA.length; - final int[][] matrixC = new int[matrixSize][matrixSize]; - -- List> tasks = IntStream.range(0, matrixSize) -- .parallel() -- .mapToObj(i -> new Callable() { -- private final int[] tempColumn = new int[matrixSize]; -+ new ForkJoinPool(threadNumber).submit( -+ () -> IntStream.range(0, matrixSize) -+ .parallel() -+ .forEach(row -> { -+ final int[] rowA = matrixA[row]; -+ final int[] rowC = matrixC[row]; - -- @Override -- public Void call() throws Exception { -- for (int c = 0; c < matrixSize; c++) { -- tempColumn[c] = matrixB[c][i]; -- } -- for (int j = 0; j < matrixSize; j++) { -- int row[] = matrixA[j]; -- int sum = 0; -- for (int k = 0; k < matrixSize; k++) { -- sum += tempColumn[k] * row[k]; -+ for (int idx = 0; idx < matrixSize; idx++) { -+ final int elA = rowA[idx]; -+ final int[] rowB = matrixB[idx]; -+ for (int col = 0; col < matrixSize; col++) { -+ rowC[col] += elA * rowB[col]; -+ } - } -- matrixC[j][i] = sum; -- } -- return null; -- } -- }) -- .collect(Collectors.toList()); -+ })).get(); - -- executor.invokeAll(tasks); - return matrixC; - } - -- public static int[][] concurrentMultiply2(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { -+ public static int[][] concurrentMultiply(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException, ExecutionException { - final int matrixSize = matrixA.length; - final int[][] matrixC = new int[matrixSize][]; - -@@ -161,7 +66,30 @@ - return matrixC; - } - -- // Optimized by https://habrahabr.ru/post/114797/ -+ public static int[][] concurrentMultiply2(int[][] matrixA, int[][] matrixB, ExecutorService executor) throws InterruptedException { -+ final int matrixSize = matrixA.length; -+ final int[][] matrixC = new int[matrixSize][matrixSize]; -+ final CountDownLatch latch = new CountDownLatch(matrixSize); -+ -+ for (int row = 0; row < matrixSize; row++) { -+ final int[] rowA = matrixA[row]; -+ final int[] rowC = matrixC[row]; -+ -+ executor.submit(() -> { -+ for (int idx = 0; idx < matrixSize; idx++) { -+ final int elA = rowA[idx]; -+ final int[] rowB = matrixB[idx]; -+ for (int col = 0; col < matrixSize; col++) { -+ rowC[col] += elA * rowB[col]; -+ } -+ } -+ latch.countDown(); -+ }); -+ } -+ latch.await(); -+ return matrixC; -+ } -+ - public static int[][] singleThreadMultiplyOpt(int[][] matrixA, int[][] matrixB) { - final int matrixSize = matrixA.length; - final int[][] matrixC = new int[matrixSize][matrixSize]; -@@ -183,6 +111,25 @@ - } - return matrixC; - } -+ -+ public static int[][] singleThreadMultiplyOpt2(int[][] matrixA, int[][] matrixB) { -+ final int matrixSize = matrixA.length; -+ final int[][] matrixC = new int[matrixSize][matrixSize]; -+ -+ for (int row = 0; row < matrixSize; row++) { -+ final int[] rowA = matrixA[row]; -+ final int[] rowC = matrixC[row]; -+ -+ for (int idx = 0; idx < matrixSize; idx++) { -+ final int elA = rowA[idx]; -+ final int[] rowB = matrixB[idx]; -+ for (int col = 0; col < matrixSize; col++) { -+ rowC[col] += elA * rowB[col]; -+ } -+ } -+ } -+ return matrixC; -+ } - - public static int[][] create(int size) { - int[][] matrix = new int[size][size]; -Index: src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (date 1508268723000) -+++ src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (revision ) -@@ -4,10 +4,6 @@ - import java.util.concurrent.ExecutorService; - import java.util.concurrent.Executors; - --/** -- * gkislin -- * 03.07.2016 -- */ - public class MainMatrix { - private static final int MATRIX_SIZE = 1000; - private static final int THREAD_NUMBER = 10; -@@ -30,7 +26,7 @@ - singleThreadSum += duration; - - start = System.currentTimeMillis(); -- final int[][] concurrentMatrixC = MatrixUtil.concurrentMultiply(matrixA, matrixB, executor); -+ final int[][] concurrentMatrixC = MatrixUtil.concurrentMultiplyStreams(matrixA, matrixB, Runtime.getRuntime().availableProcessors() - 1); - duration = (System.currentTimeMillis() - start) / 1000.; - out("Concurrent thread time, sec: %.3f", duration); - concurrentThreadSum += duration; diff --git a/2_04_JMH_Benchmark.patch b/2_04_JMH_Benchmark.patch deleted file mode 100644 index d5bd75f16..000000000 --- a/2_04_JMH_Benchmark.patch +++ /dev/null @@ -1,113 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (revision ) -+++ src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (revision ) -@@ -0,0 +1,70 @@ -+package ru.javaops.masterjava.matrix; -+ -+import org.openjdk.jmh.annotations.*; -+ -+import java.util.concurrent.ExecutorService; -+import java.util.concurrent.Executors; -+import java.util.concurrent.TimeUnit; -+ -+@Warmup(iterations = 10) -+@Measurement(iterations = 10) -+@BenchmarkMode({Mode.SingleShotTime}) -+@OutputTimeUnit(TimeUnit.MILLISECONDS) -+@State(Scope.Benchmark) -+@Threads(1) -+@Fork(10) -+@Timeout(time = 5, timeUnit = TimeUnit.MINUTES) -+public class MatrixBenchmark { -+ -+ // Matrix size -+ private static final int MATRIX_SIZE = 1000; -+ -+ @Param({"3", "4", "10"}) -+ private int threadNumber; -+ -+ private static int[][] matrixA; -+ private static int[][] matrixB; -+ -+ @Setup -+ public void setUp() { -+ matrixA = MatrixUtil.create(MATRIX_SIZE); -+ matrixB = MatrixUtil.create(MATRIX_SIZE); -+ } -+ -+ private ExecutorService executor; -+ -+ // @Benchmark -+ public int[][] singleThreadMultiplyOpt() throws Exception { -+ return MatrixUtil.singleThreadMultiplyOpt(matrixA, matrixB); -+ } -+ -+ // @Benchmark -+ public int[][] singleThreadMultiplyOpt2() throws Exception { -+ return MatrixUtil.singleThreadMultiplyOpt(matrixA, matrixB); -+ } -+ -+ @Benchmark -+ public int[][] concurrentMultiplyStreams() throws Exception { -+ return MatrixUtil.concurrentMultiplyStreams(matrixA, matrixB, threadNumber); -+ } -+ -+ // @Benchmark -+ public int[][] concurrentMultiply() throws Exception { -+ return MatrixUtil.concurrentMultiply(matrixA, matrixB, executor); -+ } -+ -+ @Benchmark -+ public int[][] concurrentMultiply2() throws Exception { -+ return MatrixUtil.concurrentMultiply2(matrixA, matrixB, executor); -+ } -+ -+ @Setup -+ public void setup() { -+ executor = Executors.newFixedThreadPool(threadNumber); -+ } -+ -+ @TearDown -+ public void tearDown() { -+ executor.shutdown(); -+ } -+} -\ No newline at end of file -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (date 1508790464000) -+++ pom.xml (revision ) -@@ -24,7 +24,7 @@ - - org.apache.maven.plugins - maven-compiler-plugin -- 3.1 -+ 3.7.0 - - ${java.version} - ${java.version} -@@ -34,6 +34,17 @@ - - - -+ -+ org.openjdk.jmh -+ jmh-core -+ RELEASE -+ -+ -+ org.openjdk.jmh -+ jmh-generator-annprocess -+ RELEASE -+ provided -+ - - - diff --git a/2_05_JMH_main_jar.patch b/2_05_JMH_main_jar.patch deleted file mode 100644 index 1ad9083f5..000000000 --- a/2_05_JMH_main_jar.patch +++ /dev/null @@ -1,85 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (date 1508792580000) -+++ src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (revision ) -@@ -1,6 +1,11 @@ - package ru.javaops.masterjava.matrix; - - import org.openjdk.jmh.annotations.*; -+import org.openjdk.jmh.runner.Runner; -+import org.openjdk.jmh.runner.RunnerException; -+import org.openjdk.jmh.runner.options.Options; -+import org.openjdk.jmh.runner.options.OptionsBuilder; -+import org.openjdk.jmh.runner.options.TimeValue; - - import java.util.concurrent.ExecutorService; - import java.util.concurrent.Executors; -@@ -33,6 +38,16 @@ - - private ExecutorService executor; - -+ public static void main(String[] args) throws RunnerException { -+ Options options = new OptionsBuilder() -+ .include(MatrixBenchmark.class.getSimpleName()) -+ .threads(1) -+ .forks(10) -+ .timeout(TimeValue.minutes(5)) -+ .build(); -+ new Runner(options).run(); -+ } -+ - // @Benchmark - public int[][] singleThreadMultiplyOpt() throws Exception { - return MatrixUtil.singleThreadMultiplyOpt(matrixA, matrixB); -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (date 1508792580000) -+++ pom.xml (revision ) -@@ -30,6 +30,41 @@ - ${java.version} - - -+ -+ org.apache.maven.plugins -+ maven-shade-plugin -+ 3.1.0 -+ -+ -+ package -+ -+ shade -+ -+ -+ benchmarks -+ -+ -+ org.openjdk.jmh.Main -+ -+ -+ -+ -+ -+ *:* -+ -+ META-INF/*.SF -+ META-INF/*.DSA -+ META-INF/*.RSA -+ -+ -+ -+ -+ -+ -+ - - - diff --git a/2_06_xml_scheme.patch b/2_06_xml_scheme.patch deleted file mode 100644 index 9650668ee..000000000 --- a/2_06_xml_scheme.patch +++ /dev/null @@ -1,754 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (revision ) -@@ -0,0 +1,85 @@ -+ -+package ru.javaops.masterjava.xml.schema; -+ -+import javax.xml.bind.JAXBElement; -+import javax.xml.bind.annotation.XmlElementDecl; -+import javax.xml.bind.annotation.XmlRegistry; -+import javax.xml.namespace.QName; -+ -+ -+/** -+ * This object contains factory methods for each -+ * Java content interface and Java element interface -+ * generated in the ru.javaops.masterjava.xml.schema package. -+ *

An ObjectFactory allows you to programatically -+ * construct new instances of the Java representation -+ * for XML content. The Java representation of XML -+ * content can consist of schema derived interfaces -+ * and classes representing the binding of schema -+ * type definitions, element declarations and model -+ * groups. Factory methods for each of these are -+ * provided in this class. -+ * -+ */ -+@XmlRegistry -+public class ObjectFactory { -+ -+ private final static QName _City_QNAME = new QName("http://javaops.ru", "City"); -+ -+ /** -+ * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: ru.javaops.masterjava.xml.schema -+ * -+ */ -+ public ObjectFactory() { -+ } -+ -+ /** -+ * Create an instance of {@link Payload } -+ * -+ */ -+ public Payload createPayload() { -+ return new Payload(); -+ } -+ -+ /** -+ * Create an instance of {@link User } -+ * -+ */ -+ public User createUser() { -+ return new User(); -+ } -+ -+ /** -+ * Create an instance of {@link Payload.Cities } -+ * -+ */ -+ public Payload.Cities createPayloadCities() { -+ return new Payload.Cities(); -+ } -+ -+ /** -+ * Create an instance of {@link Payload.Users } -+ * -+ */ -+ public Payload.Users createPayloadUsers() { -+ return new Payload.Users(); -+ } -+ -+ /** -+ * Create an instance of {@link CityType } -+ * -+ */ -+ public CityType createCityType() { -+ return new CityType(); -+ } -+ -+ /** -+ * Create an instance of {@link JAXBElement }{@code <}{@link CityType }{@code >}} -+ * -+ */ -+ @XmlElementDecl(namespace = "http://javaops.ru", name = "City") -+ public JAXBElement createCity(CityType value) { -+ return new JAXBElement(_City_QNAME, CityType.class, null, value); -+ } -+ -+} -Index: src/main/java/ru/javaops/masterjava/xml/schema/Payload.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (revision ) -@@ -0,0 +1,233 @@ -+ -+package ru.javaops.masterjava.xml.schema; -+ -+import java.util.ArrayList; -+import java.util.List; -+import javax.xml.bind.annotation.XmlAccessType; -+import javax.xml.bind.annotation.XmlAccessorType; -+import javax.xml.bind.annotation.XmlElement; -+import javax.xml.bind.annotation.XmlRootElement; -+import javax.xml.bind.annotation.XmlType; -+ -+ -+/** -+ *

Java class for anonymous complex type. -+ * -+ *

The following schema fragment specifies the expected content contained within this class. -+ * -+ *

-+ * <complexType>
-+ *   <complexContent>
-+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-+ *       <all>
-+ *         <element name="Cities">
-+ *           <complexType>
-+ *             <complexContent>
-+ *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-+ *                 <sequence maxOccurs="unbounded">
-+ *                   <element ref="{http://javaops.ru}City"/>
-+ *                 </sequence>
-+ *               </restriction>
-+ *             </complexContent>
-+ *           </complexType>
-+ *         </element>
-+ *         <element name="Users">
-+ *           <complexType>
-+ *             <complexContent>
-+ *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-+ *                 <sequence maxOccurs="unbounded" minOccurs="0">
-+ *                   <element ref="{http://javaops.ru}User"/>
-+ *                 </sequence>
-+ *               </restriction>
-+ *             </complexContent>
-+ *           </complexType>
-+ *         </element>
-+ *       </all>
-+ *     </restriction>
-+ *   </complexContent>
-+ * </complexType>
-+ * 
-+ * -+ * -+ */ -+@XmlAccessorType(XmlAccessType.FIELD) -+@XmlType(name = "", propOrder = { -+ -+}) -+@XmlRootElement(name = "Payload", namespace = "http://javaops.ru") -+public class Payload { -+ -+ @XmlElement(name = "Cities", namespace = "http://javaops.ru", required = true) -+ protected Payload.Cities cities; -+ @XmlElement(name = "Users", namespace = "http://javaops.ru", required = true) -+ protected Payload.Users users; -+ -+ /** -+ * Gets the value of the cities property. -+ * -+ * @return -+ * possible object is -+ * {@link Payload.Cities } -+ * -+ */ -+ public Payload.Cities getCities() { -+ return cities; -+ } -+ -+ /** -+ * Sets the value of the cities property. -+ * -+ * @param value -+ * allowed object is -+ * {@link Payload.Cities } -+ * -+ */ -+ public void setCities(Payload.Cities value) { -+ this.cities = value; -+ } -+ -+ /** -+ * Gets the value of the users property. -+ * -+ * @return -+ * possible object is -+ * {@link Payload.Users } -+ * -+ */ -+ public Payload.Users getUsers() { -+ return users; -+ } -+ -+ /** -+ * Sets the value of the users property. -+ * -+ * @param value -+ * allowed object is -+ * {@link Payload.Users } -+ * -+ */ -+ public void setUsers(Payload.Users value) { -+ this.users = value; -+ } -+ -+ -+ /** -+ *

Java class for anonymous complex type. -+ * -+ *

The following schema fragment specifies the expected content contained within this class. -+ * -+ *

-+     * <complexType>
-+     *   <complexContent>
-+     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-+     *       <sequence maxOccurs="unbounded">
-+     *         <element ref="{http://javaops.ru}City"/>
-+     *       </sequence>
-+     *     </restriction>
-+     *   </complexContent>
-+     * </complexType>
-+     * 
-+ * -+ * -+ */ -+ @XmlAccessorType(XmlAccessType.FIELD) -+ @XmlType(name = "", propOrder = { -+ "city" -+ }) -+ public static class Cities { -+ -+ @XmlElement(name = "City", namespace = "http://javaops.ru", required = true) -+ protected List city; -+ -+ /** -+ * Gets the value of the city property. -+ * -+ *

-+ * This accessor method returns a reference to the live list, -+ * not a snapshot. Therefore any modification you make to the -+ * returned list will be present inside the JAXB object. -+ * This is why there is not a set method for the city property. -+ * -+ *

-+ * For example, to add a new item, do as follows: -+ *

-+         *    getCity().add(newItem);
-+         * 
-+ * -+ * -+ *

-+ * Objects of the following type(s) are allowed in the list -+ * {@link CityType } -+ * -+ * -+ */ -+ public List getCity() { -+ if (city == null) { -+ city = new ArrayList(); -+ } -+ return this.city; -+ } -+ -+ } -+ -+ -+ /** -+ *

Java class for anonymous complex type. -+ * -+ *

The following schema fragment specifies the expected content contained within this class. -+ * -+ *

-+     * <complexType>
-+     *   <complexContent>
-+     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-+     *       <sequence maxOccurs="unbounded" minOccurs="0">
-+     *         <element ref="{http://javaops.ru}User"/>
-+     *       </sequence>
-+     *     </restriction>
-+     *   </complexContent>
-+     * </complexType>
-+     * 
-+ * -+ * -+ */ -+ @XmlAccessorType(XmlAccessType.FIELD) -+ @XmlType(name = "", propOrder = { -+ "user" -+ }) -+ public static class Users { -+ -+ @XmlElement(name = "User", namespace = "http://javaops.ru") -+ protected List user; -+ -+ /** -+ * Gets the value of the user property. -+ * -+ *

-+ * This accessor method returns a reference to the live list, -+ * not a snapshot. Therefore any modification you make to the -+ * returned list will be present inside the JAXB object. -+ * This is why there is not a set method for the user property. -+ * -+ *

-+ * For example, to add a new item, do as follows: -+ *

-+         *    getUser().add(newItem);
-+         * 
-+ * -+ * -+ *

-+ * Objects of the following type(s) are allowed in the list -+ * {@link User } -+ * -+ * -+ */ -+ public List getUser() { -+ if (user == null) { -+ user = new ArrayList(); -+ } -+ return this.user; -+ } -+ -+ } -+ -+} -Index: src/main/java/ru/javaops/masterjava/xml/schema/User.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/User.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/schema/User.java (revision ) -@@ -0,0 +1,151 @@ -+ -+package ru.javaops.masterjava.xml.schema; -+ -+import javax.xml.bind.annotation.XmlAccessType; -+import javax.xml.bind.annotation.XmlAccessorType; -+import javax.xml.bind.annotation.XmlAttribute; -+import javax.xml.bind.annotation.XmlElement; -+import javax.xml.bind.annotation.XmlIDREF; -+import javax.xml.bind.annotation.XmlRootElement; -+import javax.xml.bind.annotation.XmlSchemaType; -+import javax.xml.bind.annotation.XmlType; -+ -+ -+/** -+ *

Java class for anonymous complex type. -+ * -+ *

The following schema fragment specifies the expected content contained within this class. -+ * -+ *

-+ * <complexType>
-+ *   <complexContent>
-+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-+ *       <sequence>
-+ *         <element name="email" type="{http://www.w3.org/2001/XMLSchema}string"/>
-+ *         <element name="fullName" type="{http://www.w3.org/2001/XMLSchema}string"/>
-+ *       </sequence>
-+ *       <attribute name="flag" use="required" type="{http://javaops.ru}flagType" />
-+ *       <attribute name="city" use="required" type="{http://www.w3.org/2001/XMLSchema}IDREF" />
-+ *     </restriction>
-+ *   </complexContent>
-+ * </complexType>
-+ * 
-+ * -+ * -+ */ -+@XmlAccessorType(XmlAccessType.FIELD) -+@XmlType(name = "", propOrder = { -+ "email", -+ "fullName" -+}) -+@XmlRootElement(name = "User", namespace = "http://javaops.ru") -+public class User { -+ -+ @XmlElement(namespace = "http://javaops.ru", required = true) -+ protected String email; -+ @XmlElement(namespace = "http://javaops.ru", required = true) -+ protected String fullName; -+ @XmlAttribute(name = "flag", required = true) -+ protected FlagType flag; -+ @XmlAttribute(name = "city", required = true) -+ @XmlIDREF -+ @XmlSchemaType(name = "IDREF") -+ protected Object city; -+ -+ /** -+ * Gets the value of the email property. -+ * -+ * @return -+ * possible object is -+ * {@link String } -+ * -+ */ -+ public String getEmail() { -+ return email; -+ } -+ -+ /** -+ * Sets the value of the email property. -+ * -+ * @param value -+ * allowed object is -+ * {@link String } -+ * -+ */ -+ public void setEmail(String value) { -+ this.email = value; -+ } -+ -+ /** -+ * Gets the value of the fullName property. -+ * -+ * @return -+ * possible object is -+ * {@link String } -+ * -+ */ -+ public String getFullName() { -+ return fullName; -+ } -+ -+ /** -+ * Sets the value of the fullName property. -+ * -+ * @param value -+ * allowed object is -+ * {@link String } -+ * -+ */ -+ public void setFullName(String value) { -+ this.fullName = value; -+ } -+ -+ /** -+ * Gets the value of the flag property. -+ * -+ * @return -+ * possible object is -+ * {@link FlagType } -+ * -+ */ -+ public FlagType getFlag() { -+ return flag; -+ } -+ -+ /** -+ * Sets the value of the flag property. -+ * -+ * @param value -+ * allowed object is -+ * {@link FlagType } -+ * -+ */ -+ public void setFlag(FlagType value) { -+ this.flag = value; -+ } -+ -+ /** -+ * Gets the value of the city property. -+ * -+ * @return -+ * possible object is -+ * {@link Object } -+ * -+ */ -+ public Object getCity() { -+ return city; -+ } -+ -+ /** -+ * Sets the value of the city property. -+ * -+ * @param value -+ * allowed object is -+ * {@link Object } -+ * -+ */ -+ public void setCity(Object value) { -+ this.city = value; -+ } -+ -+} -Index: src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java (revision ) -@@ -0,0 +1,54 @@ -+ -+package ru.javaops.masterjava.xml.schema; -+ -+import javax.xml.bind.annotation.XmlEnum; -+import javax.xml.bind.annotation.XmlEnumValue; -+import javax.xml.bind.annotation.XmlType; -+ -+ -+/** -+ *

Java class for flagType. -+ * -+ *

The following schema fragment specifies the expected content contained within this class. -+ *

-+ *

-+ * <simpleType name="flagType">
-+ *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
-+ *     <enumeration value="active"/>
-+ *     <enumeration value="deleted"/>
-+ *     <enumeration value="superuser"/>
-+ *   </restriction>
-+ * </simpleType>
-+ * 
-+ * -+ */ -+@XmlType(name = "flagType", namespace = "http://javaops.ru") -+@XmlEnum -+public enum FlagType { -+ -+ @XmlEnumValue("active") -+ ACTIVE("active"), -+ @XmlEnumValue("deleted") -+ DELETED("deleted"), -+ @XmlEnumValue("superuser") -+ SUPERUSER("superuser"); -+ private final String value; -+ -+ FlagType(String v) { -+ value = v; -+ } -+ -+ public String value() { -+ return value; -+ } -+ -+ public static FlagType fromValue(String v) { -+ for (FlagType c: FlagType.values()) { -+ if (c.value.equals(v)) { -+ return c; -+ } -+ } -+ throw new IllegalArgumentException(v); -+ } -+ -+} -Index: src/test/resources/payload.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/test/resources/payload.xml (revision ) -+++ src/test/resources/payload.xml (revision ) -@@ -0,0 +1,23 @@ -+ -+ -+ -+ gmail@gmail.com -+ Full Name -+ -+ -+ admin@javaops.ru -+ Admin -+ -+ -+ mail@yandex.ru -+ Deleted -+ -+ -+ -+ Санкт-Петербург -+ Киев -+ Минск -+ -+ -\ No newline at end of file -Index: src/main/java/ru/javaops/masterjava/xml/schema/CityType.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/CityType.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/schema/CityType.java (revision ) -@@ -0,0 +1,94 @@ -+ -+package ru.javaops.masterjava.xml.schema; -+ -+import javax.xml.bind.annotation.XmlAccessType; -+import javax.xml.bind.annotation.XmlAccessorType; -+import javax.xml.bind.annotation.XmlAttribute; -+import javax.xml.bind.annotation.XmlID; -+import javax.xml.bind.annotation.XmlSchemaType; -+import javax.xml.bind.annotation.XmlType; -+import javax.xml.bind.annotation.XmlValue; -+import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -+ -+ -+/** -+ *

Java class for cityType complex type. -+ * -+ *

The following schema fragment specifies the expected content contained within this class. -+ * -+ *

-+ * <complexType name="cityType">
-+ *   <simpleContent>
-+ *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
-+ *       <attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
-+ *     </extension>
-+ *   </simpleContent>
-+ * </complexType>
-+ * 
-+ * -+ * -+ */ -+@XmlAccessorType(XmlAccessType.FIELD) -+@XmlType(name = "cityType", namespace = "http://javaops.ru", propOrder = { -+ "value" -+}) -+public class CityType { -+ -+ @XmlValue -+ protected String value; -+ @XmlAttribute(name = "id", required = true) -+ @XmlJavaTypeAdapter(CollapsedStringAdapter.class) -+ @XmlID -+ @XmlSchemaType(name = "ID") -+ protected String id; -+ -+ /** -+ * Gets the value of the value property. -+ * -+ * @return -+ * possible object is -+ * {@link String } -+ * -+ */ -+ public String getValue() { -+ return value; -+ } -+ -+ /** -+ * Sets the value of the value property. -+ * -+ * @param value -+ * allowed object is -+ * {@link String } -+ * -+ */ -+ public void setValue(String value) { -+ this.value = value; -+ } -+ -+ /** -+ * Gets the value of the id property. -+ * -+ * @return -+ * possible object is -+ * {@link String } -+ * -+ */ -+ public String getId() { -+ return id; -+ } -+ -+ /** -+ * Sets the value of the id property. -+ * -+ * @param value -+ * allowed object is -+ * {@link String } -+ * -+ */ -+ public void setId(String value) { -+ this.id = value; -+ } -+ -+} -Index: src/main/resources/payload.xsd -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/resources/payload.xsd (revision ) -+++ src/main/resources/payload.xsd (revision ) -@@ -0,0 +1,56 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -\ No newline at end of file diff --git a/2_07_JAXB.patch b/2_07_JAXB.patch deleted file mode 100644 index 5dfafecc9..000000000 --- a/2_07_JAXB.patch +++ /dev/null @@ -1,342 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (revision ) -@@ -0,0 +1,39 @@ -+package ru.javaops.masterjava.xml.util; -+ -+import javax.xml.bind.JAXBContext; -+import javax.xml.bind.JAXBException; -+import javax.xml.bind.Marshaller; -+import javax.xml.bind.PropertyException; -+import javax.xml.validation.Schema; -+import java.io.StringWriter; -+import java.io.Writer; -+ -+public class JaxbMarshaller { -+ private Marshaller marshaller; -+ -+ public JaxbMarshaller(JAXBContext ctx) throws JAXBException { -+ marshaller = ctx.createMarshaller(); -+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); -+ marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); -+ marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); -+ } -+ -+ public void setProperty(String prop, Object value) throws PropertyException { -+ marshaller.setProperty(prop, value); -+ } -+ -+ public synchronized void setSchema(Schema schema) { -+ marshaller.setSchema(schema); -+ } -+ -+ public String marshal(Object instance) throws JAXBException { -+ StringWriter sw = new StringWriter(); -+ marshal(instance, sw); -+ return sw.toString(); -+ } -+ -+ public synchronized void marshal(Object instance, Writer writer) throws JAXBException { -+ marshaller.marshal(instance, writer); -+ } -+ -+} -Index: src/main/java/ru/javaops/masterjava/xml/util/Schemas.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/Schemas.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/util/Schemas.java (revision ) -@@ -0,0 +1,48 @@ -+package ru.javaops.masterjava.xml.util; -+ -+import com.google.common.io.Resources; -+import org.xml.sax.SAXException; -+ -+import javax.xml.XMLConstants; -+import javax.xml.transform.stream.StreamSource; -+import javax.xml.validation.Schema; -+import javax.xml.validation.SchemaFactory; -+import java.io.File; -+import java.io.StringReader; -+import java.net.URL; -+ -+ -+public class Schemas { -+ -+ // SchemaFactory is not thread-safe -+ private static final SchemaFactory SCHEMA_FACTORY = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); -+ -+ public static synchronized Schema ofString(String xsd) { -+ try { -+ return SCHEMA_FACTORY.newSchema(new StreamSource(new StringReader(xsd))); -+ } catch (SAXException e) { -+ throw new IllegalArgumentException(e); -+ } -+ } -+ -+ public static synchronized Schema ofClasspath(String resource) { -+ // http://digitalsanctum.com/2012/11/30/how-to-read-file-contents-in-java-the-easy-way-with-guava/ -+ return ofURL(Resources.getResource(resource)); -+ } -+ -+ public static synchronized Schema ofURL(URL url) { -+ try { -+ return SCHEMA_FACTORY.newSchema(url); -+ } catch (SAXException e) { -+ throw new IllegalArgumentException(e); -+ } -+ } -+ -+ public static synchronized Schema ofFile(File file) { -+ try { -+ return SCHEMA_FACTORY.newSchema(file); -+ } catch (SAXException e) { -+ throw new IllegalArgumentException(e); -+ } -+ } -+} -Index: src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (revision ) -+++ src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (revision ) -@@ -0,0 +1,40 @@ -+package ru.javaops.masterjava.xml.util; -+ -+import com.google.common.io.Resources; -+import org.junit.Test; -+import ru.javaops.masterjava.xml.schema.CityType; -+import ru.javaops.masterjava.xml.schema.ObjectFactory; -+import ru.javaops.masterjava.xml.schema.Payload; -+ -+import javax.xml.bind.JAXBElement; -+import javax.xml.namespace.QName; -+ -+public class JaxbParserTest { -+ private static final JaxbParser JAXB_PARSER = new JaxbParser(ObjectFactory.class); -+ -+ static { -+ JAXB_PARSER.setSchema(Schemas.ofClasspath("payload.xsd")); -+ } -+ -+ @Test -+ public void testPayload() throws Exception { -+// JaxbParserTest.class.getResourceAsStream("/city.xml") -+ Payload payload = JAXB_PARSER.unmarshal( -+ Resources.getResource("payload.xml").openStream()); -+ String strPayload = JAXB_PARSER.marshal(payload); -+ JAXB_PARSER.validate(strPayload); -+ System.out.println(strPayload); -+ } -+ -+ @Test -+ public void testCity() throws Exception { -+ JAXBElement cityElement = JAXB_PARSER.unmarshal( -+ Resources.getResource("city.xml").openStream()); -+ CityType city = cityElement.getValue(); -+ JAXBElement cityElement2 = -+ new JAXBElement<>(new QName("http://javaops.ru", "City"), CityType.class, city); -+ String strCity = JAXB_PARSER.marshal(cityElement2); -+ JAXB_PARSER.validate(strCity); -+ System.out.println(strCity); -+ } -+} -\ No newline at end of file -Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision ) -@@ -0,0 +1,88 @@ -+package ru.javaops.masterjava.xml.util; -+ -+import org.xml.sax.SAXException; -+ -+import javax.xml.bind.JAXBContext; -+import javax.xml.bind.JAXBException; -+import javax.xml.bind.PropertyException; -+import javax.xml.transform.stream.StreamSource; -+import javax.xml.validation.Schema; -+import java.io.*; -+ -+ -+/** -+ * Marshalling/Unmarshalling JAXB helper -+ * XML Facade -+ */ -+public class JaxbParser { -+ -+ protected JaxbMarshaller jaxbMarshaller; -+ protected JaxbUnmarshaller jaxbUnmarshaller; -+ protected Schema schema; -+ -+ public JaxbParser(Class... classesToBeBound) { -+ try { -+ init(JAXBContext.newInstance(classesToBeBound)); -+ } catch (JAXBException e) { -+ throw new IllegalArgumentException(e); -+ } -+ } -+ -+ // http://stackoverflow.com/questions/30643802/what-is-jaxbcontext-newinstancestring-contextpath -+ public JaxbParser(String context) { -+ try { -+ init(JAXBContext.newInstance(context)); -+ } catch (JAXBException e) { -+ throw new IllegalArgumentException(e); -+ } -+ } -+ -+ private void init(JAXBContext ctx) throws JAXBException { -+ jaxbMarshaller = new JaxbMarshaller(ctx); -+ jaxbUnmarshaller = new JaxbUnmarshaller(ctx); -+ } -+ -+ // Unmarshaller -+ public T unmarshal(InputStream is) throws JAXBException { -+ return (T) jaxbUnmarshaller.unmarshal(is); -+ } -+ -+ public T unmarshal(Reader reader) throws JAXBException { -+ return (T) jaxbUnmarshaller.unmarshal(reader); -+ } -+ -+ public T unmarshal(String str) throws JAXBException { -+ return (T) jaxbUnmarshaller.unmarshal(str); -+ } -+ -+ // Marshaller -+ public void setMarshallerProperty(String prop, Object value) { -+ try { -+ jaxbMarshaller.setProperty(prop, value); -+ } catch (PropertyException e) { -+ throw new IllegalArgumentException(e); -+ } -+ } -+ -+ public String marshal(Object instance) throws JAXBException { -+ return jaxbMarshaller.marshal(instance); -+ } -+ -+ public void marshal(Object instance, Writer writer) throws JAXBException { -+ jaxbMarshaller.marshal(instance, writer); -+ } -+ -+ public void setSchema(Schema schema) { -+ this.schema = schema; -+ jaxbUnmarshaller.setSchema(schema); -+ jaxbMarshaller.setSchema(schema); -+ } -+ -+ public void validate(String str) throws IOException, SAXException { -+ validate(new StringReader(str)); -+ } -+ -+ public void validate(Reader reader) throws IOException, SAXException { -+ schema.newValidator().validate(new StreamSource(reader)); -+ } -+} -Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision ) -@@ -0,0 +1,33 @@ -+package ru.javaops.masterjava.xml.util; -+ -+import javax.xml.bind.JAXBContext; -+import javax.xml.bind.JAXBException; -+import javax.xml.bind.Unmarshaller; -+import javax.xml.validation.Schema; -+import java.io.InputStream; -+import java.io.Reader; -+import java.io.StringReader; -+ -+public class JaxbUnmarshaller { -+ private Unmarshaller unmarshaller; -+ -+ public JaxbUnmarshaller(JAXBContext ctx) throws JAXBException { -+ unmarshaller = ctx.createUnmarshaller(); -+ } -+ -+ public synchronized void setSchema(Schema schema) { -+ unmarshaller.setSchema(schema); -+ } -+ -+ public synchronized Object unmarshal(InputStream is) throws JAXBException { -+ return unmarshaller.unmarshal(is); -+ } -+ -+ public synchronized Object unmarshal(Reader reader) throws JAXBException { -+ return unmarshaller.unmarshal(reader); -+ } -+ -+ public Object unmarshal(String str) throws JAXBException { -+ return unmarshal(new StringReader(str)); -+ } -+} -Index: src/test/resources/city.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/test/resources/city.xml (revision ) -+++ src/test/resources/city.xml (revision ) -@@ -0,0 +1,4 @@ -+Санкт-Петербург -+ -\ No newline at end of file -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (date 1508793189000) -+++ pom.xml (revision ) -@@ -32,6 +32,14 @@ - - - org.apache.maven.plugins -+ maven-surefire-plugin -+ 2.20.1 -+ -+ -Dfile.encoding=UTF-8 -+ -+ -+ -+ org.apache.maven.plugins - maven-shade-plugin - 3.1.0 - -@@ -79,6 +87,17 @@ - jmh-generator-annprocess - RELEASE - provided -+
-+ -+ com.google.guava -+ guava -+ 21.0 -+ -+ -+ junit -+ junit -+ 4.12 -+ test - -
- diff --git a/2_08_StAX.patch b/2_08_StAX.patch deleted file mode 100644 index 228cca7b1..000000000 --- a/2_08_StAX.patch +++ /dev/null @@ -1,109 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision ) -@@ -0,0 +1,56 @@ -+package ru.javaops.masterjava.xml.util; -+ -+import javax.xml.stream.XMLInputFactory; -+import javax.xml.stream.XMLStreamException; -+import javax.xml.stream.XMLStreamReader; -+import javax.xml.stream.events.XMLEvent; -+import java.io.InputStream; -+ -+public class StaxStreamProcessor implements AutoCloseable { -+ private static final XMLInputFactory FACTORY = XMLInputFactory.newInstance(); -+ -+ private final XMLStreamReader reader; -+ -+ public StaxStreamProcessor(InputStream is) throws XMLStreamException { -+ reader = FACTORY.createXMLStreamReader(is); -+ } -+ -+ public XMLStreamReader getReader() { -+ return reader; -+ } -+ -+ public boolean doUntil(int stopEvent, String value) throws XMLStreamException { -+ while (reader.hasNext()) { -+ int event = reader.next(); -+ if (event == stopEvent) { -+ if (value.equals(getValue(event))) { -+ return true; -+ } -+ } -+ } -+ return false; -+ } -+ -+ public String getValue(int event) throws XMLStreamException { -+ return (event == XMLEvent.CHARACTERS) ? reader.getText() : reader.getLocalName(); -+ } -+ -+ public String getElementValue(String element) throws XMLStreamException { -+ return doUntil(XMLEvent.START_ELEMENT, element) ? reader.getElementText() : null; -+ } -+ -+ public String getText() throws XMLStreamException { -+ return reader.getElementText(); -+ } -+ -+ @Override -+ public void close() { -+ if (reader != null) { -+ try { -+ reader.close(); -+ } catch (XMLStreamException e) { -+ // empty -+ } -+ } -+ } -+} -Index: src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java (revision ) -+++ src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java (revision ) -@@ -0,0 +1,36 @@ -+package ru.javaops.masterjava.xml.util; -+ -+import com.google.common.io.Resources; -+import org.junit.Test; -+ -+import javax.xml.stream.XMLStreamReader; -+import javax.xml.stream.events.XMLEvent; -+ -+public class StaxStreamProcessorTest { -+ @Test -+ public void readCities() throws Exception { -+ try (StaxStreamProcessor processor = -+ new StaxStreamProcessor(Resources.getResource("payload.xml").openStream())) { -+ XMLStreamReader reader = processor.getReader(); -+ while (reader.hasNext()) { -+ int event = reader.next(); -+ if (event == XMLEvent.START_ELEMENT) { -+ if ("City".equals(reader.getLocalName())) { -+ System.out.println(reader.getElementText()); -+ } -+ } -+ } -+ } -+ } -+ -+ @Test -+ public void readCities2() throws Exception { -+ try (StaxStreamProcessor processor = -+ new StaxStreamProcessor(Resources.getResource("payload.xml").openStream())) { -+ String city; -+ while ((city = processor.getElementValue("City")) != null) { -+ System.out.println(city); -+ } -+ } -+ } -+} -\ No newline at end of file diff --git a/2_09_XPath.patch b/2_09_XPath.patch deleted file mode 100644 index f662f3b82..000000000 --- a/2_09_XPath.patch +++ /dev/null @@ -1,101 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java (revision ) -@@ -0,0 +1,58 @@ -+package ru.javaops.masterjava.xml.util; -+ -+import org.w3c.dom.Document; -+import org.xml.sax.SAXException; -+ -+import javax.xml.namespace.QName; -+import javax.xml.parsers.DocumentBuilder; -+import javax.xml.parsers.DocumentBuilderFactory; -+import javax.xml.parsers.ParserConfigurationException; -+import javax.xml.xpath.XPath; -+import javax.xml.xpath.XPathExpression; -+import javax.xml.xpath.XPathExpressionException; -+import javax.xml.xpath.XPathFactory; -+import java.io.IOException; -+import java.io.InputStream; -+ -+public class XPathProcessor { -+ private static final DocumentBuilderFactory DOCUMENT_FACTORY = DocumentBuilderFactory.newInstance(); -+ private static final DocumentBuilder DOCUMENT_BUILDER; -+ -+ private static final XPathFactory XPATH_FACTORY = XPathFactory.newInstance(); -+ private static final XPath XPATH = XPATH_FACTORY.newXPath(); -+ -+ static { -+ DOCUMENT_FACTORY.setNamespaceAware(true); -+ try { -+ DOCUMENT_BUILDER = DOCUMENT_FACTORY.newDocumentBuilder(); -+ } catch (ParserConfigurationException e) { -+ throw new IllegalStateException(e); -+ } -+ } -+ -+ private final Document doc; -+ -+ public XPathProcessor(InputStream is) { -+ try { -+ doc = DOCUMENT_BUILDER.parse(is); -+ } catch (SAXException | IOException e) { -+ throw new IllegalArgumentException(e); -+ } -+ } -+ -+ public static synchronized XPathExpression getExpression(String exp) { -+ try { -+ return XPATH.compile(exp); -+ } catch (XPathExpressionException e) { -+ throw new IllegalArgumentException(e); -+ } -+ } -+ -+ public T evaluate(XPathExpression expression, QName type) { -+ try { -+ return (T) expression.evaluate(doc, type); -+ } catch (XPathExpressionException e) { -+ throw new IllegalArgumentException(e); -+ } -+ } -+} -Index: src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java (revision ) -+++ src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java (revision ) -@@ -0,0 +1,26 @@ -+package ru.javaops.masterjava.xml.util; -+ -+import com.google.common.io.Resources; -+import org.junit.Test; -+import org.w3c.dom.NodeList; -+ -+import javax.xml.xpath.XPathConstants; -+import javax.xml.xpath.XPathExpression; -+import java.io.InputStream; -+import java.util.stream.IntStream; -+ -+public class XPathProcessorTest { -+ @Test -+ public void getCities() throws Exception { -+ try (InputStream is = -+ Resources.getResource("payload.xml").openStream()) { -+ XPathProcessor processor = new XPathProcessor(is); -+ XPathExpression expression = -+ XPathProcessor.getExpression("/*[name()='Payload']/*[name()='Cities']/*[name()='City']/text()"); -+ NodeList nodes = processor.evaluate(expression, XPathConstants.NODESET); -+ IntStream.range(0, nodes.getLength()).forEach( -+ i -> System.out.println(nodes.item(i).getNodeValue()) -+ ); -+ } -+ } -+} -\ No newline at end of file diff --git a/2_10_Xslt.patch b/2_10_Xslt.patch deleted file mode 100644 index fceab9e55..000000000 --- a/2_10_Xslt.patch +++ /dev/null @@ -1,95 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (revision ) -@@ -0,0 +1,43 @@ -+package ru.javaops.masterjava.xml.util; -+ -+import javax.xml.transform.*; -+import javax.xml.transform.stream.StreamResult; -+import javax.xml.transform.stream.StreamSource; -+import java.io.*; -+import java.nio.charset.StandardCharsets; -+ -+public class XsltProcessor { -+ private static TransformerFactory FACTORY = TransformerFactory.newInstance(); -+ private final Transformer xformer; -+ -+ public XsltProcessor(InputStream xslInputStream) { -+ this(new BufferedReader(new InputStreamReader(xslInputStream, StandardCharsets.UTF_8))); -+ } -+ -+ public XsltProcessor(Reader xslReader) { -+ try { -+ Templates template = FACTORY.newTemplates(new StreamSource(xslReader)); -+ xformer = template.newTransformer(); -+ } catch (TransformerConfigurationException e) { -+ throw new IllegalStateException("XSLT transformer creation failed: " + e.toString(), e); -+ } -+ } -+ -+ public String transform(InputStream xmlInputStream) throws TransformerException { -+ StringWriter out = new StringWriter(); -+ transform(xmlInputStream, out); -+ return out.getBuffer().toString(); -+ } -+ -+ public void transform(InputStream xmlInputStream, Writer result) throws TransformerException { -+ transform(new BufferedReader(new InputStreamReader(xmlInputStream, StandardCharsets.UTF_8)), result); -+ } -+ -+ public void transform(Reader sourceReader, Writer result) throws TransformerException { -+ xformer.transform(new StreamSource(sourceReader), new StreamResult(result)); -+ } -+ -+ public static String getXsltHeader(String xslt) { -+ return "\n"; -+ } -+} -Index: src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java (revision ) -+++ src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java (revision ) -@@ -0,0 +1,18 @@ -+package ru.javaops.masterjava.xml.util; -+ -+import com.google.common.io.Resources; -+import org.junit.Test; -+ -+import java.io.InputStream; -+ -+public class XsltProcessorTest { -+ @Test -+ public void transform() throws Exception { -+ try (InputStream xslInputStream = Resources.getResource("cities.xsl").openStream(); -+ InputStream xmlInputStream = Resources.getResource("payload.xml").openStream()) { -+ -+ XsltProcessor processor = new XsltProcessor(xslInputStream); -+ System.out.println(processor.transform(xmlInputStream)); -+ } -+ } -+} -Index: src/main/resources/cities.xsl -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/resources/cities.xsl (revision ) -+++ src/main/resources/cities.xsl (revision ) -@@ -0,0 +1,9 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -\ No newline at end of file From 62747e01d3b06b16d5785699665f596b0086d4ad Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:22:14 +0200 Subject: [PATCH 17/46] 3 1 HW2 schema --- .../masterjava/xml/schema/GroupType.java | 40 ++++ .../masterjava/xml/schema/ObjectFactory.java | 24 ++ .../masterjava/xml/schema/Payload.java | 111 ++++++++- .../masterjava/xml/schema/Project.java | 216 ++++++++++++++++++ .../javaops/masterjava/xml/schema/User.java | 95 +++++--- src/main/resources/payload.xsd | 57 ++++- src/test/resources/payload.xml | 36 +-- 7 files changed, 516 insertions(+), 63 deletions(-) create mode 100644 src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java create mode 100644 src/main/java/ru/javaops/masterjava/xml/schema/Project.java diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java b/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java new file mode 100644 index 000000000..d5041640b --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java @@ -0,0 +1,40 @@ + +package ru.javaops.masterjava.xml.schema; + +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for groupType. + * + *

The following schema fragment specifies the expected content contained within this class. + *

+ *

+ * <simpleType name="groupType">
+ *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     <enumeration value="REGISTERING"/>
+ *     <enumeration value="CURRENT"/>
+ *     <enumeration value="FINISHED"/>
+ *   </restriction>
+ * </simpleType>
+ * 
+ * + */ +@XmlType(name = "groupType", namespace = "http://javaops.ru") +@XmlEnum +public enum GroupType { + + REGISTERING, + CURRENT, + FINISHED; + + public String value() { + return name(); + } + + public static GroupType fromValue(String v) { + return valueOf(v); + } + +} diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java b/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java index e8f105e2a..bfb393299 100644 --- a/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java +++ b/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java @@ -33,6 +33,14 @@ public class ObjectFactory { public ObjectFactory() { } + /** + * Create an instance of {@link Project } + * + */ + public Project createProject() { + return new Project(); + } + /** * Create an instance of {@link Payload } * @@ -41,6 +49,14 @@ public Payload createPayload() { return new Payload(); } + /** + * Create an instance of {@link Project.Group } + * + */ + public Project.Group createProjectGroup() { + return new Project.Group(); + } + /** * Create an instance of {@link User } * @@ -49,6 +65,14 @@ public User createUser() { return new User(); } + /** + * Create an instance of {@link Payload.Projects } + * + */ + public Payload.Projects createPayloadProjects() { + return new Payload.Projects(); + } + /** * Create an instance of {@link Payload.Cities } * diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java b/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java index 2a6276490..9d4cc3046 100644 --- a/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java +++ b/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java @@ -1,13 +1,9 @@ package ru.javaops.masterjava.xml.schema; +import javax.xml.bind.annotation.*; import java.util.ArrayList; import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; /** @@ -19,7 +15,18 @@ * <complexType> * <complexContent> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> - * <all> + * <sequence> + * <element name="Projects"> + * <complexType> + * <complexContent> + * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> + * <sequence maxOccurs="unbounded"> + * <element ref="{http://javaops.ru}Project"/> + * </sequence> + * </restriction> + * </complexContent> + * </complexType> + * </element> * <element name="Cities"> * <complexType> * <complexContent> @@ -42,7 +49,7 @@ * </complexContent> * </complexType> * </element> - * </all> + * </sequence> * </restriction> * </complexContent> * </complexType> @@ -52,16 +59,44 @@ */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { - + "projects", + "cities", + "users" }) @XmlRootElement(name = "Payload", namespace = "http://javaops.ru") public class Payload { + @XmlElement(name = "Projects", namespace = "http://javaops.ru", required = true) + protected Payload.Projects projects; @XmlElement(name = "Cities", namespace = "http://javaops.ru", required = true) protected Payload.Cities cities; @XmlElement(name = "Users", namespace = "http://javaops.ru", required = true) protected Payload.Users users; + /** + * Gets the value of the projects property. + * + * @return + * possible object is + * {@link Payload.Projects } + * + */ + public Payload.Projects getProjects() { + return projects; + } + + /** + * Sets the value of the projects property. + * + * @param value + * allowed object is + * {@link Payload.Projects } + * + */ + public void setProjects(Payload.Projects value) { + this.projects = value; + } + /** * Gets the value of the cities property. * @@ -171,6 +206,66 @@ public List getCity() { } + /** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+     * <complexType>
+     *   <complexContent>
+     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       <sequence maxOccurs="unbounded">
+     *         <element ref="{http://javaops.ru}Project"/>
+     *       </sequence>
+     *     </restriction>
+     *   </complexContent>
+     * </complexType>
+     * 
+ * + * + */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "", propOrder = { + "project" + }) + public static class Projects { + + @XmlElement(name = "Project", namespace = "http://javaops.ru", required = true) + protected List project; + + /** + * Gets the value of the project property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the project property. + * + *

+ * For example, to add a new item, do as follows: + *

+         *    getProject().add(newItem);
+         * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Project } + * + * + */ + public List getProject() { + if (project == null) { + project = new ArrayList(); + } + return this.project; + } + + } + + /** *

Java class for anonymous complex type. * diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/Project.java b/src/main/java/ru/javaops/masterjava/xml/schema/Project.java new file mode 100644 index 000000000..180a997e9 --- /dev/null +++ b/src/main/java/ru/javaops/masterjava/xml/schema/Project.java @@ -0,0 +1,216 @@ + +package ru.javaops.masterjava.xml.schema; + +import javax.xml.bind.annotation.*; +import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.ArrayList; +import java.util.List; + + +/** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType>
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="description" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <sequence maxOccurs="unbounded">
+ *           <element name="Group">
+ *             <complexType>
+ *               <complexContent>
+ *                 <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                   <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
+ *                   <attribute name="type" use="required" type="{http://javaops.ru}groupType" />
+ *                 </restriction>
+ *               </complexContent>
+ *             </complexType>
+ *           </element>
+ *         </sequence>
+ *       </sequence>
+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "description", + "group" +}) +@XmlRootElement(name = "Project", namespace = "http://javaops.ru") +public class Project { + + @XmlElement(namespace = "http://javaops.ru", required = true) + protected String description; + @XmlElement(name = "Group", namespace = "http://javaops.ru", required = true) + protected List group; + @XmlAttribute(name = "name", required = true) + protected String name; + + /** + * Gets the value of the description property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getDescription() { + return description; + } + + /** + * Sets the value of the description property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setDescription(String value) { + this.description = value; + } + + /** + * Gets the value of the group property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the group property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getGroup().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Project.Group } + * + * + */ + public List getGroup() { + if (group == null) { + group = new ArrayList(); + } + return this.group; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + + /** + *

Java class for anonymous complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+     * <complexType>
+     *   <complexContent>
+     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
+     *       <attribute name="type" use="required" type="{http://javaops.ru}groupType" />
+     *     </restriction>
+     *   </complexContent>
+     * </complexType>
+     * 
+ * + * + */ + @XmlAccessorType(XmlAccessType.FIELD) + @XmlType(name = "") + public static class Group { + + @XmlAttribute(name = "name", required = true) + @XmlJavaTypeAdapter(CollapsedStringAdapter.class) + @XmlID + @XmlSchemaType(name = "ID") + protected String name; + @XmlAttribute(name = "type", required = true) + protected GroupType type; + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link GroupType } + * + */ + public GroupType getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link GroupType } + * + */ + public void setType(GroupType value) { + this.type = value; + } + + } + +} diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/User.java b/src/main/java/ru/javaops/masterjava/xml/schema/User.java index b3430ce71..b2cc1c449 100644 --- a/src/main/java/ru/javaops/masterjava/xml/schema/User.java +++ b/src/main/java/ru/javaops/masterjava/xml/schema/User.java @@ -1,14 +1,9 @@ package ru.javaops.masterjava.xml.schema; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlIDREF; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.*; +import java.util.ArrayList; +import java.util.List; /** @@ -18,16 +13,14 @@ * *
  * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element name="email" type="{http://www.w3.org/2001/XMLSchema}string"/>
- *         <element name="fullName" type="{http://www.w3.org/2001/XMLSchema}string"/>
- *       </sequence>
+ *   <simpleContent>
+ *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
+ *       <attribute name="email" type="{http://javaops.ru}emailAddressType" />
  *       <attribute name="flag" use="required" type="{http://javaops.ru}flagType" />
  *       <attribute name="city" use="required" type="{http://www.w3.org/2001/XMLSchema}IDREF" />
- *     </restriction>
- *   </complexContent>
+ *       <attribute name="groupRefs" type="{http://www.w3.org/2001/XMLSchema}IDREFS" />
+ *     </extension>
+ *   </simpleContent>
  * </complexType>
  * 
* @@ -35,69 +28,72 @@ */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { - "email", - "fullName" + "value" }) @XmlRootElement(name = "User", namespace = "http://javaops.ru") public class User { - @XmlElement(namespace = "http://javaops.ru", required = true) + @XmlValue + protected String value; + @XmlAttribute(name = "email") protected String email; - @XmlElement(namespace = "http://javaops.ru", required = true) - protected String fullName; @XmlAttribute(name = "flag", required = true) protected FlagType flag; @XmlAttribute(name = "city", required = true) @XmlIDREF @XmlSchemaType(name = "IDREF") protected Object city; + @XmlAttribute(name = "groupRefs") + @XmlIDREF + @XmlSchemaType(name = "IDREFS") + protected List groupRefs; /** - * Gets the value of the email property. + * Gets the value of the value property. * * @return * possible object is * {@link String } * */ - public String getEmail() { - return email; + public String getValue() { + return value; } /** - * Sets the value of the email property. + * Sets the value of the value property. * * @param value * allowed object is * {@link String } * */ - public void setEmail(String value) { - this.email = value; + public void setValue(String value) { + this.value = value; } /** - * Gets the value of the fullName property. + * Gets the value of the email property. * * @return * possible object is * {@link String } * */ - public String getFullName() { - return fullName; + public String getEmail() { + return email; } /** - * Sets the value of the fullName property. + * Sets the value of the email property. * * @param value * allowed object is * {@link String } * */ - public void setFullName(String value) { - this.fullName = value; + public void setEmail(String value) { + this.email = value; } /** @@ -148,4 +144,37 @@ public void setCity(Object value) { this.city = value; } + /** + * Gets the value of the groupRefs property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the groupRefs property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getGroupRefs().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Object } + * + * + */ + public List getGroupRefs() { + if (groupRefs == null) { + groupRefs = new ArrayList(); + } + return this.groupRefs; + } + + @Override + public String toString() { + return value + '(' + email + ')'; + } } diff --git a/src/main/resources/payload.xsd b/src/main/resources/payload.xsd index 9ef1e46eb..3d545ec54 100644 --- a/src/main/resources/payload.xsd +++ b/src/main/resources/payload.xsd @@ -6,7 +6,14 @@ - + + + + + + + + @@ -21,18 +28,39 @@ - + - + - - + + + + + + + + + - - + + + + + + + + + + + + + + + + @@ -44,7 +72,13 @@ - + + + + + + + @@ -53,4 +87,11 @@ + + + + + + + \ No newline at end of file diff --git a/src/test/resources/payload.xml b/src/test/resources/payload.xml index 796e99cb3..fadf8c64a 100644 --- a/src/test/resources/payload.xml +++ b/src/test/resources/payload.xml @@ -1,23 +1,31 @@ - - - gmail@gmail.com - Full Name - - - admin@javaops.ru - Admin - - - mail@yandex.ru - Deleted - - + + + + Topjava + + + + + + Masterjava + + + Санкт-Петербург + Москва Киев Минск + + Full Name + Admin + Deleted + User1 + User2 + User3 + \ No newline at end of file From 80dbdbf8e26cb47c1562ed3e3d3d86427b36774d Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:22:31 +0200 Subject: [PATCH 18/46] 3 2 HW2 JAXB HTML --- src/main/java/ru/javaops/masterjava/Main.java | 14 -- .../java/ru/javaops/masterjava/MainXml.java | 140 ++++++++++++++++++ 2 files changed, 140 insertions(+), 14 deletions(-) delete mode 100644 src/main/java/ru/javaops/masterjava/Main.java create mode 100644 src/test/java/ru/javaops/masterjava/MainXml.java diff --git a/src/main/java/ru/javaops/masterjava/Main.java b/src/main/java/ru/javaops/masterjava/Main.java deleted file mode 100644 index a849258c4..000000000 --- a/src/main/java/ru/javaops/masterjava/Main.java +++ /dev/null @@ -1,14 +0,0 @@ -package ru.javaops.masterjava; - -/** - * User: gkislin - * Date: 05.08.2015 - * - * @link http://caloriesmng.herokuapp.com/ - * @link https://github.com/JavaOPs/topjava - */ -public class Main { - public static void main(String[] args) { - System.out.format("Hello MasterJava!"); - } -} diff --git a/src/test/java/ru/javaops/masterjava/MainXml.java b/src/test/java/ru/javaops/masterjava/MainXml.java new file mode 100644 index 000000000..8f57825c7 --- /dev/null +++ b/src/test/java/ru/javaops/masterjava/MainXml.java @@ -0,0 +1,140 @@ +package ru.javaops.masterjava; + +import com.google.common.base.Splitter; +import com.google.common.io.Resources; +import j2html.tags.ContainerTag; +import one.util.streamex.StreamEx; +import ru.javaops.masterjava.xml.schema.ObjectFactory; +import ru.javaops.masterjava.xml.schema.Payload; +import ru.javaops.masterjava.xml.schema.Project; +import ru.javaops.masterjava.xml.schema.User; +import ru.javaops.masterjava.xml.util.JaxbParser; +import ru.javaops.masterjava.xml.util.Schemas; +import ru.javaops.masterjava.xml.util.StaxStreamProcessor; +import ru.javaops.masterjava.xml.util.XsltProcessor; + +import javax.xml.stream.events.XMLEvent; +import java.io.InputStream; +import java.io.Writer; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; + +import static com.google.common.base.Strings.nullToEmpty; +import static j2html.TagCreator.*; + +public class MainXml { + + private static final Comparator USER_COMPARATOR = Comparator.comparing(User::getValue).thenComparing(User::getEmail); + + public static void main(String[] args) throws Exception { + if (args.length != 1) { + System.out.println("Required argument: projectName"); + System.exit(1); + } + String projectName = args[0]; + URL payloadUrl = Resources.getResource("payload.xml"); + + Set users = parseByJaxb(projectName, payloadUrl); + users.forEach(System.out::println); + + System.out.println(); + String html = toHtml(users, projectName); + System.out.println(html); + try (Writer writer = Files.newBufferedWriter(Paths.get("out/users.html"))) { + writer.write(html); + } + + System.out.println(); + users = processByStax(projectName, payloadUrl); + users.forEach(System.out::println); + + System.out.println(); + html = transform(projectName, payloadUrl); + try (Writer writer = Files.newBufferedWriter(Paths.get("out/groups.html"))) { + writer.write(html); + } + } + + private static Set parseByJaxb(String projectName, URL payloadUrl) throws Exception { + JaxbParser parser = new JaxbParser(ObjectFactory.class); + parser.setSchema(Schemas.ofClasspath("payload.xsd")); + Payload payload; + try (InputStream is = payloadUrl.openStream()) { + payload = parser.unmarshal(is); + } + + Project project = StreamEx.of(payload.getProjects().getProject()) + .filter(p -> p.getName().equals(projectName)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException("Invalid project name '" + projectName + '\'')); + + final Set groups = new HashSet<>(project.getGroup()); // identity compare + return StreamEx.of(payload.getUsers().getUser()) + .filter(u -> !Collections.disjoint(groups, u.getGroupRefs())) + .collect( + Collectors.toCollection(() -> new TreeSet<>(USER_COMPARATOR)) + ); + } + + private static Set processByStax(String projectName, URL payloadUrl) throws Exception { + + try (InputStream is = payloadUrl.openStream()) { + StaxStreamProcessor processor = new StaxStreamProcessor(is); + final Set groupNames = new HashSet<>(); + + // Projects loop + projects: + while (processor.startElement("Project", "Projects")) { + if (projectName.equals(processor.getAttribute("name"))) { + while (processor.startElement("Group", "Project")) { + groupNames.add(processor.getAttribute("name")); + } + break; + } + } + if (groupNames.isEmpty()) { + throw new IllegalArgumentException("Invalid " + projectName + " or no groups"); + } + + // Users loop + Set users = new TreeSet<>(USER_COMPARATOR); + + JaxbParser parser = new JaxbParser(User.class); + while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { + String groupRefs = processor.getAttribute("groupRefs"); + if (!Collections.disjoint(groupNames, Splitter.on(' ').splitToList(nullToEmpty(groupRefs)))) { + User user = parser.unmarshal(processor.getReader(), User.class); + users.add(user); + } + } + return users; + } + } + + private static String toHtml(Set users, String projectName) { + final ContainerTag table = table().with( + tr().with(th("FullName"), th("email"))) + .attr("border", "1") + .attr("cellpadding", "8") + .attr("cellspacing", "0"); + + users.forEach(u -> table.with(tr().with(td(u.getValue()), td(u.getEmail())))); + + return html().with( + head().with(title(projectName + " users")), + body().with(h1(projectName + " users"), table) + ).render(); + } + + private static String transform(String projectName, URL payloadUrl) throws Exception { + URL xsl = Resources.getResource("groups.xsl"); + try (InputStream xmlStream = payloadUrl.openStream(); InputStream xslStream = xsl.openStream()) { + XsltProcessor processor = new XsltProcessor(xslStream); + processor.setParameter("projectName", projectName); + return processor.transform(xmlStream); + } + } +} From a6124d63cb8ce666cc56624be77f2119d371351f Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:22:51 +0200 Subject: [PATCH 19/46] 3 4 StAX refactoring --- .../masterjava/xml/util/JaxbParser.java | 5 +++ .../masterjava/xml/util/JaxbUnmarshaller.java | 7 ++++- .../xml/util/StaxStreamProcessor.java | 31 ++++++++++++++++--- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java b/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java index b3a45f66c..563d53ba0 100644 --- a/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java +++ b/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java @@ -5,6 +5,7 @@ import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.PropertyException; +import javax.xml.stream.XMLStreamReader; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import java.io.*; @@ -55,6 +56,10 @@ public T unmarshal(String str) throws JAXBException { return (T) jaxbUnmarshaller.unmarshal(str); } + public T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { + return jaxbUnmarshaller.unmarshal(reader, elementClass); + } + // Marshaller public void setMarshallerProperty(String prop, Object value) { try { diff --git a/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java b/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java index 7a3e13461..1de89d823 100644 --- a/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java +++ b/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java @@ -3,6 +3,7 @@ import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; +import javax.xml.stream.XMLStreamReader; import javax.xml.validation.Schema; import java.io.InputStream; import java.io.Reader; @@ -30,4 +31,8 @@ public synchronized Object unmarshal(Reader reader) throws JAXBException { public Object unmarshal(String str) throws JAXBException { return unmarshal(new StringReader(str)); } -} + + public synchronized T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { + return unmarshaller.unmarshal(reader, elementClass).getValue(); + } +} \ No newline at end of file diff --git a/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java b/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java index 921ca6aff..5878118c0 100644 --- a/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java +++ b/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java @@ -15,17 +15,40 @@ public StaxStreamProcessor(InputStream is) throws XMLStreamException { reader = FACTORY.createXMLStreamReader(is); } + public boolean startElement(String element, String parent) throws XMLStreamException { + while (reader.hasNext()) { + int event = reader.next(); + if (parent != null && isElementEnd(event, parent)) { + return false; + } + if (isElementStart(event, element)) { + return true; + } + } + return false; + } + + private boolean isElementStart(int event, String el) { + return event == XMLEvent.START_ELEMENT && el.equals(reader.getLocalName()); + } + + private boolean isElementEnd(int event, String el) { + return event == XMLEvent.END_ELEMENT && el.equals(reader.getLocalName()); + } + public XMLStreamReader getReader() { return reader; } + public String getAttribute(String name) throws XMLStreamException { + return reader.getAttributeValue(null, name); + } + public boolean doUntil(int stopEvent, String value) throws XMLStreamException { while (reader.hasNext()) { int event = reader.next(); - if (event == stopEvent) { - if (value.equals(getValue(event))) { - return true; - } + if (event == stopEvent && value.equals(getValue(event))) { + return true; } } return false; From 75a4d120b3325b6d5a2cb64b2854d74fa17de769 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:23:03 +0200 Subject: [PATCH 20/46] 3 5 HW2 xslt --- .../masterjava/xml/util/XsltProcessor.java | 4 ++ src/main/resources/groups.xsl | 37 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/main/resources/groups.xsl diff --git a/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java b/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java index 019eeed3d..083febb00 100644 --- a/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java +++ b/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java @@ -40,4 +40,8 @@ public void transform(Reader sourceReader, Writer result) throws TransformerExce public static String getXsltHeader(String xslt) { return "\n"; } + + public void setParameter(String name, String value) { + xformer.setParameter(name, value); + } } diff --git a/src/main/resources/groups.xsl b/src/main/resources/groups.xsl new file mode 100644 index 000000000..c5ade36b8 --- /dev/null +++ b/src/main/resources/groups.xsl @@ -0,0 +1,37 @@ + + + + + + + + + + <xsl:value-of select="$projectName"/> groups + + + +

+ groups +

+ + + + + + + + + + + +
GroupType
+ + + +
+ + +
+
\ No newline at end of file From af66ca4cfc47b9d962b4931eaf5a77b0c555e747 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:23:14 +0200 Subject: [PATCH 21/46] 3 6 multimodule --- common/pom.xml | 21 ++++++++++ parent/pom.xml | 69 +++++++++++++++++++++++++++++++ pom.xml | 107 +++++-------------------------------------------- upload/pom.xml | 39 ++++++++++++++++++ 4 files changed, 140 insertions(+), 96 deletions(-) create mode 100644 common/pom.xml create mode 100644 parent/pom.xml create mode 100644 upload/pom.xml diff --git a/common/pom.xml b/common/pom.xml new file mode 100644 index 000000000..33d3da8ed --- /dev/null +++ b/common/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + + + ru.javaops + parent + ../parent/pom.xml + 1.0-SNAPSHOT + + + common + 1.0-SNAPSHOT + jar + Common + + + + \ No newline at end of file diff --git a/parent/pom.xml b/parent/pom.xml new file mode 100644 index 000000000..d7b056d1d --- /dev/null +++ b/parent/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + ru.javaops + parent + pom + 1.0-SNAPSHOT + Parent + + + 1.8 + UTF-8 + UTF-8 + + + + install + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.20.1 + + -Dfile.encoding=UTF-8 + + + + + + + + com.google.guava + guava + 23.3-jre + + + one.util + streamex + RELEASE + + + + + junit + junit + 4.12 + test + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 884be4839..0085819cf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,106 +4,21 @@ ru.javaops masterjava - jar + pom 1.0-SNAPSHOT Master Java https://github.com/JavaOPs/masterjava - - 1.8 - UTF-8 - UTF-8 - - - - masterjava - install - - - org.apache.maven.plugins - maven-compiler-plugin - 3.7.0 - - ${java.version} - ${java.version} - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.20.1 - - -Dfile.encoding=UTF-8 - - - - org.apache.maven.plugins - maven-shade-plugin - 3.1.0 - - - package - - shade - - - benchmarks - - - org.openjdk.jmh.Main - - - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - - - - - - - org.openjdk.jmh - jmh-core - RELEASE - - - org.openjdk.jmh - jmh-generator-annprocess - RELEASE - provided - - - com.google.guava - guava - 21.0 - - - junit - junit - 4.12 - test - - - - - - - - + + upload + common + + diff --git a/upload/pom.xml b/upload/pom.xml new file mode 100644 index 000000000..7cac01c05 --- /dev/null +++ b/upload/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + + ru.javaops + parent + ../parent/pom.xml + 1.0-SNAPSHOT + + + upload + 1.0-SNAPSHOT + war + Upload + + + + + org.apache.maven.plugins + maven-war-plugin + 3.2.0 + + false + + + + + + + + ru.javaops + common + ${project.version} + + + \ No newline at end of file From bb784fb543dfd2e10dd8881034b064b09564d5b4 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:26:24 +0200 Subject: [PATCH 22/46] 2 09 XPath --- 3_1_HW2_schema.patch | 815 ------------------------------------ 3_2_HW2_JAXB_HTML.patch | 132 ------ 3_3_HW2_StAX.patch | 147 ------- 3_4_StAX_refactoring.patch | 158 ------- 3_5_HW2_xslt.patch | 104 ----- 3_6_multimodule.patch | 294 ------------- 4_1_HW3_pom_structure.patch | 535 ----------------------- 7 files changed, 2185 deletions(-) delete mode 100644 3_1_HW2_schema.patch delete mode 100644 3_2_HW2_JAXB_HTML.patch delete mode 100644 3_3_HW2_StAX.patch delete mode 100644 3_4_StAX_refactoring.patch delete mode 100644 3_5_HW2_xslt.patch delete mode 100644 3_6_multimodule.patch delete mode 100644 4_1_HW3_pom_structure.patch diff --git a/3_1_HW2_schema.patch b/3_1_HW2_schema.patch deleted file mode 100644 index a105e2de6..000000000 --- a/3_1_HW2_schema.patch +++ /dev/null @@ -1,815 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (revision 1819bf210a3125dd3597a87c3bbcfd584ad7a254) -+++ src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (revision ) -@@ -33,6 +33,14 @@ - public ObjectFactory() { - } - -+ /** -+ * Create an instance of {@link Project } -+ * -+ */ -+ public Project createProject() { -+ return new Project(); -+ } -+ - /** - * Create an instance of {@link Payload } - * -@@ -41,6 +49,14 @@ - return new Payload(); - } - -+ /** -+ * Create an instance of {@link Project.Group } -+ * -+ */ -+ public Project.Group createProjectGroup() { -+ return new Project.Group(); -+ } -+ - /** - * Create an instance of {@link User } - * -@@ -49,6 +65,14 @@ - return new User(); - } - -+ /** -+ * Create an instance of {@link Payload.Projects } -+ * -+ */ -+ public Payload.Projects createPayloadProjects() { -+ return new Payload.Projects(); -+ } -+ - /** - * Create an instance of {@link Payload.Cities } - * -Index: src/test/resources/payload.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/test/resources/payload.xml (revision 1819bf210a3125dd3597a87c3bbcfd584ad7a254) -+++ src/test/resources/payload.xml (revision ) -@@ -1,23 +1,31 @@ - -- -- -- gmail@gmail.com -- Full Name -- -- -- admin@javaops.ru -- Admin -- -- -- mail@yandex.ru -- Deleted -- -- -+ -+ -+ -+ Topjava -+ -+ -+ -+ -+ -+ Masterjava -+ -+ -+ - - Санкт-Петербург -+ Москва - Киев - Минск - -+ -+ Full Name -+ Admin -+ Deleted -+ User1 -+ User2 -+ User3 -+ - -\ No newline at end of file -Index: src/main/java/ru/javaops/masterjava/xml/schema/Payload.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (revision 1819bf210a3125dd3597a87c3bbcfd584ad7a254) -+++ src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (revision ) -@@ -1,13 +1,9 @@ - - package ru.javaops.masterjava.xml.schema; - -+import javax.xml.bind.annotation.*; - import java.util.ArrayList; - import java.util.List; --import javax.xml.bind.annotation.XmlAccessType; --import javax.xml.bind.annotation.XmlAccessorType; --import javax.xml.bind.annotation.XmlElement; --import javax.xml.bind.annotation.XmlRootElement; --import javax.xml.bind.annotation.XmlType; - - - /** -@@ -19,7 +15,18 @@ - * <complexType> - * <complexContent> - * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> -- * <all> -+ * <sequence> -+ * <element name="Projects"> -+ * <complexType> -+ * <complexContent> -+ * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> -+ * <sequence maxOccurs="unbounded"> -+ * <element ref="{http://javaops.ru}Project"/> -+ * </sequence> -+ * </restriction> -+ * </complexContent> -+ * </complexType> -+ * </element> - * <element name="Cities"> - * <complexType> - * <complexContent> -@@ -42,7 +49,7 @@ - * </complexContent> - * </complexType> - * </element> -- * </all> -+ * </sequence> - * </restriction> - * </complexContent> - * </complexType> -@@ -52,16 +59,44 @@ - */ - @XmlAccessorType(XmlAccessType.FIELD) - @XmlType(name = "", propOrder = { -- -+ "projects", -+ "cities", -+ "users" - }) - @XmlRootElement(name = "Payload", namespace = "http://javaops.ru") - public class Payload { - -+ @XmlElement(name = "Projects", namespace = "http://javaops.ru", required = true) -+ protected Payload.Projects projects; - @XmlElement(name = "Cities", namespace = "http://javaops.ru", required = true) - protected Payload.Cities cities; - @XmlElement(name = "Users", namespace = "http://javaops.ru", required = true) - protected Payload.Users users; - -+ /** -+ * Gets the value of the projects property. -+ * -+ * @return -+ * possible object is -+ * {@link Payload.Projects } -+ * -+ */ -+ public Payload.Projects getProjects() { -+ return projects; -+ } -+ -+ /** -+ * Sets the value of the projects property. -+ * -+ * @param value -+ * allowed object is -+ * {@link Payload.Projects } -+ * -+ */ -+ public void setProjects(Payload.Projects value) { -+ this.projects = value; -+ } -+ - /** - * Gets the value of the cities property. - * -@@ -171,6 +206,66 @@ - } - - -+ /** -+ *

Java class for anonymous complex type. -+ * -+ *

The following schema fragment specifies the expected content contained within this class. -+ * -+ *

-+     * <complexType>
-+     *   <complexContent>
-+     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-+     *       <sequence maxOccurs="unbounded">
-+     *         <element ref="{http://javaops.ru}Project"/>
-+     *       </sequence>
-+     *     </restriction>
-+     *   </complexContent>
-+     * </complexType>
-+     * 
-+ * -+ * -+ */ -+ @XmlAccessorType(XmlAccessType.FIELD) -+ @XmlType(name = "", propOrder = { -+ "project" -+ }) -+ public static class Projects { -+ -+ @XmlElement(name = "Project", namespace = "http://javaops.ru", required = true) -+ protected List project; -+ -+ /** -+ * Gets the value of the project property. -+ * -+ *

-+ * This accessor method returns a reference to the live list, -+ * not a snapshot. Therefore any modification you make to the -+ * returned list will be present inside the JAXB object. -+ * This is why there is not a set method for the project property. -+ * -+ *

-+ * For example, to add a new item, do as follows: -+ *

-+         *    getProject().add(newItem);
-+         * 
-+ * -+ * -+ *

-+ * Objects of the following type(s) are allowed in the list -+ * {@link Project } -+ * -+ * -+ */ -+ public List getProject() { -+ if (project == null) { -+ project = new ArrayList(); -+ } -+ return this.project; -+ } -+ -+ } -+ -+ - /** - *

Java class for anonymous complex type. - * -Index: src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java (revision ) -@@ -0,0 +1,40 @@ -+ -+package ru.javaops.masterjava.xml.schema; -+ -+import javax.xml.bind.annotation.XmlEnum; -+import javax.xml.bind.annotation.XmlType; -+ -+ -+/** -+ *

Java class for groupType. -+ * -+ *

The following schema fragment specifies the expected content contained within this class. -+ *

-+ *

-+ * <simpleType name="groupType">
-+ *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
-+ *     <enumeration value="REGISTERING"/>
-+ *     <enumeration value="CURRENT"/>
-+ *     <enumeration value="FINISHED"/>
-+ *   </restriction>
-+ * </simpleType>
-+ * 
-+ * -+ */ -+@XmlType(name = "groupType", namespace = "http://javaops.ru") -+@XmlEnum -+public enum GroupType { -+ -+ REGISTERING, -+ CURRENT, -+ FINISHED; -+ -+ public String value() { -+ return name(); -+ } -+ -+ public static GroupType fromValue(String v) { -+ return valueOf(v); -+ } -+ -+} -Index: src/main/java/ru/javaops/masterjava/xml/schema/Project.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/Project.java (revision ) -+++ src/main/java/ru/javaops/masterjava/xml/schema/Project.java (revision ) -@@ -0,0 +1,216 @@ -+ -+package ru.javaops.masterjava.xml.schema; -+ -+import javax.xml.bind.annotation.*; -+import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -+import java.util.ArrayList; -+import java.util.List; -+ -+ -+/** -+ *

Java class for anonymous complex type. -+ * -+ *

The following schema fragment specifies the expected content contained within this class. -+ * -+ *

-+ * <complexType>
-+ *   <complexContent>
-+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-+ *       <sequence>
-+ *         <element name="description" type="{http://www.w3.org/2001/XMLSchema}string"/>
-+ *         <sequence maxOccurs="unbounded">
-+ *           <element name="Group">
-+ *             <complexType>
-+ *               <complexContent>
-+ *                 <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-+ *                   <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
-+ *                   <attribute name="type" use="required" type="{http://javaops.ru}groupType" />
-+ *                 </restriction>
-+ *               </complexContent>
-+ *             </complexType>
-+ *           </element>
-+ *         </sequence>
-+ *       </sequence>
-+ *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
-+ *     </restriction>
-+ *   </complexContent>
-+ * </complexType>
-+ * 
-+ * -+ * -+ */ -+@XmlAccessorType(XmlAccessType.FIELD) -+@XmlType(name = "", propOrder = { -+ "description", -+ "group" -+}) -+@XmlRootElement(name = "Project", namespace = "http://javaops.ru") -+public class Project { -+ -+ @XmlElement(namespace = "http://javaops.ru", required = true) -+ protected String description; -+ @XmlElement(name = "Group", namespace = "http://javaops.ru", required = true) -+ protected List group; -+ @XmlAttribute(name = "name", required = true) -+ protected String name; -+ -+ /** -+ * Gets the value of the description property. -+ * -+ * @return -+ * possible object is -+ * {@link String } -+ * -+ */ -+ public String getDescription() { -+ return description; -+ } -+ -+ /** -+ * Sets the value of the description property. -+ * -+ * @param value -+ * allowed object is -+ * {@link String } -+ * -+ */ -+ public void setDescription(String value) { -+ this.description = value; -+ } -+ -+ /** -+ * Gets the value of the group property. -+ * -+ *

-+ * This accessor method returns a reference to the live list, -+ * not a snapshot. Therefore any modification you make to the -+ * returned list will be present inside the JAXB object. -+ * This is why there is not a set method for the group property. -+ * -+ *

-+ * For example, to add a new item, do as follows: -+ *

-+     *    getGroup().add(newItem);
-+     * 
-+ * -+ * -+ *

-+ * Objects of the following type(s) are allowed in the list -+ * {@link Project.Group } -+ * -+ * -+ */ -+ public List getGroup() { -+ if (group == null) { -+ group = new ArrayList(); -+ } -+ return this.group; -+ } -+ -+ /** -+ * Gets the value of the name property. -+ * -+ * @return -+ * possible object is -+ * {@link String } -+ * -+ */ -+ public String getName() { -+ return name; -+ } -+ -+ /** -+ * Sets the value of the name property. -+ * -+ * @param value -+ * allowed object is -+ * {@link String } -+ * -+ */ -+ public void setName(String value) { -+ this.name = value; -+ } -+ -+ -+ /** -+ *

Java class for anonymous complex type. -+ * -+ *

The following schema fragment specifies the expected content contained within this class. -+ * -+ *

-+     * <complexType>
-+     *   <complexContent>
-+     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-+     *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}ID" />
-+     *       <attribute name="type" use="required" type="{http://javaops.ru}groupType" />
-+     *     </restriction>
-+     *   </complexContent>
-+     * </complexType>
-+     * 
-+ * -+ * -+ */ -+ @XmlAccessorType(XmlAccessType.FIELD) -+ @XmlType(name = "") -+ public static class Group { -+ -+ @XmlAttribute(name = "name", required = true) -+ @XmlJavaTypeAdapter(CollapsedStringAdapter.class) -+ @XmlID -+ @XmlSchemaType(name = "ID") -+ protected String name; -+ @XmlAttribute(name = "type", required = true) -+ protected GroupType type; -+ -+ /** -+ * Gets the value of the name property. -+ * -+ * @return -+ * possible object is -+ * {@link String } -+ * -+ */ -+ public String getName() { -+ return name; -+ } -+ -+ /** -+ * Sets the value of the name property. -+ * -+ * @param value -+ * allowed object is -+ * {@link String } -+ * -+ */ -+ public void setName(String value) { -+ this.name = value; -+ } -+ -+ /** -+ * Gets the value of the type property. -+ * -+ * @return -+ * possible object is -+ * {@link GroupType } -+ * -+ */ -+ public GroupType getType() { -+ return type; -+ } -+ -+ /** -+ * Sets the value of the type property. -+ * -+ * @param value -+ * allowed object is -+ * {@link GroupType } -+ * -+ */ -+ public void setType(GroupType value) { -+ this.type = value; -+ } -+ -+ } -+ -+} -Index: src/main/resources/payload.xsd -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/resources/payload.xsd (revision 1819bf210a3125dd3597a87c3bbcfd584ad7a254) -+++ src/main/resources/payload.xsd (revision ) -@@ -6,7 +6,14 @@ - - - -- -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -21,18 +28,39 @@ - - - -- -+ - - - -- -+ - - -- -- -+ -+ -+ -+ -+ -+ -+ -+ -+ - -- -- -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - -@@ -44,7 +72,13 @@ - - - -- -+ -+ -+ -+ -+ -+ -+ - - - -@@ -53,4 +87,11 @@ - - - -+ -+ -+ -+ -+ -+ -+ - -\ No newline at end of file -Index: src/main/java/ru/javaops/masterjava/xml/schema/User.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/User.java (revision 1819bf210a3125dd3597a87c3bbcfd584ad7a254) -+++ src/main/java/ru/javaops/masterjava/xml/schema/User.java (revision ) -@@ -1,14 +1,9 @@ - - package ru.javaops.masterjava.xml.schema; - --import javax.xml.bind.annotation.XmlAccessType; --import javax.xml.bind.annotation.XmlAccessorType; --import javax.xml.bind.annotation.XmlAttribute; --import javax.xml.bind.annotation.XmlElement; --import javax.xml.bind.annotation.XmlIDREF; --import javax.xml.bind.annotation.XmlRootElement; --import javax.xml.bind.annotation.XmlSchemaType; --import javax.xml.bind.annotation.XmlType; -+import javax.xml.bind.annotation.*; -+import java.util.ArrayList; -+import java.util.List; - - - /** -@@ -18,16 +13,14 @@ - * - *
-  * <complexType>
-- *   <complexContent>
-- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
-- *       <sequence>
-- *         <element name="email" type="{http://www.w3.org/2001/XMLSchema}string"/>
-- *         <element name="fullName" type="{http://www.w3.org/2001/XMLSchema}string"/>
-- *       </sequence>
-+ *   <simpleContent>
-+ *     <extension base="<http://www.w3.org/2001/XMLSchema>string">
-+ *       <attribute name="email" type="{http://javaops.ru}emailAddressType" />
-  *       <attribute name="flag" use="required" type="{http://javaops.ru}flagType" />
-  *       <attribute name="city" use="required" type="{http://www.w3.org/2001/XMLSchema}IDREF" />
-- *     </restriction>
-- *   </complexContent>
-+ *       <attribute name="groupRefs" type="{http://www.w3.org/2001/XMLSchema}IDREFS" />
-+ *     </extension>
-+ *   </simpleContent>
-  * </complexType>
-  * 
- * -@@ -35,69 +28,72 @@ - */ - @XmlAccessorType(XmlAccessType.FIELD) - @XmlType(name = "", propOrder = { -- "email", -- "fullName" -+ "value" - }) - @XmlRootElement(name = "User", namespace = "http://javaops.ru") - public class User { - -- @XmlElement(namespace = "http://javaops.ru", required = true) -+ @XmlValue -+ protected String value; -+ @XmlAttribute(name = "email") - protected String email; -- @XmlElement(namespace = "http://javaops.ru", required = true) -- protected String fullName; - @XmlAttribute(name = "flag", required = true) - protected FlagType flag; - @XmlAttribute(name = "city", required = true) - @XmlIDREF - @XmlSchemaType(name = "IDREF") - protected Object city; -+ @XmlAttribute(name = "groupRefs") -+ @XmlIDREF -+ @XmlSchemaType(name = "IDREFS") -+ protected List groupRefs; - - /** -- * Gets the value of the email property. -+ * Gets the value of the value property. - * - * @return - * possible object is - * {@link String } - * - */ -- public String getEmail() { -- return email; -+ public String getValue() { -+ return value; - } - - /** -- * Sets the value of the email property. -+ * Sets the value of the value property. - * - * @param value - * allowed object is - * {@link String } - * - */ -- public void setEmail(String value) { -- this.email = value; -+ public void setValue(String value) { -+ this.value = value; - } - - /** -- * Gets the value of the fullName property. -+ * Gets the value of the email property. - * - * @return - * possible object is - * {@link String } - * - */ -- public String getFullName() { -- return fullName; -+ public String getEmail() { -+ return email; - } - - /** -- * Sets the value of the fullName property. -+ * Sets the value of the email property. - * - * @param value - * allowed object is - * {@link String } - * - */ -- public void setFullName(String value) { -- this.fullName = value; -+ public void setEmail(String value) { -+ this.email = value; - } - - /** -@@ -148,4 +144,37 @@ - this.city = value; - } - -+ /** -+ * Gets the value of the groupRefs property. -+ * -+ *

-+ * This accessor method returns a reference to the live list, -+ * not a snapshot. Therefore any modification you make to the -+ * returned list will be present inside the JAXB object. -+ * This is why there is not a set method for the groupRefs property. -+ * -+ *

-+ * For example, to add a new item, do as follows: -+ *

-+     *    getGroupRefs().add(newItem);
-+     * 
-+ * -+ * -+ *

-+ * Objects of the following type(s) are allowed in the list -+ * {@link Object } -+ * -+ * -+ */ -+ public List getGroupRefs() { -+ if (groupRefs == null) { -+ groupRefs = new ArrayList(); -+ } -+ return this.groupRefs; -+ } -+ -+ @Override -+ public String toString() { -+ return value + '(' + email + ')'; -+ } - } diff --git a/3_2_HW2_JAXB_HTML.patch b/3_2_HW2_JAXB_HTML.patch deleted file mode 100644 index dc83677a1..000000000 --- a/3_2_HW2_JAXB_HTML.patch +++ /dev/null @@ -1,132 +0,0 @@ -Index: src/test/java/ru/javaops/masterjava/MainXml.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/test/java/ru/javaops/masterjava/MainXml.java (revision ) -+++ src/test/java/ru/javaops/masterjava/MainXml.java (revision ) -@@ -0,0 +1,78 @@ -+package ru.javaops.masterjava; -+ -+import com.google.common.io.Resources; -+import j2html.tags.ContainerTag; -+import one.util.streamex.StreamEx; -+import ru.javaops.masterjava.xml.schema.ObjectFactory; -+import ru.javaops.masterjava.xml.schema.Payload; -+import ru.javaops.masterjava.xml.schema.Project; -+import ru.javaops.masterjava.xml.schema.User; -+import ru.javaops.masterjava.xml.util.JaxbParser; -+import ru.javaops.masterjava.xml.util.Schemas; -+ -+import java.io.InputStream; -+import java.io.Writer; -+import java.net.URL; -+import java.nio.file.Files; -+import java.nio.file.Paths; -+import java.util.*; -+import java.util.stream.Collectors; -+ -+import static j2html.TagCreator.*; -+ -+public class MainXml { -+ -+ public static void main(String[] args) throws Exception { -+ if (args.length != 1) { -+ System.out.println("Format: projectName"); -+ System.exit(1); -+ } -+ String projectName = args[0]; -+ URL payloadUrl = Resources.getResource("payload.xml"); -+ -+ Set users = parseByJaxb(projectName, payloadUrl); -+ users.forEach(System.out::println); -+ -+ String html = toHtml(users, projectName); -+ System.out.println(html); -+ try (Writer writer = Files.newBufferedWriter(Paths.get("out/users.html"))) { -+ writer.write(html); -+ } -+ } -+ -+ private static Set parseByJaxb(String projectName, URL payloadUrl) throws Exception { -+ JaxbParser parser = new JaxbParser(ObjectFactory.class); -+ parser.setSchema(Schemas.ofClasspath("payload.xsd")); -+ Payload payload; -+ try (InputStream is = payloadUrl.openStream()) { -+ payload = parser.unmarshal(is); -+ } -+ -+ Project project = StreamEx.of(payload.getProjects().getProject()) -+ .filter(p -> p.getName().equals(projectName)) -+ .findAny() -+ .orElseThrow(() -> new IllegalArgumentException("Invalid project name '" + projectName + '\'')); -+ -+ final Set groups = new HashSet<>(project.getGroup()); // identity compare -+ return StreamEx.of(payload.getUsers().getUser()) -+ .filter(u -> !Collections.disjoint(groups, u.getGroupRefs())) -+ .collect( -+ Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getValue).thenComparing(User::getEmail))) -+ ); -+ } -+ -+ private static String toHtml(Set users, String projectName) { -+ final ContainerTag table = table().with( -+ tr().with(th("FullName"), th("email"))) -+ .attr("border", "1") -+ .attr("cellpadding", "8") -+ .attr("cellspacing", "0"); -+ -+ users.forEach(u -> table.with(tr().with(td(u.getValue()), td(u.getEmail())))); -+ -+ return html().with( -+ head().with(title(projectName + " users")), -+ body().with(h1(projectName + " users"), table) -+ ).render(); -+ } -+} -Index: src/main/java/ru/javaops/masterjava/Main.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/Main.java (date 1509203382000) -+++ src/main/java/ru/javaops/masterjava/Main.java (date 1509203382000) -@@ -1,14 +0,0 @@ --package ru.javaops.masterjava; -- --/** -- * User: gkislin -- * Date: 05.08.2015 -- * -- * @link http://caloriesmng.herokuapp.com/ -- * @link https://github.com/JavaOPs/topjava -- */ --public class Main { -- public static void main(String[] args) { -- System.out.format("Hello MasterJava!"); -- } --} -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (date 1509203382000) -+++ pom.xml (revision ) -@@ -94,6 +94,19 @@ - 21.0 - - -+ one.util -+ streamex -+ RELEASE -+ -+ -+ -+ com.j2html -+ j2html -+ RELEASE -+ -+ -+ -+ - junit - junit - 4.12 diff --git a/3_3_HW2_StAX.patch b/3_3_HW2_StAX.patch deleted file mode 100644 index 5562a232e..000000000 --- a/3_3_HW2_StAX.patch +++ /dev/null @@ -1,147 +0,0 @@ -Index: src/test/java/ru/javaops/masterjava/MainXml.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/test/java/ru/javaops/masterjava/MainXml.java (date 1509203657000) -+++ src/test/java/ru/javaops/masterjava/MainXml.java (revision ) -@@ -1,5 +1,6 @@ - package ru.javaops.masterjava; - -+import com.google.common.base.Splitter; - import com.google.common.io.Resources; - import j2html.tags.ContainerTag; - import one.util.streamex.StreamEx; -@@ -9,7 +10,9 @@ - import ru.javaops.masterjava.xml.schema.User; - import ru.javaops.masterjava.xml.util.JaxbParser; - import ru.javaops.masterjava.xml.util.Schemas; -+import ru.javaops.masterjava.xml.util.StaxStreamProcessor; - -+import javax.xml.stream.events.XMLEvent; - import java.io.InputStream; - import java.io.Writer; - import java.net.URL; -@@ -18,13 +21,16 @@ - import java.util.*; - import java.util.stream.Collectors; - -+import static com.google.common.base.Strings.nullToEmpty; - import static j2html.TagCreator.*; - - public class MainXml { - -+ private static final Comparator USER_COMPARATOR = Comparator.comparing(User::getValue).thenComparing(User::getEmail); -+ - public static void main(String[] args) throws Exception { - if (args.length != 1) { -- System.out.println("Format: projectName"); -+ System.out.println("Required argument: projectName"); - System.exit(1); - } - String projectName = args[0]; -@@ -33,11 +39,16 @@ - Set users = parseByJaxb(projectName, payloadUrl); - users.forEach(System.out::println); - -+ System.out.println(); - String html = toHtml(users, projectName); - System.out.println(html); - try (Writer writer = Files.newBufferedWriter(Paths.get("out/users.html"))) { - writer.write(html); - } -+ -+ System.out.println(); -+ users = processByStax(projectName, payloadUrl); -+ users.forEach(System.out::println); - } - - private static Set parseByJaxb(String projectName, URL payloadUrl) throws Exception { -@@ -57,9 +68,49 @@ - return StreamEx.of(payload.getUsers().getUser()) - .filter(u -> !Collections.disjoint(groups, u.getGroupRefs())) - .collect( -- Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getValue).thenComparing(User::getEmail))) -+ Collectors.toCollection(() -> new TreeSet<>(USER_COMPARATOR)) - ); - } -+ -+ private static Set processByStax(String projectName, URL payloadUrl) throws Exception { -+ -+ try (InputStream is = payloadUrl.openStream()) { -+ StaxStreamProcessor processor = new StaxStreamProcessor(is); -+ final Set groupNames = new HashSet<>(); -+ -+ // Projects loop -+ projects: -+ while (processor.doUntil(XMLEvent.START_ELEMENT, "Project")) { -+ if (projectName.equals(processor.getAttribute("name"))) { -+ // Groups loop -+ String element; -+ while ((element = processor.doUntilAny(XMLEvent.START_ELEMENT, "Project", "Group", "Users")) != null) { -+ if (!element.equals("Group")) { -+ break projects; -+ } -+ groupNames.add(processor.getAttribute("name")); -+ } -+ } -+ } -+ if (groupNames.isEmpty()) { -+ throw new IllegalArgumentException("Invalid " + projectName + " or no groups"); -+ } -+ -+ // Users loop -+ Set users = new TreeSet<>(USER_COMPARATOR); -+ -+ while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { -+ String groupRefs = processor.getAttribute("groupRefs"); -+ if (!Collections.disjoint(groupNames, Splitter.on(' ').splitToList(nullToEmpty(groupRefs)))) { -+ User user = new User(); -+ user.setEmail(processor.getAttribute("email")); -+ user.setValue(processor.getText()); -+ users.add(user); -+ } -+ } -+ return users; -+ } -+ } - - private static String toHtml(Set users, String projectName) { - final ContainerTag table = table().with( -Index: src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (date 1509203657000) -+++ src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision ) -@@ -20,15 +20,26 @@ - } - - public boolean doUntil(int stopEvent, String value) throws XMLStreamException { -+ return doUntilAny(stopEvent, value) != null; -+ } -+ -+ public String getAttribute(String name) throws XMLStreamException { -+ return reader.getAttributeValue(null, name); -+ } -+ -+ public String doUntilAny(int stopEvent, String... values) throws XMLStreamException { - while (reader.hasNext()) { - int event = reader.next(); - if (event == stopEvent) { -- if (value.equals(getValue(event))) { -- return true; -+ String xmlValue = getValue(event); -+ for (String value : values) { -+ if (value.equals(xmlValue)) { -+ return xmlValue; -+ } - } - } - } -- return false; -+ return null; - } - - public String getValue(int event) throws XMLStreamException { diff --git a/3_4_StAX_refactoring.patch b/3_4_StAX_refactoring.patch deleted file mode 100644 index 168b15d64..000000000 --- a/3_4_StAX_refactoring.patch +++ /dev/null @@ -1,158 +0,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision 52e6136915e10695a7f83412a9fd977bc2389d7b) -+++ src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision 5918da0d89f8a9146dba4d9e1ca41211807d7d4b) -@@ -5,6 +5,7 @@ - import javax.xml.bind.JAXBContext; - import javax.xml.bind.JAXBException; - import javax.xml.bind.PropertyException; -+import javax.xml.stream.XMLStreamReader; - import javax.xml.transform.stream.StreamSource; - import javax.xml.validation.Schema; - import java.io.*; -@@ -55,6 +56,10 @@ - return (T) jaxbUnmarshaller.unmarshal(str); - } - -+ public T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { -+ return jaxbUnmarshaller.unmarshal(reader, elementClass); -+ } -+ - // Marshaller - public void setMarshallerProperty(String prop, Object value) { - try { -Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision 52e6136915e10695a7f83412a9fd977bc2389d7b) -+++ src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision 5918da0d89f8a9146dba4d9e1ca41211807d7d4b) -@@ -3,6 +3,7 @@ - import javax.xml.bind.JAXBContext; - import javax.xml.bind.JAXBException; - import javax.xml.bind.Unmarshaller; -+import javax.xml.stream.XMLStreamReader; - import javax.xml.validation.Schema; - import java.io.InputStream; - import java.io.Reader; -@@ -30,4 +31,8 @@ - public Object unmarshal(String str) throws JAXBException { - return unmarshal(new StringReader(str)); - } --} -+ -+ public synchronized T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { -+ return unmarshaller.unmarshal(reader, elementClass).getValue(); -+ } -+} -\ No newline at end of file -Index: src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision 52e6136915e10695a7f83412a9fd977bc2389d7b) -+++ src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision 5918da0d89f8a9146dba4d9e1ca41211807d7d4b) -@@ -15,31 +15,43 @@ - reader = FACTORY.createXMLStreamReader(is); - } - -+ public boolean startElement(String element, String parent) throws XMLStreamException { -+ while (reader.hasNext()) { -+ int event = reader.next(); -+ if (parent != null && isElementEnd(event, parent)) { -+ return false; -+ } -+ if (isElementStart(event, element)) { -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ private boolean isElementStart(int event, String el) { -+ return event == XMLEvent.START_ELEMENT && el.equals(reader.getLocalName()); -+ } -+ -+ private boolean isElementEnd(int event, String el) { -+ return event == XMLEvent.END_ELEMENT && el.equals(reader.getLocalName()); -+ } -+ - public XMLStreamReader getReader() { - return reader; - } - -- public boolean doUntil(int stopEvent, String value) throws XMLStreamException { -- return doUntilAny(stopEvent, value) != null; -- } -- - public String getAttribute(String name) throws XMLStreamException { - return reader.getAttributeValue(null, name); - } - -- public String doUntilAny(int stopEvent, String... values) throws XMLStreamException { -+ public boolean doUntil(int stopEvent, String value) throws XMLStreamException { - while (reader.hasNext()) { - int event = reader.next(); -- if (event == stopEvent) { -- String xmlValue = getValue(event); -- for (String value : values) { -- if (value.equals(xmlValue)) { -- return xmlValue; -- } -- } -+ if (event == stopEvent && value.equals(getValue(event))) { -+ return true; - } - } -- return null; -+ return false; - } - - public String getValue(int event) throws XMLStreamException { -Index: src/test/java/ru/javaops/masterjava/MainXml.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/test/java/ru/javaops/masterjava/MainXml.java (revision 52e6136915e10695a7f83412a9fd977bc2389d7b) -+++ src/test/java/ru/javaops/masterjava/MainXml.java (revision 5918da0d89f8a9146dba4d9e1ca41211807d7d4b) -@@ -80,16 +80,12 @@ - - // Projects loop - projects: -- while (processor.doUntil(XMLEvent.START_ELEMENT, "Project")) { -+ while (processor.startElement("Project", "Projects")) { - if (projectName.equals(processor.getAttribute("name"))) { -- // Groups loop -- String element; -- while ((element = processor.doUntilAny(XMLEvent.START_ELEMENT, "Project", "Group", "Users")) != null) { -- if (!element.equals("Group")) { -- break projects; -- } -+ while (processor.startElement("Group", "Project")) { - groupNames.add(processor.getAttribute("name")); - } -+ break; - } - } - if (groupNames.isEmpty()) { -@@ -99,12 +95,11 @@ - // Users loop - Set users = new TreeSet<>(USER_COMPARATOR); - -+ JaxbParser parser = new JaxbParser(User.class); - while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { - String groupRefs = processor.getAttribute("groupRefs"); - if (!Collections.disjoint(groupNames, Splitter.on(' ').splitToList(nullToEmpty(groupRefs)))) { -- User user = new User(); -- user.setEmail(processor.getAttribute("email")); -- user.setValue(processor.getText()); -+ User user = parser.unmarshal(processor.getReader(), User.class); - users.add(user); - } - } diff --git a/3_5_HW2_xslt.patch b/3_5_HW2_xslt.patch deleted file mode 100644 index e7ea65589..000000000 --- a/3_5_HW2_xslt.patch +++ /dev/null @@ -1,104 +0,0 @@ -Index: src/main/resources/groups.xsl -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/resources/groups.xsl (revision ) -+++ src/main/resources/groups.xsl (revision ) -@@ -0,0 +1,37 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ <xsl:value-of select="$projectName"/> groups -+ -+ -+ -+

-+ groups -+

-+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+
GroupType
-+ -+ -+ -+
-+ -+ -+
-+
-\ No newline at end of file -Index: src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (date 1509357844000) -+++ src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (revision ) -@@ -40,4 +40,8 @@ - public static String getXsltHeader(String xslt) { - return "\n"; - } -+ -+ public void setParameter(String name, String value) { -+ xformer.setParameter(name, value); -+ } - } -Index: src/test/java/ru/javaops/masterjava/MainXml.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- src/test/java/ru/javaops/masterjava/MainXml.java (date 1509357844000) -+++ src/test/java/ru/javaops/masterjava/MainXml.java (revision ) -@@ -11,6 +11,7 @@ - import ru.javaops.masterjava.xml.util.JaxbParser; - import ru.javaops.masterjava.xml.util.Schemas; - import ru.javaops.masterjava.xml.util.StaxStreamProcessor; -+import ru.javaops.masterjava.xml.util.XsltProcessor; - - import java.io.InputStream; - import java.io.Writer; -@@ -48,6 +49,12 @@ - System.out.println(); - users = processByStax(projectName, payloadUrl); - users.forEach(System.out::println); -+ -+ System.out.println(); -+ html = transform(projectName, payloadUrl); -+ try (Writer writer = Files.newBufferedWriter(Paths.get("out/groups.html"))) { -+ writer.write(html); -+ } - } - - private static Set parseByJaxb(String projectName, URL payloadUrl) throws Exception { -@@ -119,4 +126,13 @@ - body().with(h1(projectName + " users"), table) - ).render(); - } -+ -+ private static String transform(String projectName, URL payloadUrl) throws Exception { -+ URL xsl = Resources.getResource("groups.xsl"); -+ try (InputStream xmlStream = payloadUrl.openStream(); InputStream xslStream = xsl.openStream()) { -+ XsltProcessor processor = new XsltProcessor(xslStream); -+ processor.setParameter("projectName", projectName); -+ return processor.transform(xmlStream); -+ } -+ } - } diff --git a/3_6_multimodule.patch b/3_6_multimodule.patch deleted file mode 100644 index 87522e64f..000000000 --- a/3_6_multimodule.patch +++ /dev/null @@ -1,294 +0,0 @@ -Index: common/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- common/pom.xml (revision ) -+++ common/pom.xml (revision ) -@@ -0,0 +1,21 @@ -+ -+ -+ 4.0.0 -+ -+ -+ ru.javaops -+ parent -+ ../parent/pom.xml -+ 1.0-SNAPSHOT -+ -+ -+ common -+ 1.0-SNAPSHOT -+ jar -+ Common -+ -+ -+ -+ -\ No newline at end of file -Index: parent/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- parent/pom.xml (revision ) -+++ parent/pom.xml (revision ) -@@ -0,0 +1,69 @@ -+ -+ -+ 4.0.0 -+ -+ ru.javaops -+ parent -+ pom -+ 1.0-SNAPSHOT -+ Parent -+ -+ -+ 1.8 -+ UTF-8 -+ UTF-8 -+ -+ -+ -+ install -+ -+ -+ org.apache.maven.plugins -+ maven-compiler-plugin -+ 3.7.0 -+ -+ ${java.version} -+ ${java.version} -+ -+ -+ -+ org.apache.maven.plugins -+ maven-surefire-plugin -+ 2.20.1 -+ -+ -Dfile.encoding=UTF-8 -+ -+ -+ -+ -+ -+ -+ -+ com.google.guava -+ guava -+ 23.3-jre -+ -+ -+ one.util -+ streamex -+ RELEASE -+ -+ -+ -+ -+ junit -+ junit -+ 4.12 -+ test -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -\ No newline at end of file -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (revision 9ee8ecec87012db4d0e272f8651cf4fdbe83b520) -+++ pom.xml (revision ) -@@ -4,119 +4,21 @@ - - ru.javaops - masterjava -- jar -+ pom - - 1.0-SNAPSHOT - - Master Java - https://github.com/JavaOPs/masterjava - -- -- 1.8 -- UTF-8 -- UTF-8 -- -- -- -- masterjava -- install -- -- -- org.apache.maven.plugins -- maven-compiler-plugin -- 3.7.0 -- -- ${java.version} -- ${java.version} -- -- -- -- org.apache.maven.plugins -- maven-surefire-plugin -- 2.20.1 -- -- -Dfile.encoding=UTF-8 -- -- -- -- org.apache.maven.plugins -- maven-shade-plugin -- 3.1.0 -- -- -- package -- -- shade -- -- -- benchmarks -- -- -- org.openjdk.jmh.Main -- -- -- -- -- -- *:* -- -- META-INF/*.SF -- META-INF/*.DSA -- META-INF/*.RSA -- -- -- -- -- -- -- -- -- -- -- -- -- org.openjdk.jmh -- jmh-core -- RELEASE -- -- -- org.openjdk.jmh -- jmh-generator-annprocess -- RELEASE -- provided -- -- -- com.google.guava -- guava -- 21.0 -- -- -- one.util -- streamex -- RELEASE -- -- -- -- com.j2html -- j2html -- RELEASE -- -- -- -- -- junit -- junit -- 4.12 -- test -- -- -- -- -- -- -- -- -+ -+ upload -+ common -+ -+ - -Index: upload/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- upload/pom.xml (revision ) -+++ upload/pom.xml (revision ) -@@ -0,0 +1,39 @@ -+ -+ -+ 4.0.0 -+ -+ -+ ru.javaops -+ parent -+ ../parent/pom.xml -+ 1.0-SNAPSHOT -+ -+ -+ upload -+ 1.0-SNAPSHOT -+ war -+ Upload -+ -+ -+ -+ -+ org.apache.maven.plugins -+ maven-war-plugin -+ 3.2.0 -+ -+ false -+ -+ -+ -+ -+ -+ -+ -+ ru.javaops -+ common -+ ${project.version} -+ -+ -+ -\ No newline at end of file diff --git a/4_1_HW3_pom_structure.patch b/4_1_HW3_pom_structure.patch deleted file mode 100644 index b01e8df31..000000000 --- a/4_1_HW3_pom_structure.patch +++ /dev/null @@ -1,535 +0,0 @@ -Index: services/mail-api/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- services/mail-api/pom.xml (revision ) -+++ services/mail-api/pom.xml (revision ) -@@ -0,0 +1,26 @@ -+ -+ -+ 4.0.0 -+ -+ -+ ru.javaops -+ parent -+ ../../parent/pom.xml -+ 1.0-SNAPSHOT -+ -+ -+ mail-api -+ 1.0-SNAPSHOT -+ Mail API -+ -+ -+ -+ ${project.groupId} -+ common -+ ${project.version} -+ -+ -+ -+ -\ No newline at end of file -Index: services/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- services/pom.xml (revision ) -+++ services/pom.xml (revision ) -@@ -0,0 +1,15 @@ -+ -+ 4.0.0 -+ -+ ru.javaops -+ services -+ pom -+ 1.0-SNAPSHOT -+ -+ Services -+ -+ mail-api -+ mail-service -+ -+ -Index: test/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- test/pom.xml (revision ) -+++ test/pom.xml (revision ) -@@ -0,0 +1,76 @@ -+ -+ -+ 4.0.0 -+ -+ -+ ru.javaops -+ parent -+ ../parent/pom.xml -+ 1.0-SNAPSHOT -+ -+ -+ test -+ 1.0-SNAPSHOT -+ Test -+ -+ -+ -+ -+ org.apache.maven.plugins -+ maven-shade-plugin -+ 2.2 -+ -+ -+ package -+ -+ shade -+ -+ -+ benchmarks -+ -+ -+ org.openjdk.jmh.Main -+ -+ -+ -+ -+ -+ *:* -+ -+ META-INF/*.SF -+ META-INF/*.DSA -+ META-INF/*.RSA -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ ${project.groupId} -+ common -+ ${project.version} -+ -+ -+ org.openjdk.jmh -+ jmh-core -+ RELEASE -+ -+ -+ org.openjdk.jmh -+ jmh-generator-annprocess -+ RELEASE -+ provided -+ -+ -+ -\ No newline at end of file -Index: web/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/pom.xml (revision ) -+++ web/pom.xml (revision ) -@@ -0,0 +1,15 @@ -+ -+ 4.0.0 -+ -+ ru.javaops -+ web -+ pom -+ 1.0-SNAPSHOT -+ Web -+ -+ -+ upload -+ webapp -+ -+ -Index: web/webapp/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/webapp/pom.xml (revision ) -+++ web/webapp/pom.xml (revision ) -@@ -0,0 +1,30 @@ -+ -+ -+ 4.0.0 -+ -+ -+ ru.javaops -+ parent-web -+ ../../parent-web/pom.xml -+ 1.0-SNAPSHOT -+ -+ -+ webapp -+ 1.0-SNAPSHOT -+ war -+ WebApp -+ -+ -+ webapp -+ -+ -+ -+ -+ ${project.groupId} -+ common -+ ${project.version} -+ -+ -+ -\ No newline at end of file -Index: services/mail-service/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- services/mail-service/pom.xml (revision ) -+++ services/mail-service/pom.xml (revision ) -@@ -0,0 +1,26 @@ -+ -+ -+ 4.0.0 -+ -+ -+ ru.javaops -+ parent-web -+ ../../parent-web/pom.xml -+ 1.0-SNAPSHOT -+ -+ -+ mail-service -+ 1.0-SNAPSHOT -+ war -+ Mail Service -+ -+ -+ -+ ${project.groupId} -+ mail-api -+ ${project.version} -+ -+ -+ -\ No newline at end of file -Index: web/upload/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/pom.xml (revision ) -+++ web/upload/pom.xml (revision ) -@@ -0,0 +1,31 @@ -+ -+ -+ 4.0.0 -+ -+ -+ ru.javaops -+ parent-web -+ ../../parent-web/pom.xml -+ 1.0-SNAPSHOT -+ -+ -+ upload -+ 1.0-SNAPSHOT -+ war -+ Upload -+ -+ -+ upload -+ -+ -+ -+ -+ com.j2html -+ j2html -+ 1.2.0 -+ -+ -+ -+ -\ No newline at end of file -Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/schema/Payload.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java -=================================================================== ---- src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java (date 1510506709000) -+++ web/upload/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/schema/User.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/User.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/User.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java -=================================================================== ---- src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (date 1510506709000) -+++ web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (date 1510506709000) -+++ test/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/resources/cities.xsl -=================================================================== ---- src/main/resources/cities.xsl (date 1510506709000) -+++ web/upload/src/main/resources/cities.xsl (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/resources/groups.xsl -=================================================================== ---- src/main/resources/groups.xsl (date 1510506709000) -+++ web/upload/src/main/resources/groups.xsl (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/resources/payload.xsd -=================================================================== ---- src/main/resources/payload.xsd (date 1510506709000) -+++ web/upload/src/main/resources/payload.xsd (revision ) -@@ -1,0 +1,0 @@ -Index: upload/pom.xml -=================================================================== ---- upload/pom.xml (date 1510506709000) -+++ parent-web/pom.xml (revision ) -@@ -11,10 +11,10 @@ - 1.0-SNAPSHOT - - -- upload -+ parent-web -+ pom - 1.0-SNAPSHOT -- war -- Upload -+ Parent Web - - - -@@ -31,9 +31,16 @@ - - - -- ru.javaops -- common -- ${project.version} -+ javax.servlet -+ javax.servlet-api -+ 3.1.0 -+ provided - - -+ -+ -+ -+ -+ -+ - -\ No newline at end of file -Index: src/test/resources/payload.xml -=================================================================== ---- src/test/resources/payload.xml (date 1510506709000) -+++ web/upload/src/test/resources/payload.xml (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/util/Schemas.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/Schemas.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (date 1510506709000) -+++ test/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/test/resources/city.xml -=================================================================== ---- src/test/resources/city.xml (date 1510506709000) -+++ web/upload/src/test/resources/city.xml (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java -=================================================================== ---- src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java (date 1510506709000) -+++ web/upload/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/schema/Project.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/Project.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Project.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/test/java/ru/javaops/masterjava/MainXml.java -=================================================================== ---- src/test/java/ru/javaops/masterjava/MainXml.java (date 1510506709000) -+++ web/upload/src/test/java/ru/javaops/masterjava/MainXml.java (revision ) -@@ -20,7 +20,6 @@ - import java.nio.file.Files; - import java.nio.file.Paths; - import java.util.*; --import java.util.stream.Collectors; - - import static com.google.common.base.Strings.nullToEmpty; - import static j2html.TagCreator.*; -@@ -74,9 +73,7 @@ - final Set groups = new HashSet<>(project.getGroup()); // identity compare - return StreamEx.of(payload.getUsers().getUser()) - .filter(u -> !Collections.disjoint(groups, u.getGroupRefs())) -- .collect( -- Collectors.toCollection(() -> new TreeSet<>(USER_COMPARATOR)) -- ); -+ .toCollection(() -> new TreeSet<>(USER_COMPARATOR)); - } - - private static Set processByStax(String projectName, URL payloadUrl) throws Exception { -Index: src/main/java/ru/javaops/masterjava/xml/schema/CityType.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/CityType.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java (revision ) -@@ -1,13 +1,8 @@ -+ - - package ru.javaops.masterjava.xml.schema; - --import javax.xml.bind.annotation.XmlAccessType; --import javax.xml.bind.annotation.XmlAccessorType; --import javax.xml.bind.annotation.XmlAttribute; --import javax.xml.bind.annotation.XmlID; --import javax.xml.bind.annotation.XmlSchemaType; --import javax.xml.bind.annotation.XmlType; --import javax.xml.bind.annotation.XmlValue; -+import javax.xml.bind.annotation.*; - import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; - import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - -Index: src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (date 1510506709000) -+++ test/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (revision ) -@@ -1,0 +1,0 @@ -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (date 1510506709000) -+++ pom.xml (revision ) -@@ -8,17 +8,14 @@ - - 1.0-SNAPSHOT - -- Master Java -+ Masterjava Root - https://github.com/JavaOPs/masterjava - - -- upload - common -- -+ -+ web -+ services - - -Index: src/main/java/ru/javaops/masterjava/service/MailService.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/service/MailService.java (date 1510506709000) -+++ services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailServiceExecutor.java (revision ) -@@ -1,4 +1,4 @@ --package ru.javaops.masterjava.service; -+package ru.javaops.masterjava.service.mail; - - import java.util.ArrayList; - import java.util.List; -@@ -6,7 +6,7 @@ - import java.util.concurrent.*; - import java.util.stream.Collectors; - --public class MailService { -+public class MailServiceExecutor { - private static final String OK = "OK"; - - private static final String INTERRUPTED_BY_FAULTS_NUMBER = "+++ Interrupted by faults number"; -Index: src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java -=================================================================== ---- src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java (date 1510506709000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java (revision ) -@@ -1,0 +1,0 @@ -Index: src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java -=================================================================== ---- src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java (date 1510506709000) -+++ web/upload/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java (revision ) -@@ -1,0 +1,0 @@ From 05913a020e8794f2f74a6418e41b8ca6b1cc3f27 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 08:26:59 +0200 Subject: [PATCH 23/46] 4 1 HW3 pom structure --- {upload => parent-web}/pom.xml | 19 +++-- pom.xml | 11 +-- services/mail-api/pom.xml | 26 +++++++ services/mail-service/pom.xml | 26 +++++++ .../service/mail/MailServiceExecutor.java | 4 +- services/pom.xml | 15 ++++ test/pom.xml | 76 +++++++++++++++++++ .../javaops/masterjava/matrix/MainMatrix.java | 0 .../masterjava/matrix/MatrixBenchmark.java | 0 .../javaops/masterjava/matrix/MatrixUtil.java | 0 web/pom.xml | 15 ++++ web/upload/pom.xml | 31 ++++++++ .../masterjava/xml/schema/CityType.java | 9 +-- .../masterjava/xml/schema/FlagType.java | 0 .../masterjava/xml/schema/GroupType.java | 0 .../masterjava/xml/schema/ObjectFactory.java | 0 .../masterjava/xml/schema/Payload.java | 0 .../masterjava/xml/schema/Project.java | 0 .../javaops/masterjava/xml/schema/User.java | 0 .../masterjava/xml/util/JaxbMarshaller.java | 0 .../masterjava/xml/util/JaxbParser.java | 0 .../masterjava/xml/util/JaxbUnmarshaller.java | 0 .../javaops/masterjava/xml/util/Schemas.java | 0 .../xml/util/StaxStreamProcessor.java | 0 .../masterjava/xml/util/XPathProcessor.java | 0 .../masterjava/xml/util/XsltProcessor.java | 0 .../upload/src}/main/resources/cities.xsl | 0 .../upload/src}/main/resources/groups.xsl | 0 .../upload/src}/main/resources/payload.xsd | 0 .../java/ru/javaops/masterjava/MainXml.java | 5 +- .../masterjava/xml/util/JaxbParserTest.java | 0 .../xml/util/StaxStreamProcessorTest.java | 0 .../xml/util/XPathProcessorTest.java | 0 .../xml/util/XsltProcessorTest.java | 0 .../upload/src}/test/resources/city.xml | 0 .../upload/src}/test/resources/payload.xml | 0 web/webapp/pom.xml | 30 ++++++++ 37 files changed, 241 insertions(+), 26 deletions(-) rename {upload => parent-web}/pom.xml (74%) create mode 100644 services/mail-api/pom.xml create mode 100644 services/mail-service/pom.xml rename src/main/java/ru/javaops/masterjava/service/MailService.java => services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailServiceExecutor.java (98%) create mode 100644 services/pom.xml create mode 100644 test/pom.xml rename {src => test/src}/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (100%) rename {src => test/src}/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (100%) rename {src => test/src}/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (100%) create mode 100644 web/pom.xml create mode 100644 web/upload/pom.xml rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/schema/CityType.java (85%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/schema/FlagType.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/schema/GroupType.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/schema/Payload.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/schema/Project.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/schema/User.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/util/Schemas.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java (100%) rename {src => web/upload/src}/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (100%) rename {src => web/upload/src}/main/resources/cities.xsl (100%) rename {src => web/upload/src}/main/resources/groups.xsl (100%) rename {src => web/upload/src}/main/resources/payload.xsd (100%) rename {src => web/upload/src}/test/java/ru/javaops/masterjava/MainXml.java (96%) rename {src => web/upload/src}/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (100%) rename {src => web/upload/src}/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java (100%) rename {src => web/upload/src}/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java (100%) rename {src => web/upload/src}/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java (100%) rename {src => web/upload/src}/test/resources/city.xml (100%) rename {src => web/upload/src}/test/resources/payload.xml (100%) create mode 100644 web/webapp/pom.xml diff --git a/upload/pom.xml b/parent-web/pom.xml similarity index 74% rename from upload/pom.xml rename to parent-web/pom.xml index 7cac01c05..e46b5a49f 100644 --- a/upload/pom.xml +++ b/parent-web/pom.xml @@ -11,10 +11,10 @@ 1.0-SNAPSHOT - upload + parent-web + pom 1.0-SNAPSHOT - war - Upload + Parent Web @@ -31,9 +31,16 @@ - ru.javaops - common - ${project.version} + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0085819cf..f0c5cbbb2 100644 --- a/pom.xml +++ b/pom.xml @@ -8,17 +8,14 @@ 1.0-SNAPSHOT - Master Java + Masterjava Root https://github.com/JavaOPs/masterjava - upload common - + + web + services diff --git a/services/mail-api/pom.xml b/services/mail-api/pom.xml new file mode 100644 index 000000000..25c53388e --- /dev/null +++ b/services/mail-api/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + + ru.javaops + parent + ../../parent/pom.xml + 1.0-SNAPSHOT + + + mail-api + 1.0-SNAPSHOT + Mail API + + + + ${project.groupId} + common + ${project.version} + + + + \ No newline at end of file diff --git a/services/mail-service/pom.xml b/services/mail-service/pom.xml new file mode 100644 index 000000000..2b4be6bad --- /dev/null +++ b/services/mail-service/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + + ru.javaops + parent-web + ../../parent-web/pom.xml + 1.0-SNAPSHOT + + + mail-service + 1.0-SNAPSHOT + war + Mail Service + + + + ${project.groupId} + mail-api + ${project.version} + + + \ No newline at end of file diff --git a/src/main/java/ru/javaops/masterjava/service/MailService.java b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailServiceExecutor.java similarity index 98% rename from src/main/java/ru/javaops/masterjava/service/MailService.java rename to services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailServiceExecutor.java index cef46e55e..e26f302d2 100644 --- a/src/main/java/ru/javaops/masterjava/service/MailService.java +++ b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailServiceExecutor.java @@ -1,4 +1,4 @@ -package ru.javaops.masterjava.service; +package ru.javaops.masterjava.service.mail; import java.util.ArrayList; import java.util.List; @@ -6,7 +6,7 @@ import java.util.concurrent.*; import java.util.stream.Collectors; -public class MailService { +public class MailServiceExecutor { private static final String OK = "OK"; private static final String INTERRUPTED_BY_FAULTS_NUMBER = "+++ Interrupted by faults number"; diff --git a/services/pom.xml b/services/pom.xml new file mode 100644 index 000000000..62ffc5e38 --- /dev/null +++ b/services/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + + ru.javaops + services + pom + 1.0-SNAPSHOT + + Services + + mail-api + mail-service + + diff --git a/test/pom.xml b/test/pom.xml new file mode 100644 index 000000000..f469908cf --- /dev/null +++ b/test/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + + ru.javaops + parent + ../parent/pom.xml + 1.0-SNAPSHOT + + + test + 1.0-SNAPSHOT + Test + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.2 + + + package + + shade + + + benchmarks + + + org.openjdk.jmh.Main + + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + + + ${project.groupId} + common + ${project.version} + + + org.openjdk.jmh + jmh-core + RELEASE + + + org.openjdk.jmh + jmh-generator-annprocess + RELEASE + provided + + + \ No newline at end of file diff --git a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java b/test/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java rename to test/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java b/test/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java rename to test/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/test/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java rename to test/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java diff --git a/web/pom.xml b/web/pom.xml new file mode 100644 index 000000000..76ff400e0 --- /dev/null +++ b/web/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + + ru.javaops + web + pom + 1.0-SNAPSHOT + Web + + + upload + webapp + + diff --git a/web/upload/pom.xml b/web/upload/pom.xml new file mode 100644 index 000000000..881475191 --- /dev/null +++ b/web/upload/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + + ru.javaops + parent-web + ../../parent-web/pom.xml + 1.0-SNAPSHOT + + + upload + 1.0-SNAPSHOT + war + Upload + + + upload + + + + + com.j2html + j2html + 1.2.0 + + + + \ No newline at end of file diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java similarity index 85% rename from src/main/java/ru/javaops/masterjava/xml/schema/CityType.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java index 029e352cb..6a83965e1 100644 --- a/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java +++ b/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java @@ -1,13 +1,8 @@ + package ru.javaops.masterjava.xml.schema; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlID; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/schema/Payload.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/Project.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Project.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/schema/Project.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Project.java diff --git a/src/main/java/ru/javaops/masterjava/xml/schema/User.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/User.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/schema/User.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/schema/User.java diff --git a/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java diff --git a/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java diff --git a/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java diff --git a/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/util/Schemas.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java diff --git a/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java diff --git a/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java diff --git a/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java similarity index 100% rename from src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java rename to web/upload/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java diff --git a/src/main/resources/cities.xsl b/web/upload/src/main/resources/cities.xsl similarity index 100% rename from src/main/resources/cities.xsl rename to web/upload/src/main/resources/cities.xsl diff --git a/src/main/resources/groups.xsl b/web/upload/src/main/resources/groups.xsl similarity index 100% rename from src/main/resources/groups.xsl rename to web/upload/src/main/resources/groups.xsl diff --git a/src/main/resources/payload.xsd b/web/upload/src/main/resources/payload.xsd similarity index 100% rename from src/main/resources/payload.xsd rename to web/upload/src/main/resources/payload.xsd diff --git a/src/test/java/ru/javaops/masterjava/MainXml.java b/web/upload/src/test/java/ru/javaops/masterjava/MainXml.java similarity index 96% rename from src/test/java/ru/javaops/masterjava/MainXml.java rename to web/upload/src/test/java/ru/javaops/masterjava/MainXml.java index 8f57825c7..08db01e0e 100644 --- a/src/test/java/ru/javaops/masterjava/MainXml.java +++ b/web/upload/src/test/java/ru/javaops/masterjava/MainXml.java @@ -20,7 +20,6 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; -import java.util.stream.Collectors; import static com.google.common.base.Strings.nullToEmpty; import static j2html.TagCreator.*; @@ -74,9 +73,7 @@ private static Set parseByJaxb(String projectName, URL payloadUrl) throws final Set groups = new HashSet<>(project.getGroup()); // identity compare return StreamEx.of(payload.getUsers().getUser()) .filter(u -> !Collections.disjoint(groups, u.getGroupRefs())) - .collect( - Collectors.toCollection(() -> new TreeSet<>(USER_COMPARATOR)) - ); + .toCollection(() -> new TreeSet<>(USER_COMPARATOR)); } private static Set processByStax(String projectName, URL payloadUrl) throws Exception { diff --git a/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java b/web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java similarity index 100% rename from src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java rename to web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java diff --git a/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java b/web/upload/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java similarity index 100% rename from src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java rename to web/upload/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java diff --git a/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java b/web/upload/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java similarity index 100% rename from src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java rename to web/upload/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java diff --git a/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java b/web/upload/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java similarity index 100% rename from src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java rename to web/upload/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java diff --git a/src/test/resources/city.xml b/web/upload/src/test/resources/city.xml similarity index 100% rename from src/test/resources/city.xml rename to web/upload/src/test/resources/city.xml diff --git a/src/test/resources/payload.xml b/web/upload/src/test/resources/payload.xml similarity index 100% rename from src/test/resources/payload.xml rename to web/upload/src/test/resources/payload.xml diff --git a/web/webapp/pom.xml b/web/webapp/pom.xml new file mode 100644 index 000000000..60bb1c8c3 --- /dev/null +++ b/web/webapp/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + + + ru.javaops + parent-web + ../../parent-web/pom.xml + 1.0-SNAPSHOT + + + webapp + 1.0-SNAPSHOT + war + WebApp + + + webapp + + + + + ${project.groupId} + common + ${project.version} + + + \ No newline at end of file From c9539de0886e9b7bc0b5500676f69f64f8251019 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 10:08:11 +0200 Subject: [PATCH 24/46] 2 09 XPath --- parent-web/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parent-web/pom.xml b/parent-web/pom.xml index e46b5a49f..894c41bd3 100644 --- a/parent-web/pom.xml +++ b/parent-web/pom.xml @@ -18,7 +18,7 @@ - + org.apache.maven.plugins maven-war-plugin 3.2.0 From 29da96e5ec86f42910f3d4fc289675c8d2dcc9c9 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 10:42:34 +0200 Subject: [PATCH 25/46] 4 2 HW3 thymeleaf upload --- parent-web/pom.xml | 5 ++ web/common-web/pom.xml | 42 +++++++++++++ .../common/web/ThymeleafListener.java | 20 ++++++ .../masterjava/common/web/ThymeleafUtil.java | 24 +++++++ web/pom.xml | 1 + .../ru/javaops/masterjava/model/User.java | 63 +++++++++++++++++++ .../ru/javaops/masterjava/model/UserFlag.java | 11 ++++ .../masterjava/upload/UploadServlet.java | 56 +++++++++++++++++ .../masterjava/upload/UserProcessor.java | 28 +++++++++ .../webapp/WEB-INF/templates/exception.html | 20 ++++++ .../main/webapp/WEB-INF/templates/result.html | 27 ++++++++ .../main/webapp/WEB-INF/templates/upload.html | 16 +++++ 12 files changed, 313 insertions(+) create mode 100644 web/common-web/pom.xml create mode 100644 web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafListener.java create mode 100644 web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java create mode 100644 web/upload/src/main/java/ru/javaops/masterjava/model/User.java create mode 100644 web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java create mode 100644 web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java create mode 100644 web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java create mode 100644 web/upload/src/main/webapp/WEB-INF/templates/exception.html create mode 100644 web/upload/src/main/webapp/WEB-INF/templates/result.html create mode 100644 web/upload/src/main/webapp/WEB-INF/templates/upload.html diff --git a/parent-web/pom.xml b/parent-web/pom.xml index 894c41bd3..b902f721f 100644 --- a/parent-web/pom.xml +++ b/parent-web/pom.xml @@ -30,6 +30,11 @@ + + ${project.groupId} + common-web + ${project.version} + javax.servlet javax.servlet-api diff --git a/web/common-web/pom.xml b/web/common-web/pom.xml new file mode 100644 index 000000000..a72bf0040 --- /dev/null +++ b/web/common-web/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + + ru.javaops + parent + ../../parent/pom.xml + 1.0-SNAPSHOT + + + common-web + 1.0-SNAPSHOT + Common Web + + + + ${project.groupId} + common + ${project.version} + + + commons-fileupload + commons-fileupload + 1.3.3 + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + + org.thymeleaf + thymeleaf + 3.0.8.RELEASE + + + \ No newline at end of file diff --git a/web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafListener.java b/web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafListener.java new file mode 100644 index 000000000..16948aa44 --- /dev/null +++ b/web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafListener.java @@ -0,0 +1,20 @@ +package ru.javaops.masterjava.common.web; + +import org.thymeleaf.TemplateEngine; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.annotation.WebListener; + +@WebListener +public class ThymeleafListener implements ServletContextListener { + + public static TemplateEngine engine; + + public void contextInitialized(ServletContextEvent sce) { + engine = ThymeleafUtil.getTemplateEngine(sce.getServletContext()); + } + + public void contextDestroyed(ServletContextEvent sce) { + } +} diff --git a/web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java b/web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java new file mode 100644 index 000000000..bf87ed3eb --- /dev/null +++ b/web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java @@ -0,0 +1,24 @@ +package ru.javaops.masterjava.common.web; + +import org.thymeleaf.TemplateEngine; +import org.thymeleaf.templatemode.TemplateMode; +import org.thymeleaf.templateresolver.ServletContextTemplateResolver; + +import javax.servlet.ServletContext; + +public class ThymeleafUtil { + + private ThymeleafUtil() { + } + + public static TemplateEngine getTemplateEngine(ServletContext context) { + final ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(context); + templateResolver.setTemplateMode(TemplateMode.HTML); + templateResolver.setPrefix("/WEB-INF/templates/"); + templateResolver.setSuffix(".html"); + templateResolver.setCacheTTLMs(1000L); + final TemplateEngine engine = new TemplateEngine(); + engine.setTemplateResolver(templateResolver); + return engine; + } +} diff --git a/web/pom.xml b/web/pom.xml index 76ff400e0..ddb4a428b 100644 --- a/web/pom.xml +++ b/web/pom.xml @@ -9,6 +9,7 @@ Web + common-web upload webapp diff --git a/web/upload/src/main/java/ru/javaops/masterjava/model/User.java b/web/upload/src/main/java/ru/javaops/masterjava/model/User.java new file mode 100644 index 000000000..d7c3f8cd3 --- /dev/null +++ b/web/upload/src/main/java/ru/javaops/masterjava/model/User.java @@ -0,0 +1,63 @@ +package ru.javaops.masterjava.model; + +import java.util.Objects; + +public class User { + private final Integer id; + private final String fullName; + private final String email; + private final UserFlag flag; + + public User(String fullName, String email, UserFlag flag) { + this(null, fullName, email, flag); + } + + public User(Integer id, String fullName, String email, UserFlag flag) { + this.id = id; + this.fullName = fullName; + this.email = email; + this.flag = flag; + } + + public Integer getId() { + return id; + } + + public String getFullName() { + return fullName; + } + + public String getEmail() { + return email; + } + + public UserFlag getFlag() { + return flag; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + User user = (User) o; + return Objects.equals(id, user.id) && + Objects.equals(fullName, user.fullName) && + Objects.equals(email, user.email) && + flag == user.flag; + } + + @Override + public int hashCode() { + return Objects.hash(id, fullName, email, flag); + } + + @Override + public String toString() { + return "User (" + + "id=" + id + + ", fullName='" + fullName + '\'' + + ", email='" + email + '\'' + + ", flag=" + flag + + ')'; + } +} diff --git a/web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java b/web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java new file mode 100644 index 000000000..603626ae1 --- /dev/null +++ b/web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java @@ -0,0 +1,11 @@ +package ru.javaops.masterjava.model; + +/** + * gkislin + * 13.10.2016 + */ +public enum UserFlag { + active, + deleted, + superuser; +} diff --git a/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java b/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java new file mode 100644 index 000000000..86e82db66 --- /dev/null +++ b/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java @@ -0,0 +1,56 @@ +package ru.javaops.masterjava.upload; + +import org.apache.commons.fileupload.FileItemIterator; +import org.apache.commons.fileupload.FileItemStream; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.thymeleaf.context.WebContext; +import ru.javaops.masterjava.model.User; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import static ru.javaops.masterjava.common.web.ThymeleafListener.engine; + +@WebServlet("/") +public class UploadServlet extends HttpServlet { + + private final UserProcessor userProcessor = new UserProcessor(); + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale()); + engine.process("upload", webContext, resp.getWriter()); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + final ServletFileUpload upload = new ServletFileUpload(); + final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale()); + + try { +// https://commons.apache.org/proper/commons-fileupload/streaming.html + + final FileItemIterator itemIterator = upload.getItemIterator(req); + while (itemIterator.hasNext()) { //expect that it's only one file + FileItemStream fileItemStream = itemIterator.next(); + if (!fileItemStream.isFormField()) { + try (InputStream is = fileItemStream.openStream()) { + List users = userProcessor.process(is); + webContext.setVariable("users", users); + engine.process("result", webContext, resp.getWriter()); + } + break; + } + } + } catch (Exception e) { + webContext.setVariable("exception", e); + engine.process("exception", webContext, resp.getWriter()); + } + } +} diff --git a/web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java b/web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java new file mode 100644 index 000000000..4c81d3483 --- /dev/null +++ b/web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java @@ -0,0 +1,28 @@ +package ru.javaops.masterjava.upload; + +import ru.javaops.masterjava.model.User; +import ru.javaops.masterjava.model.UserFlag; +import ru.javaops.masterjava.xml.util.StaxStreamProcessor; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.XMLEvent; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +public class UserProcessor { + + public List process(final InputStream is) throws XMLStreamException { + final StaxStreamProcessor processor = new StaxStreamProcessor(is); + List users = new ArrayList<>(); + + while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { + final String email = processor.getAttribute("email"); + final UserFlag flag = UserFlag.valueOf(processor.getAttribute("flag")); + final String fullName = processor.getReader().getElementText(); + final User user = new User(fullName, email, flag); + users.add(user); + } + return users; + } +} diff --git a/web/upload/src/main/webapp/WEB-INF/templates/exception.html b/web/upload/src/main/webapp/WEB-INF/templates/exception.html new file mode 100644 index 000000000..2b5e6fe5a --- /dev/null +++ b/web/upload/src/main/webapp/WEB-INF/templates/exception.html @@ -0,0 +1,20 @@ + + + + Application error + + + +
+
+
+

Application error:

+ +

exception.message

+
    +
  • +
+
+
+ + \ No newline at end of file diff --git a/web/upload/src/main/webapp/WEB-INF/templates/result.html b/web/upload/src/main/webapp/WEB-INF/templates/result.html new file mode 100644 index 000000000..01ec88cfd --- /dev/null +++ b/web/upload/src/main/webapp/WEB-INF/templates/result.html @@ -0,0 +1,27 @@ + + + + Uploaded users + + +

Upload XML

+

Uploaded users

+ + + + + + + + + + + + + + + + +
Full NameEmailFlag
+ + \ No newline at end of file diff --git a/web/upload/src/main/webapp/WEB-INF/templates/upload.html b/web/upload/src/main/webapp/WEB-INF/templates/upload.html new file mode 100644 index 000000000..d48c3123e --- /dev/null +++ b/web/upload/src/main/webapp/WEB-INF/templates/upload.html @@ -0,0 +1,16 @@ + + + Upload XML + + +
+

Select xml file to upload

+

+
+

+

+ +

+
+ + \ No newline at end of file From fcdd9d957142549b7ceb8dad30344d2cea120679 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 13:41:52 +0200 Subject: [PATCH 26/46] 4.2h3 XPath --- .../java/ru/javaops/masterjava/common/web/ThymeleafUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java b/web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java index bf87ed3eb..0d817ff52 100644 --- a/web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java +++ b/web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java @@ -16,8 +16,8 @@ public static TemplateEngine getTemplateEngine(ServletContext context) { templateResolver.setTemplateMode(TemplateMode.HTML); templateResolver.setPrefix("/WEB-INF/templates/"); templateResolver.setSuffix(".html"); - templateResolver.setCacheTTLMs(1000L); - final TemplateEngine engine = new TemplateEngine(); + templateResolver.setCacheTTLMs(1000L);// Через какое время обновлять кеш + final TemplateEngine engine = new TemplateEngine();// Движок который обрабатывает наши теймлейты engine.setTemplateResolver(templateResolver); return engine; } From 364e78aec7c36dae257183557a03d4a055d92596 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 13:42:41 +0200 Subject: [PATCH 27/46] 4 3 HW3 upload servlet3 --- web/common-web/pom.xml | 5 --- .../masterjava/upload/UploadServlet.java | 31 ++++++++----------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/web/common-web/pom.xml b/web/common-web/pom.xml index a72bf0040..98ba46590 100644 --- a/web/common-web/pom.xml +++ b/web/common-web/pom.xml @@ -21,11 +21,6 @@ common ${project.version}
- - commons-fileupload - commons-fileupload - 1.3.3 - javax.servlet javax.servlet-api diff --git a/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java b/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java index 86e82db66..3831eda27 100644 --- a/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java +++ b/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java @@ -1,23 +1,23 @@ package ru.javaops.masterjava.upload; -import org.apache.commons.fileupload.FileItemIterator; -import org.apache.commons.fileupload.FileItemStream; -import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.thymeleaf.context.WebContext; import ru.javaops.masterjava.model.User; import javax.servlet.ServletException; +import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.Part; import java.io.IOException; import java.io.InputStream; import java.util.List; import static ru.javaops.masterjava.common.web.ThymeleafListener.engine; -@WebServlet("/") +@WebServlet(urlPatterns = "/", loadOnStartup = 1) +@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 10) //10 MB in memory limit public class UploadServlet extends HttpServlet { private final UserProcessor userProcessor = new UserProcessor(); @@ -30,23 +30,18 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - final ServletFileUpload upload = new ServletFileUpload(); final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale()); try { -// https://commons.apache.org/proper/commons-fileupload/streaming.html - - final FileItemIterator itemIterator = upload.getItemIterator(req); - while (itemIterator.hasNext()) { //expect that it's only one file - FileItemStream fileItemStream = itemIterator.next(); - if (!fileItemStream.isFormField()) { - try (InputStream is = fileItemStream.openStream()) { - List users = userProcessor.process(is); - webContext.setVariable("users", users); - engine.process("result", webContext, resp.getWriter()); - } - break; - } +// http://docs.oracle.com/javaee/6/tutorial/doc/glraq.html + Part filePart = req.getPart("fileToUpload"); + if (filePart.getSize() == 0) { + throw new IllegalStateException("Upload file have not been selected"); + } + try (InputStream is = filePart.getInputStream()) { + List users = userProcessor.process(is); + webContext.setVariable("users", users); + engine.process("result", webContext, resp.getWriter()); } } catch (Exception e) { webContext.setVariable("exception", e); From 0b772e6823f28931f00bdd3fbec40fe19d139ca0 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 13:44:50 +0200 Subject: [PATCH 28/46] 4.2h3 XPath --- 4_2_HW3_thymeleaf_upload.patch | 425 --------------------------------- 1 file changed, 425 deletions(-) delete mode 100644 4_2_HW3_thymeleaf_upload.patch diff --git a/4_2_HW3_thymeleaf_upload.patch b/4_2_HW3_thymeleaf_upload.patch deleted file mode 100644 index 35f72dd77..000000000 --- a/4_2_HW3_thymeleaf_upload.patch +++ /dev/null @@ -1,425 +0,0 @@ -Index: web/upload/src/main/webapp/WEB-INF/templates/result.html -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/webapp/WEB-INF/templates/result.html (revision ) -+++ web/upload/src/main/webapp/WEB-INF/templates/result.html (revision ) -@@ -0,0 +1,27 @@ -+ -+ -+ -+ Uploaded users -+ -+ -+

Upload XML

-+

Uploaded users

-+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+
Full NameEmailFlag
-+ -+ -\ No newline at end of file -Index: web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java (revision ) -+++ web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java (revision ) -@@ -0,0 +1,28 @@ -+package ru.javaops.masterjava.upload; -+ -+import ru.javaops.masterjava.model.User; -+import ru.javaops.masterjava.model.UserFlag; -+import ru.javaops.masterjava.xml.util.StaxStreamProcessor; -+ -+import javax.xml.stream.XMLStreamException; -+import javax.xml.stream.events.XMLEvent; -+import java.io.InputStream; -+import java.util.ArrayList; -+import java.util.List; -+ -+public class UserProcessor { -+ -+ public List process(final InputStream is) throws XMLStreamException { -+ final StaxStreamProcessor processor = new StaxStreamProcessor(is); -+ List users = new ArrayList<>(); -+ -+ while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { -+ final String email = processor.getAttribute("email"); -+ final UserFlag flag = UserFlag.valueOf(processor.getAttribute("flag")); -+ final String fullName = processor.getReader().getElementText(); -+ final User user = new User(fullName, email, flag); -+ users.add(user); -+ } -+ return users; -+ } -+} -Index: web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java (revision ) -+++ web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java (revision ) -@@ -0,0 +1,11 @@ -+package ru.javaops.masterjava.model; -+ -+/** -+ * gkislin -+ * 13.10.2016 -+ */ -+public enum UserFlag { -+ active, -+ deleted, -+ superuser; -+} -Index: web/upload/src/main/webapp/WEB-INF/templates/exception.html -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/webapp/WEB-INF/templates/exception.html (revision ) -+++ web/upload/src/main/webapp/WEB-INF/templates/exception.html (revision ) -@@ -0,0 +1,20 @@ -+ -+ -+ -+ Application error -+ -+ -+ -+
-+
-+
-+

Application error:

-+ -+

exception.message

-+
    -+
  • -+
-+
-+
-+ -+ -\ No newline at end of file -Index: web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafListener.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafListener.java (revision ) -+++ web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafListener.java (revision ) -@@ -0,0 +1,20 @@ -+package ru.javaops.masterjava.common.web; -+ -+import org.thymeleaf.TemplateEngine; -+ -+import javax.servlet.ServletContextEvent; -+import javax.servlet.ServletContextListener; -+import javax.servlet.annotation.WebListener; -+ -+@WebListener -+public class ThymeleafListener implements ServletContextListener { -+ -+ public static TemplateEngine engine; -+ -+ public void contextInitialized(ServletContextEvent sce) { -+ engine = ThymeleafUtil.getTemplateEngine(sce.getServletContext()); -+ } -+ -+ public void contextDestroyed(ServletContextEvent sce) { -+ } -+} -Index: web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java (revision ) -+++ web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java (revision ) -@@ -0,0 +1,56 @@ -+package ru.javaops.masterjava.upload; -+ -+import org.apache.commons.fileupload.FileItemIterator; -+import org.apache.commons.fileupload.FileItemStream; -+import org.apache.commons.fileupload.servlet.ServletFileUpload; -+import org.thymeleaf.context.WebContext; -+import ru.javaops.masterjava.model.User; -+ -+import javax.servlet.ServletException; -+import javax.servlet.annotation.WebServlet; -+import javax.servlet.http.HttpServlet; -+import javax.servlet.http.HttpServletRequest; -+import javax.servlet.http.HttpServletResponse; -+import java.io.IOException; -+import java.io.InputStream; -+import java.util.List; -+ -+import static ru.javaops.masterjava.common.web.ThymeleafListener.engine; -+ -+@WebServlet("/") -+public class UploadServlet extends HttpServlet { -+ -+ private final UserProcessor userProcessor = new UserProcessor(); -+ -+ @Override -+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { -+ final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale()); -+ engine.process("upload", webContext, resp.getWriter()); -+ } -+ -+ @Override -+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { -+ final ServletFileUpload upload = new ServletFileUpload(); -+ final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale()); -+ -+ try { -+// https://commons.apache.org/proper/commons-fileupload/streaming.html -+ -+ final FileItemIterator itemIterator = upload.getItemIterator(req); -+ while (itemIterator.hasNext()) { //expect that it's only one file -+ FileItemStream fileItemStream = itemIterator.next(); -+ if (!fileItemStream.isFormField()) { -+ try (InputStream is = fileItemStream.openStream()) { -+ List users = userProcessor.process(is); -+ webContext.setVariable("users", users); -+ engine.process("result", webContext, resp.getWriter()); -+ } -+ break; -+ } -+ } -+ } catch (Exception e) { -+ webContext.setVariable("exception", e); -+ engine.process("exception", webContext, resp.getWriter()); -+ } -+ } -+} -Index: web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java (revision ) -+++ web/common-web/src/main/java/ru/javaops/masterjava/common/web/ThymeleafUtil.java (revision ) -@@ -0,0 +1,24 @@ -+package ru.javaops.masterjava.common.web; -+ -+import org.thymeleaf.TemplateEngine; -+import org.thymeleaf.templatemode.TemplateMode; -+import org.thymeleaf.templateresolver.ServletContextTemplateResolver; -+ -+import javax.servlet.ServletContext; -+ -+public class ThymeleafUtil { -+ -+ private ThymeleafUtil() { -+ } -+ -+ public static TemplateEngine getTemplateEngine(ServletContext context) { -+ final ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(context); -+ templateResolver.setTemplateMode(TemplateMode.HTML); -+ templateResolver.setPrefix("/WEB-INF/templates/"); -+ templateResolver.setSuffix(".html"); -+ templateResolver.setCacheTTLMs(1000L); -+ final TemplateEngine engine = new TemplateEngine(); -+ engine.setTemplateResolver(templateResolver); -+ return engine; -+ } -+} -Index: web/common-web/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/common-web/pom.xml (revision ) -+++ web/common-web/pom.xml (revision ) -@@ -0,0 +1,42 @@ -+ -+ -+ 4.0.0 -+ -+ -+ ru.javaops -+ parent -+ ../../parent/pom.xml -+ 1.0-SNAPSHOT -+ -+ -+ common-web -+ 1.0-SNAPSHOT -+ Common Web -+ -+ -+ -+ ${project.groupId} -+ common -+ ${project.version} -+ -+ -+ commons-fileupload -+ commons-fileupload -+ 1.3.3 -+ -+ -+ javax.servlet -+ javax.servlet-api -+ 3.1.0 -+ provided -+ -+ -+ -+ org.thymeleaf -+ thymeleaf -+ 3.0.8.RELEASE -+ -+ -+ -\ No newline at end of file -Index: web/upload/src/main/java/ru/javaops/masterjava/model/User.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/java/ru/javaops/masterjava/model/User.java (revision ) -+++ web/upload/src/main/java/ru/javaops/masterjava/model/User.java (revision ) -@@ -0,0 +1,63 @@ -+package ru.javaops.masterjava.model; -+ -+import java.util.Objects; -+ -+public class User { -+ private final Integer id; -+ private final String fullName; -+ private final String email; -+ private final UserFlag flag; -+ -+ public User(String fullName, String email, UserFlag flag) { -+ this(null, fullName, email, flag); -+ } -+ -+ public User(Integer id, String fullName, String email, UserFlag flag) { -+ this.id = id; -+ this.fullName = fullName; -+ this.email = email; -+ this.flag = flag; -+ } -+ -+ public Integer getId() { -+ return id; -+ } -+ -+ public String getFullName() { -+ return fullName; -+ } -+ -+ public String getEmail() { -+ return email; -+ } -+ -+ public UserFlag getFlag() { -+ return flag; -+ } -+ -+ @Override -+ public boolean equals(Object o) { -+ if (this == o) return true; -+ if (o == null || getClass() != o.getClass()) return false; -+ User user = (User) o; -+ return Objects.equals(id, user.id) && -+ Objects.equals(fullName, user.fullName) && -+ Objects.equals(email, user.email) && -+ flag == user.flag; -+ } -+ -+ @Override -+ public int hashCode() { -+ return Objects.hash(id, fullName, email, flag); -+ } -+ -+ @Override -+ public String toString() { -+ return "User (" + -+ "id=" + id + -+ ", fullName='" + fullName + '\'' + -+ ", email='" + email + '\'' + -+ ", flag=" + flag + -+ ')'; -+ } -+} -Index: web/upload/src/main/webapp/WEB-INF/templates/upload.html -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/webapp/WEB-INF/templates/upload.html (revision ) -+++ web/upload/src/main/webapp/WEB-INF/templates/upload.html (revision ) -@@ -0,0 +1,16 @@ -+ -+ -+ Upload XML -+ -+ -+
-+

Select xml file to upload

-+

-+
-+

-+

-+ -+

-+
-+ -+ -\ No newline at end of file -Index: web/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/pom.xml (date 1509890578000) -+++ web/pom.xml (revision ) -@@ -9,6 +9,7 @@ - Web - - -+ common-web - upload - webapp - -Index: parent-web/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- parent-web/pom.xml (date 1509890578000) -+++ parent-web/pom.xml (revision ) -@@ -31,6 +31,11 @@ - - - -+ ${project.groupId} -+ common-web -+ ${project.version} -+ -+ - javax.servlet - javax.servlet-api - 3.1.0 From 138bed59bcb5e0625d6d6db3381ecdae3897e71d Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 18:13:51 +0200 Subject: [PATCH 29/46] 4.2h3 XPath --- web/upload/pom.xml | 6 ++++++ .../java/ru/javaops/masterjava/upload/UploadServlet.java | 2 -- web/upload/src/main/webapp/WEB-INF/templates/result.html | 8 ++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/web/upload/pom.xml b/web/upload/pom.xml index 881475191..a313ef729 100644 --- a/web/upload/pom.xml +++ b/web/upload/pom.xml @@ -26,6 +26,12 @@ j2html 1.2.0 + + ${project.groupId} + common-web + ${project.version} + compile + \ No newline at end of file diff --git a/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java b/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java index 3831eda27..21c73a8e5 100644 --- a/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java +++ b/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java @@ -2,7 +2,6 @@ import org.thymeleaf.context.WebContext; import ru.javaops.masterjava.model.User; - import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; @@ -13,7 +12,6 @@ import java.io.IOException; import java.io.InputStream; import java.util.List; - import static ru.javaops.masterjava.common.web.ThymeleafListener.engine; @WebServlet(urlPatterns = "/", loadOnStartup = 1) diff --git a/web/upload/src/main/webapp/WEB-INF/templates/result.html b/web/upload/src/main/webapp/WEB-INF/templates/result.html index 01ec88cfd..40f006484 100644 --- a/web/upload/src/main/webapp/WEB-INF/templates/result.html +++ b/web/upload/src/main/webapp/WEB-INF/templates/result.html @@ -15,11 +15,11 @@

Uploaded users

- + - - - + user.fullName + user.email + user.flag From 4d643e052a4d608078a4d23625f83137381aebb9 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 18:14:03 +0200 Subject: [PATCH 30/46] 4 2 HW3 thymeleaf upload --- web/common-web/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web/common-web/pom.xml b/web/common-web/pom.xml index 98ba46590..a72bf0040 100644 --- a/web/common-web/pom.xml +++ b/web/common-web/pom.xml @@ -21,6 +21,11 @@ common ${project.version}
+ + commons-fileupload + commons-fileupload + 1.3.3 + javax.servlet javax.servlet-api From 263458ad76db1260aa3c4059aca52a8c4d69f94f Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 18:14:35 +0200 Subject: [PATCH 31/46] 4 4 HW3 jaxb stax --- .../masterjava/upload/UserProcessor.java | 14 ++-- .../masterjava/xml/util/JaxbMarshaller.java | 15 ++-- .../masterjava/xml/util/JaxbParser.java | 71 ++++++++----------- .../masterjava/xml/util/JaxbUnmarshaller.java | 16 ++--- .../java/ru/javaops/masterjava/MainXml.java | 13 ++-- .../masterjava/xml/util/JaxbParserTest.java | 22 +++--- 6 files changed, 75 insertions(+), 76 deletions(-) diff --git a/web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java b/web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java index 4c81d3483..f8c574bf8 100644 --- a/web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java +++ b/web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java @@ -2,8 +2,12 @@ import ru.javaops.masterjava.model.User; import ru.javaops.masterjava.model.UserFlag; +import ru.javaops.masterjava.xml.schema.ObjectFactory; +import ru.javaops.masterjava.xml.util.JaxbParser; +import ru.javaops.masterjava.xml.util.JaxbUnmarshaller; import ru.javaops.masterjava.xml.util.StaxStreamProcessor; +import javax.xml.bind.JAXBException; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.XMLEvent; import java.io.InputStream; @@ -11,16 +15,16 @@ import java.util.List; public class UserProcessor { + private static final JaxbParser jaxbParser = new JaxbParser(ObjectFactory.class); - public List process(final InputStream is) throws XMLStreamException { + public List process(final InputStream is) throws XMLStreamException, JAXBException { final StaxStreamProcessor processor = new StaxStreamProcessor(is); List users = new ArrayList<>(); + JaxbUnmarshaller unmarshaller = jaxbParser.createUnmarshaller(); while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { - final String email = processor.getAttribute("email"); - final UserFlag flag = UserFlag.valueOf(processor.getAttribute("flag")); - final String fullName = processor.getReader().getElementText(); - final User user = new User(fullName, email, flag); + ru.javaops.masterjava.xml.schema.User xmlUser = unmarshaller.unmarshal(processor.getReader(), ru.javaops.masterjava.xml.schema.User.class); + final User user = new User(xmlUser.getValue(), xmlUser.getEmail(), UserFlag.valueOf(xmlUser.getFlag().value())); users.add(user); } return users; diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java index d6006800f..507825dda 100644 --- a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java +++ b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java @@ -18,11 +18,15 @@ public JaxbMarshaller(JAXBContext ctx) throws JAXBException { marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); } - public void setProperty(String prop, Object value) throws PropertyException { - marshaller.setProperty(prop, value); + public void setProperty(String prop, Object value) { + try { + marshaller.setProperty(prop, value); + } catch (PropertyException e) { + throw new IllegalArgumentException(e); + } } - public synchronized void setSchema(Schema schema) { + public void setSchema(Schema schema) { marshaller.setSchema(schema); } @@ -32,8 +36,7 @@ public String marshal(Object instance) throws JAXBException { return sw.toString(); } - public synchronized void marshal(Object instance, Writer writer) throws JAXBException { + public void marshal(Object instance, Writer writer) throws JAXBException { marshaller.marshal(instance, writer); } - -} +} \ No newline at end of file diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java index 563d53ba0..8aff55510 100644 --- a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java +++ b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java @@ -4,28 +4,26 @@ import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; -import javax.xml.bind.PropertyException; -import javax.xml.stream.XMLStreamReader; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; -import java.io.*; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; /** - * Marshalling/Unmarshalling JAXB helper - * XML Facade + * Marshalling/Unmarshalling JAXB facade */ public class JaxbParser { - protected JaxbMarshaller jaxbMarshaller; - protected JaxbUnmarshaller jaxbUnmarshaller; + private JAXBContext ctx; protected Schema schema; public JaxbParser(Class... classesToBeBound) { try { init(JAXBContext.newInstance(classesToBeBound)); } catch (JAXBException e) { - throw new IllegalArgumentException(e); + throw new IllegalStateException(e); } } @@ -34,53 +32,42 @@ public JaxbParser(String context) { try { init(JAXBContext.newInstance(context)); } catch (JAXBException e) { - throw new IllegalArgumentException(e); + throw new IllegalStateException(e); } } - private void init(JAXBContext ctx) throws JAXBException { - jaxbMarshaller = new JaxbMarshaller(ctx); - jaxbUnmarshaller = new JaxbUnmarshaller(ctx); + private void init(JAXBContext ctx) { + this.ctx = ctx; } - // Unmarshaller - public T unmarshal(InputStream is) throws JAXBException { - return (T) jaxbUnmarshaller.unmarshal(is); - } - - public T unmarshal(Reader reader) throws JAXBException { - return (T) jaxbUnmarshaller.unmarshal(reader); - } - - public T unmarshal(String str) throws JAXBException { - return (T) jaxbUnmarshaller.unmarshal(str); - } - - public T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { - return jaxbUnmarshaller.unmarshal(reader, elementClass); - } - - // Marshaller - public void setMarshallerProperty(String prop, Object value) { + // https://stackoverflow.com/a/7400735/548473 + public JaxbMarshaller createMarshaller() { try { - jaxbMarshaller.setProperty(prop, value); - } catch (PropertyException e) { - throw new IllegalArgumentException(e); + JaxbMarshaller marshaller = new JaxbMarshaller(ctx); + if (schema != null) { + marshaller.setSchema(schema); + } + return marshaller; + } catch (JAXBException e) { + throw new IllegalStateException(e); } } - public String marshal(Object instance) throws JAXBException { - return jaxbMarshaller.marshal(instance); - } - - public void marshal(Object instance, Writer writer) throws JAXBException { - jaxbMarshaller.marshal(instance, writer); + // https://stackoverflow.com/a/7400735/548473 + public JaxbUnmarshaller createUnmarshaller() { + try { + JaxbUnmarshaller unmarshaller = new JaxbUnmarshaller(ctx); + if (schema != null) { + unmarshaller.setSchema(schema); + } + return unmarshaller; + } catch (JAXBException e) { + throw new IllegalStateException(e); + } } public void setSchema(Schema schema) { this.schema = schema; - jaxbUnmarshaller.setSchema(schema); - jaxbMarshaller.setSchema(schema); } public void validate(String str) throws IOException, SAXException { diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java index 1de89d823..f9f29c2c9 100644 --- a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java +++ b/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java @@ -16,23 +16,23 @@ public JaxbUnmarshaller(JAXBContext ctx) throws JAXBException { unmarshaller = ctx.createUnmarshaller(); } - public synchronized void setSchema(Schema schema) { + public void setSchema(Schema schema) { unmarshaller.setSchema(schema); } - public synchronized Object unmarshal(InputStream is) throws JAXBException { - return unmarshaller.unmarshal(is); + public T unmarshal(InputStream is) throws JAXBException { + return (T) unmarshaller.unmarshal(is); } - public synchronized Object unmarshal(Reader reader) throws JAXBException { - return unmarshaller.unmarshal(reader); + public T unmarshal(Reader reader) throws JAXBException { + return (T) unmarshaller.unmarshal(reader); } - public Object unmarshal(String str) throws JAXBException { - return unmarshal(new StringReader(str)); + public T unmarshal(String str) throws JAXBException { + return (T) unmarshal(new StringReader(str)); } - public synchronized T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { + public T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { return unmarshaller.unmarshal(reader, elementClass).getValue(); } } \ No newline at end of file diff --git a/web/upload/src/test/java/ru/javaops/masterjava/MainXml.java b/web/upload/src/test/java/ru/javaops/masterjava/MainXml.java index 08db01e0e..ce2e3a902 100644 --- a/web/upload/src/test/java/ru/javaops/masterjava/MainXml.java +++ b/web/upload/src/test/java/ru/javaops/masterjava/MainXml.java @@ -8,10 +8,7 @@ import ru.javaops.masterjava.xml.schema.Payload; import ru.javaops.masterjava.xml.schema.Project; import ru.javaops.masterjava.xml.schema.User; -import ru.javaops.masterjava.xml.util.JaxbParser; -import ru.javaops.masterjava.xml.util.Schemas; -import ru.javaops.masterjava.xml.util.StaxStreamProcessor; -import ru.javaops.masterjava.xml.util.XsltProcessor; +import ru.javaops.masterjava.xml.util.*; import javax.xml.stream.events.XMLEvent; import java.io.InputStream; @@ -59,10 +56,11 @@ public static void main(String[] args) throws Exception { private static Set parseByJaxb(String projectName, URL payloadUrl) throws Exception { JaxbParser parser = new JaxbParser(ObjectFactory.class); + JaxbUnmarshaller unmarshaller = parser.createUnmarshaller(); parser.setSchema(Schemas.ofClasspath("payload.xsd")); Payload payload; try (InputStream is = payloadUrl.openStream()) { - payload = parser.unmarshal(is); + payload = unmarshaller.unmarshal(is); } Project project = StreamEx.of(payload.getProjects().getProject()) @@ -99,11 +97,12 @@ private static Set processByStax(String projectName, URL payloadUrl) throw // Users loop Set users = new TreeSet<>(USER_COMPARATOR); - JaxbParser parser = new JaxbParser(User.class); + JaxbParser parser = new JaxbParser(ObjectFactory.class); + JaxbUnmarshaller unmarshaller = parser.createUnmarshaller(); while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { String groupRefs = processor.getAttribute("groupRefs"); if (!Collections.disjoint(groupNames, Splitter.on(' ').splitToList(nullToEmpty(groupRefs)))) { - User user = parser.unmarshal(processor.getReader(), User.class); + User user = unmarshaller.unmarshal(processor.getReader(), User.class); users.add(user); } } diff --git a/web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java b/web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java index 623265428..4754b17d6 100644 --- a/web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java +++ b/web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java @@ -10,31 +10,37 @@ import javax.xml.namespace.QName; public class JaxbParserTest { - private static final JaxbParser JAXB_PARSER = new JaxbParser(ObjectFactory.class); + // https://google.github.io/styleguide/javaguide.html#s5.2.4-constant-names + private static final JaxbParser jaxbParser; + private static final JaxbMarshaller marshaller; + private static final JaxbUnmarshaller unmarshaller; static { - JAXB_PARSER.setSchema(Schemas.ofClasspath("payload.xsd")); + jaxbParser = new JaxbParser(ObjectFactory.class); + jaxbParser.setSchema(Schemas.ofClasspath("payload.xsd")); + marshaller = jaxbParser.createMarshaller(); + unmarshaller = jaxbParser.createUnmarshaller(); } @Test public void testPayload() throws Exception { // JaxbParserTest.class.getResourceAsStream("/city.xml") - Payload payload = JAXB_PARSER.unmarshal( + Payload payload = unmarshaller.unmarshal( Resources.getResource("payload.xml").openStream()); - String strPayload = JAXB_PARSER.marshal(payload); - JAXB_PARSER.validate(strPayload); + String strPayload = marshaller.marshal(payload); + jaxbParser.validate(strPayload); System.out.println(strPayload); } @Test public void testCity() throws Exception { - JAXBElement cityElement = JAXB_PARSER.unmarshal( + JAXBElement cityElement = unmarshaller.unmarshal( Resources.getResource("city.xml").openStream()); CityType city = cityElement.getValue(); JAXBElement cityElement2 = new JAXBElement<>(new QName("http://javaops.ru", "City"), CityType.class, city); - String strCity = JAXB_PARSER.marshal(cityElement2); - JAXB_PARSER.validate(strCity); + String strCity = marshaller.marshal(cityElement2); + jaxbParser.validate(strCity); System.out.println(strCity); } } \ No newline at end of file From 8e907b7a3e072995d6a9dd89535f418b2080d6a4 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 18:39:26 +0200 Subject: [PATCH 32/46] 4 3 HW3 upload servlet3 --- web/common-web/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/web/common-web/pom.xml b/web/common-web/pom.xml index a72bf0040..98ba46590 100644 --- a/web/common-web/pom.xml +++ b/web/common-web/pom.xml @@ -21,11 +21,6 @@ common ${project.version} - - commons-fileupload - commons-fileupload - 1.3.3 - javax.servlet javax.servlet-api From a82ea18808b9fc866963a5fb5e899c5d04e36ff6 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 19:58:14 +0200 Subject: [PATCH 33/46] 4.2h3 XPath --- 4_3_HW3_upload_servlet3.patch | 87 --------- 4_4_HW3_jaxb_stax.patch | 341 ---------------------------------- 2 files changed, 428 deletions(-) delete mode 100644 4_3_HW3_upload_servlet3.patch delete mode 100644 4_4_HW3_jaxb_stax.patch diff --git a/4_3_HW3_upload_servlet3.patch b/4_3_HW3_upload_servlet3.patch deleted file mode 100644 index 28afb256c..000000000 --- a/4_3_HW3_upload_servlet3.patch +++ /dev/null @@ -1,87 +0,0 @@ -Index: web/common-web/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/common-web/pom.xml (date 1510507514000) -+++ web/common-web/pom.xml (revision ) -@@ -22,11 +22,6 @@ - ${project.version} - - -- commons-fileupload -- commons-fileupload -- 1.3.3 -- -- - javax.servlet - javax.servlet-api - 3.1.0 -Index: web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java (date 1510507514000) -+++ web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java (revision ) -@@ -1,23 +1,23 @@ - package ru.javaops.masterjava.upload; - --import org.apache.commons.fileupload.FileItemIterator; --import org.apache.commons.fileupload.FileItemStream; --import org.apache.commons.fileupload.servlet.ServletFileUpload; - import org.thymeleaf.context.WebContext; - import ru.javaops.masterjava.model.User; - - import javax.servlet.ServletException; -+import javax.servlet.annotation.MultipartConfig; - import javax.servlet.annotation.WebServlet; - import javax.servlet.http.HttpServlet; - import javax.servlet.http.HttpServletRequest; - import javax.servlet.http.HttpServletResponse; -+import javax.servlet.http.Part; - import java.io.IOException; - import java.io.InputStream; - import java.util.List; - - import static ru.javaops.masterjava.common.web.ThymeleafListener.engine; - --@WebServlet("/") -+@WebServlet(urlPatterns = "/", loadOnStartup = 1) -+@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 10) //10 MB in memory limit - public class UploadServlet extends HttpServlet { - - private final UserProcessor userProcessor = new UserProcessor(); -@@ -30,23 +30,18 @@ - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { -- final ServletFileUpload upload = new ServletFileUpload(); - final WebContext webContext = new WebContext(req, resp, req.getServletContext(), req.getLocale()); - - try { --// https://commons.apache.org/proper/commons-fileupload/streaming.html -- -- final FileItemIterator itemIterator = upload.getItemIterator(req); -- while (itemIterator.hasNext()) { //expect that it's only one file -- FileItemStream fileItemStream = itemIterator.next(); -- if (!fileItemStream.isFormField()) { -- try (InputStream is = fileItemStream.openStream()) { -- List users = userProcessor.process(is); -- webContext.setVariable("users", users); -- engine.process("result", webContext, resp.getWriter()); -- } -- break; -- } -+// http://docs.oracle.com/javaee/6/tutorial/doc/glraq.html -+ Part filePart = req.getPart("fileToUpload"); -+ if (filePart.getSize() == 0) { -+ throw new IllegalStateException("Upload file have not been selected"); -+ } -+ try (InputStream is = filePart.getInputStream()) { -+ List users = userProcessor.process(is); -+ webContext.setVariable("users", users); -+ engine.process("result", webContext, resp.getWriter()); - } - } catch (Exception e) { - webContext.setVariable("exception", e); diff --git a/4_4_HW3_jaxb_stax.patch b/4_4_HW3_jaxb_stax.patch deleted file mode 100644 index 59c54fd96..000000000 --- a/4_4_HW3_jaxb_stax.patch +++ /dev/null @@ -1,341 +0,0 @@ -Index: web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java (date 1510508700000) -+++ web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java (revision ) -@@ -2,8 +2,12 @@ - - import ru.javaops.masterjava.model.User; - import ru.javaops.masterjava.model.UserFlag; -+import ru.javaops.masterjava.xml.schema.ObjectFactory; -+import ru.javaops.masterjava.xml.util.JaxbParser; -+import ru.javaops.masterjava.xml.util.JaxbUnmarshaller; - import ru.javaops.masterjava.xml.util.StaxStreamProcessor; - -+import javax.xml.bind.JAXBException; - import javax.xml.stream.XMLStreamException; - import javax.xml.stream.events.XMLEvent; - import java.io.InputStream; -@@ -11,16 +15,16 @@ - import java.util.List; - - public class UserProcessor { -+ private static final JaxbParser jaxbParser = new JaxbParser(ObjectFactory.class); - -- public List process(final InputStream is) throws XMLStreamException { -+ public List process(final InputStream is) throws XMLStreamException, JAXBException { - final StaxStreamProcessor processor = new StaxStreamProcessor(is); - List users = new ArrayList<>(); - -+ JaxbUnmarshaller unmarshaller = jaxbParser.createUnmarshaller(); - while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { -- final String email = processor.getAttribute("email"); -- final UserFlag flag = UserFlag.valueOf(processor.getAttribute("flag")); -- final String fullName = processor.getReader().getElementText(); -- final User user = new User(fullName, email, flag); -+ ru.javaops.masterjava.xml.schema.User xmlUser = unmarshaller.unmarshal(processor.getReader(), ru.javaops.masterjava.xml.schema.User.class); -+ final User user = new User(xmlUser.getValue(), xmlUser.getEmail(), UserFlag.valueOf(xmlUser.getFlag().value())); - users.add(user); - } - return users; -Index: web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (date 1510508700000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (revision ) -@@ -16,23 +16,23 @@ - unmarshaller = ctx.createUnmarshaller(); - } - -- public synchronized void setSchema(Schema schema) { -+ public void setSchema(Schema schema) { - unmarshaller.setSchema(schema); - } - -- public synchronized Object unmarshal(InputStream is) throws JAXBException { -- return unmarshaller.unmarshal(is); -+ public T unmarshal(InputStream is) throws JAXBException { -+ return (T) unmarshaller.unmarshal(is); - } - -- public synchronized Object unmarshal(Reader reader) throws JAXBException { -- return unmarshaller.unmarshal(reader); -+ public T unmarshal(Reader reader) throws JAXBException { -+ return (T) unmarshaller.unmarshal(reader); - } - -- public Object unmarshal(String str) throws JAXBException { -- return unmarshal(new StringReader(str)); -+ public T unmarshal(String str) throws JAXBException { -+ return (T) unmarshal(new StringReader(str)); - } - -- public synchronized T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { -+ public T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { - return unmarshaller.unmarshal(reader, elementClass).getValue(); - } - } -\ No newline at end of file -Index: web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (date 1510508700000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (revision ) -@@ -4,28 +4,26 @@ - - import javax.xml.bind.JAXBContext; - import javax.xml.bind.JAXBException; --import javax.xml.bind.PropertyException; --import javax.xml.stream.XMLStreamReader; - import javax.xml.transform.stream.StreamSource; - import javax.xml.validation.Schema; --import java.io.*; -+import java.io.IOException; -+import java.io.Reader; -+import java.io.StringReader; - - - /** -- * Marshalling/Unmarshalling JAXB helper -- * XML Facade -+ * Marshalling/Unmarshalling JAXB facade - */ - public class JaxbParser { - -- protected JaxbMarshaller jaxbMarshaller; -- protected JaxbUnmarshaller jaxbUnmarshaller; -+ private JAXBContext ctx; - protected Schema schema; - - public JaxbParser(Class... classesToBeBound) { - try { - init(JAXBContext.newInstance(classesToBeBound)); - } catch (JAXBException e) { -- throw new IllegalArgumentException(e); -+ throw new IllegalStateException(e); - } - } - -@@ -34,53 +32,42 @@ - try { - init(JAXBContext.newInstance(context)); - } catch (JAXBException e) { -- throw new IllegalArgumentException(e); -+ throw new IllegalStateException(e); - } - } - -- private void init(JAXBContext ctx) throws JAXBException { -- jaxbMarshaller = new JaxbMarshaller(ctx); -- jaxbUnmarshaller = new JaxbUnmarshaller(ctx); -+ private void init(JAXBContext ctx) { -+ this.ctx = ctx; - } - -- // Unmarshaller -- public T unmarshal(InputStream is) throws JAXBException { -- return (T) jaxbUnmarshaller.unmarshal(is); -- } -- -- public T unmarshal(Reader reader) throws JAXBException { -- return (T) jaxbUnmarshaller.unmarshal(reader); -- } -- -- public T unmarshal(String str) throws JAXBException { -- return (T) jaxbUnmarshaller.unmarshal(str); -- } -- -- public T unmarshal(XMLStreamReader reader, Class elementClass) throws JAXBException { -- return jaxbUnmarshaller.unmarshal(reader, elementClass); -- } -- -- // Marshaller -- public void setMarshallerProperty(String prop, Object value) { -+ // https://stackoverflow.com/a/7400735/548473 -+ public JaxbMarshaller createMarshaller() { - try { -- jaxbMarshaller.setProperty(prop, value); -- } catch (PropertyException e) { -- throw new IllegalArgumentException(e); -- } -- } -- -- public String marshal(Object instance) throws JAXBException { -- return jaxbMarshaller.marshal(instance); -+ JaxbMarshaller marshaller = new JaxbMarshaller(ctx); -+ if (schema != null) { -+ marshaller.setSchema(schema); -+ } -+ return marshaller; -+ } catch (JAXBException e) { -+ throw new IllegalStateException(e); -+ } - } - -- public void marshal(Object instance, Writer writer) throws JAXBException { -- jaxbMarshaller.marshal(instance, writer); -+ // https://stackoverflow.com/a/7400735/548473 -+ public JaxbUnmarshaller createUnmarshaller() { -+ try { -+ JaxbUnmarshaller unmarshaller = new JaxbUnmarshaller(ctx); -+ if (schema != null) { -+ unmarshaller.setSchema(schema); -+ } -+ return unmarshaller; -+ } catch (JAXBException e) { -+ throw new IllegalStateException(e); -+ } - } - - public void setSchema(Schema schema) { - this.schema = schema; -- jaxbUnmarshaller.setSchema(schema); -- jaxbMarshaller.setSchema(schema); - } - - public void validate(String str) throws IOException, SAXException { -Index: web/upload/src/test/java/ru/javaops/masterjava/MainXml.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/test/java/ru/javaops/masterjava/MainXml.java (date 1510508700000) -+++ web/upload/src/test/java/ru/javaops/masterjava/MainXml.java (revision ) -@@ -8,10 +8,7 @@ - import ru.javaops.masterjava.xml.schema.Payload; - import ru.javaops.masterjava.xml.schema.Project; - import ru.javaops.masterjava.xml.schema.User; --import ru.javaops.masterjava.xml.util.JaxbParser; --import ru.javaops.masterjava.xml.util.Schemas; --import ru.javaops.masterjava.xml.util.StaxStreamProcessor; --import ru.javaops.masterjava.xml.util.XsltProcessor; -+import ru.javaops.masterjava.xml.util.*; - - import javax.xml.stream.events.XMLEvent; - import java.io.InputStream; -@@ -59,10 +56,11 @@ - - private static Set parseByJaxb(String projectName, URL payloadUrl) throws Exception { - JaxbParser parser = new JaxbParser(ObjectFactory.class); -+ JaxbUnmarshaller unmarshaller = parser.createUnmarshaller(); - parser.setSchema(Schemas.ofClasspath("payload.xsd")); - Payload payload; - try (InputStream is = payloadUrl.openStream()) { -- payload = parser.unmarshal(is); -+ payload = unmarshaller.unmarshal(is); - } - - Project project = StreamEx.of(payload.getProjects().getProject()) -@@ -99,11 +97,12 @@ - // Users loop - Set users = new TreeSet<>(USER_COMPARATOR); - -- JaxbParser parser = new JaxbParser(User.class); -+ JaxbParser parser = new JaxbParser(ObjectFactory.class); -+ JaxbUnmarshaller unmarshaller = parser.createUnmarshaller(); - while (processor.doUntil(XMLEvent.START_ELEMENT, "User")) { - String groupRefs = processor.getAttribute("groupRefs"); - if (!Collections.disjoint(groupNames, Splitter.on(' ').splitToList(nullToEmpty(groupRefs)))) { -- User user = parser.unmarshal(processor.getReader(), User.class); -+ User user = unmarshaller.unmarshal(processor.getReader(), User.class); - users.add(user); - } - } -Index: web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (date 1510508700000) -+++ web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (revision ) -@@ -18,11 +18,15 @@ - marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); - } - -- public void setProperty(String prop, Object value) throws PropertyException { -- marshaller.setProperty(prop, value); -+ public void setProperty(String prop, Object value) { -+ try { -+ marshaller.setProperty(prop, value); -+ } catch (PropertyException e) { -+ throw new IllegalArgumentException(e); -+ } - } - -- public synchronized void setSchema(Schema schema) { -+ public void setSchema(Schema schema) { - marshaller.setSchema(schema); - } - -@@ -32,8 +36,7 @@ - return sw.toString(); - } - -- public synchronized void marshal(Object instance, Writer writer) throws JAXBException { -+ public void marshal(Object instance, Writer writer) throws JAXBException { - marshaller.marshal(instance, writer); - } -- --} -+} -\ No newline at end of file -Index: web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (date 1510508700000) -+++ web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (revision ) -@@ -10,31 +10,37 @@ - import javax.xml.namespace.QName; - - public class JaxbParserTest { -- private static final JaxbParser JAXB_PARSER = new JaxbParser(ObjectFactory.class); -+ // https://google.github.io/styleguide/javaguide.html#s5.2.4-constant-names -+ private static final JaxbParser jaxbParser; -+ private static final JaxbMarshaller marshaller; -+ private static final JaxbUnmarshaller unmarshaller; - - static { -- JAXB_PARSER.setSchema(Schemas.ofClasspath("payload.xsd")); -+ jaxbParser = new JaxbParser(ObjectFactory.class); -+ jaxbParser.setSchema(Schemas.ofClasspath("payload.xsd")); -+ marshaller = jaxbParser.createMarshaller(); -+ unmarshaller = jaxbParser.createUnmarshaller(); - } - - @Test - public void testPayload() throws Exception { - // JaxbParserTest.class.getResourceAsStream("/city.xml") -- Payload payload = JAXB_PARSER.unmarshal( -+ Payload payload = unmarshaller.unmarshal( - Resources.getResource("payload.xml").openStream()); -- String strPayload = JAXB_PARSER.marshal(payload); -- JAXB_PARSER.validate(strPayload); -+ String strPayload = marshaller.marshal(payload); -+ jaxbParser.validate(strPayload); - System.out.println(strPayload); - } - - @Test - public void testCity() throws Exception { -- JAXBElement cityElement = JAXB_PARSER.unmarshal( -+ JAXBElement cityElement = unmarshaller.unmarshal( - Resources.getResource("city.xml").openStream()); - CityType city = cityElement.getValue(); - JAXBElement cityElement2 = - new JAXBElement<>(new QName("http://javaops.ru", "City"), CityType.class, city); -- String strCity = JAXB_PARSER.marshal(cityElement2); -- JAXB_PARSER.validate(strCity); -+ String strCity = marshaller.marshal(cityElement2); -+ jaxbParser.validate(strCity); - System.out.println(strCity); - } - } -\ No newline at end of file From d26a370ac700329ba3db5292542771c44eccb980 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 19:58:28 +0200 Subject: [PATCH 34/46] 4 5 dependencies --- parent/pom.xml | 2 ++ pom.xml | 3 +++ 2 files changed, 5 insertions(+) diff --git a/parent/pom.xml b/parent/pom.xml index d7b056d1d..c32ae495a 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -14,6 +14,8 @@ 1.8 UTF-8 UTF-8 + + false diff --git a/pom.xml b/pom.xml index f0c5cbbb2..43674e646 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,9 @@ https://github.com/JavaOPs/masterjava + parent + parent-web + common test From da06ac576134044b674776012205318c8899bbd1 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 20:59:03 +0200 Subject: [PATCH 35/46] 4 6 fix convergence --- web/upload/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web/upload/pom.xml b/web/upload/pom.xml index a313ef729..4fb7cc050 100644 --- a/web/upload/pom.xml +++ b/web/upload/pom.xml @@ -25,6 +25,12 @@ com.j2html j2html 1.2.0 + + + com.google.guava + guava + + ${project.groupId} From dc9f548f3beb60f904a23d771f32ac6432246dd5 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 20:59:18 +0200 Subject: [PATCH 36/46] 4.2h3 XPath --- 4_5_dependencies.patch | 33 ---------------------- 4_6_fix_convergence.patch | 58 --------------------------------------- parent/pom.xml | 2 +- test/pom.xml | 4 +-- 4 files changed, 3 insertions(+), 94 deletions(-) delete mode 100644 4_5_dependencies.patch delete mode 100644 4_6_fix_convergence.patch diff --git a/4_5_dependencies.patch b/4_5_dependencies.patch deleted file mode 100644 index 03cf7222c..000000000 --- a/4_5_dependencies.patch +++ /dev/null @@ -1,33 +0,0 @@ -Index: parent/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- parent/pom.xml (date 1490101176000) -+++ parent/pom.xml (revision ) -@@ -14,6 +14,8 @@ - 1.8 - UTF-8 - UTF-8 -+ -+ false - - - -Index: pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- pom.xml (date 1490101176000) -+++ pom.xml (revision ) -@@ -12,6 +12,9 @@ - https://github.com/JavaOPs/masterjava - - -+ parent -+ parent-web -+ - common - test - diff --git a/4_6_fix_convergence.patch b/4_6_fix_convergence.patch deleted file mode 100644 index 06ed4939a..000000000 --- a/4_6_fix_convergence.patch +++ /dev/null @@ -1,58 +0,0 @@ -Index: web/upload/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/upload/pom.xml (date 1510518837000) -+++ web/upload/pom.xml (revision ) -@@ -25,6 +25,12 @@ - com.j2html - j2html - 1.2.0 -+ -+ -+ com.google.guava -+ guava -+ -+ - -
- -Index: test/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- test/pom.xml (date 1510518837000) -+++ test/pom.xml (revision ) -@@ -64,12 +64,12 @@ - - org.openjdk.jmh - jmh-core -- RELEASE -+ 1.19 - - - org.openjdk.jmh - jmh-generator-annprocess -- RELEASE -+ 1.19 - provided - - -Index: parent/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- parent/pom.xml (date 1510518837000) -+++ parent/pom.xml (revision ) -@@ -50,7 +50,7 @@ - - one.util - streamex -- RELEASE -+ 0.6.6 - - - diff --git a/parent/pom.xml b/parent/pom.xml index c32ae495a..21d6c9c02 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -50,7 +50,7 @@ one.util streamex - RELEASE + 0.6.7 diff --git a/test/pom.xml b/test/pom.xml index f469908cf..9e4585463 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -64,12 +64,12 @@ org.openjdk.jmh jmh-core - RELEASE + 1.21 org.openjdk.jmh jmh-generator-annprocess - RELEASE + 1.21 provided From a602487dacdf03dff6c5614a598a238a00a88832 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 21:02:09 +0200 Subject: [PATCH 37/46] 4.2h3 XPath --- 4_7_enforcer.patch | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 4_7_enforcer.patch diff --git a/4_7_enforcer.patch b/4_7_enforcer.patch deleted file mode 100644 index d9905cbce..000000000 --- a/4_7_enforcer.patch +++ /dev/null @@ -1,32 +0,0 @@ -Index: parent/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- parent/pom.xml (date 1490103087000) -+++ parent/pom.xml (revision ) -@@ -38,6 +38,24 @@ - -Dfile.encoding=UTF-8 - - -+ -+ org.apache.maven.plugins -+ maven-enforcer-plugin -+ 1.4.1 -+ -+ -+ enforce -+ -+ -+ -+ -+ -+ -+ enforce -+ -+ -+ -+ -
-
- From 5a961f7c2900d84e38ea7f0cdb691cb1336563d4 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 22:23:24 +0200 Subject: [PATCH 38/46] 4 7 enforcer --- mvn | 0 parent/pom.xml | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 mvn diff --git a/mvn b/mvn new file mode 100644 index 000000000..e69de29bb diff --git a/parent/pom.xml b/parent/pom.xml index 21d6c9c02..c181a64ce 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -14,7 +14,11 @@ 1.8 UTF-8 UTF-8 + + 1.2.3 + 1.7.25 + /apps/masterjava/config/ false @@ -38,7 +42,37 @@ -Dfile.encoding=UTF-8 + + org.apache.maven.plugins + maven-enforcer-plugin + 1.4.1 + + + enforce + + + + + + + enforce + + + +
+ + + + ${masterjava.config} + + logback-test.xml + + + + src/test/resources + +
@@ -53,6 +87,20 @@ 0.6.7
+ + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + runtime + + + + ch.qos.logback + logback-classic + ${logback.version} + + junit From dcb9ce2be01fafb08e1c2eaf9522e05fc2809803 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 22:23:35 +0200 Subject: [PATCH 39/46] 4 8 logging --- config_templates/logback-test.xml | 20 ++++++++++++++++ config_templates/logback.xml | 40 +++++++++++++++++++++++++++++++ parent-web/pom.xml | 13 ++++++++++ web/common-web/pom.xml | 6 +++++ 4 files changed, 79 insertions(+) create mode 100644 config_templates/logback-test.xml create mode 100644 config_templates/logback.xml diff --git a/config_templates/logback-test.xml b/config_templates/logback-test.xml new file mode 100644 index 000000000..b6815ab8d --- /dev/null +++ b/config_templates/logback-test.xml @@ -0,0 +1,20 @@ + + + + true + + + + + UTF-8 + %-5level %logger{0} [%file:%line] %msg%n + + + + + + + + + + \ No newline at end of file diff --git a/config_templates/logback.xml b/config_templates/logback.xml new file mode 100644 index 000000000..352ee14a0 --- /dev/null +++ b/config_templates/logback.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + ${LOG_DIR}/${project.build.finalName}.log + + UTF-8 + %d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{0} [%file:%line] - %msg%n + + + + ${LOG_DIR}/archived/${project.build.finalName}.%d{yyyy-MM-dd}.%i.log + + + 5MB + + + + + + + UTF-8 + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} [%file:%line] - %msg%n + + + + + + + + + + diff --git a/parent-web/pom.xml b/parent-web/pom.xml index b902f721f..572e97220 100644 --- a/parent-web/pom.xml +++ b/parent-web/pom.xml @@ -27,6 +27,19 @@ + + + + ${masterjava.config} + true + + logback.xml + + + + src/main/resources + + diff --git a/web/common-web/pom.xml b/web/common-web/pom.xml index 98ba46590..37ca1f642 100644 --- a/web/common-web/pom.xml +++ b/web/common-web/pom.xml @@ -32,6 +32,12 @@ org.thymeleaf thymeleaf 3.0.8.RELEASE + + + org.slf4j + slf4j-api + + \ No newline at end of file From e69b943dd1e912dd0d89a8c6961e8bf70c7357db Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 22:24:07 +0200 Subject: [PATCH 40/46] 4 8 logging --- web/upload/pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/upload/pom.xml b/web/upload/pom.xml index 4fb7cc050..9dac14170 100644 --- a/web/upload/pom.xml +++ b/web/upload/pom.xml @@ -25,12 +25,12 @@ com.j2html j2html 1.2.0 - - - com.google.guava - guava - - + + + + + + ${project.groupId} From 245d0eb9187b2ddc7140c7166042590bbfe8dafe Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 23:11:59 +0200 Subject: [PATCH 41/46] 4 8 logging --- parent/pom.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/parent/pom.xml b/parent/pom.xml index c181a64ce..e908f5fb5 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -101,6 +101,20 @@ ${logback.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + runtime + + + + ch.qos.logback + logback-classic + ${logback.version} + + junit From 4b2355e523f19c18a1299bdd0e13b8c8ce8be8e7 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 23:17:52 +0200 Subject: [PATCH 42/46] 4 8 logging --- 4_8_logging.patch | 184 ------------------------------ config_templates/logback-test.xml | 20 ---- config_templates/logback.xml | 40 ------- 3 files changed, 244 deletions(-) delete mode 100644 4_8_logging.patch delete mode 100644 config_templates/logback-test.xml delete mode 100644 config_templates/logback.xml diff --git a/4_8_logging.patch b/4_8_logging.patch deleted file mode 100644 index 8ab045325..000000000 --- a/4_8_logging.patch +++ /dev/null @@ -1,184 +0,0 @@ -Index: config_templates/logback.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- config_templates/logback.xml (revision ) -+++ config_templates/logback.xml (revision ) -@@ -0,0 +1,40 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ ${LOG_DIR}/${project.build.finalName}.log -+ -+ UTF-8 -+ %d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{0} [%file:%line] - %msg%n -+ -+ -+ -+ ${LOG_DIR}/archived/${project.build.finalName}.%d{yyyy-MM-dd}.%i.log -+ -+ -+ 5MB -+ -+ -+ -+ -+ -+ -+ UTF-8 -+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} [%file:%line] - %msg%n -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -Index: config_templates/logback-test.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- config_templates/logback-test.xml (revision ) -+++ config_templates/logback-test.xml (revision ) -@@ -0,0 +1,20 @@ -+ -+ -+ -+ true -+ -+ -+ -+ -+ UTF-8 -+ %-5level %logger{0} [%file:%line] %msg%n -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -\ No newline at end of file -Index: web/common-web/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- web/common-web/pom.xml (date 1509893613000) -+++ web/common-web/pom.xml (revision ) -@@ -32,6 +32,12 @@ - org.thymeleaf - thymeleaf - 3.0.8.RELEASE -+ -+ -+ org.slf4j -+ slf4j-api -+ -+ - - - -\ No newline at end of file -Index: parent/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- parent/pom.xml (date 1509893613000) -+++ parent/pom.xml (revision ) -@@ -14,7 +14,11 @@ - 1.8 - UTF-8 - UTF-8 -+ -+ 1.2.3 -+ 1.7.25 - -+ /apps/masterjava/config/ - false - - -@@ -57,6 +61,18 @@ - - - -+ -+ -+ -+ ${masterjava.config} -+ -+ logback-test.xml -+ -+ -+ -+ src/test/resources -+ -+ - - - -@@ -70,6 +86,20 @@ - streamex - 0.6.6 - -+ -+ -+ -+ org.slf4j -+ jcl-over-slf4j -+ ${slf4j.version} -+ runtime -+ -+ -+ -+ ch.qos.logback -+ logback-classic -+ ${logback.version} -+ - - - -Index: parent-web/pom.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- parent-web/pom.xml (date 1509893613000) -+++ parent-web/pom.xml (revision ) -@@ -27,6 +27,19 @@ - - - -+ -+ -+ -+ ${masterjava.config} -+ true -+ -+ logback.xml -+ -+ -+ -+ src/main/resources -+ -+ - - - diff --git a/config_templates/logback-test.xml b/config_templates/logback-test.xml deleted file mode 100644 index b6815ab8d..000000000 --- a/config_templates/logback-test.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - true - - - - - UTF-8 - %-5level %logger{0} [%file:%line] %msg%n - - - - - - - - - - \ No newline at end of file diff --git a/config_templates/logback.xml b/config_templates/logback.xml deleted file mode 100644 index 352ee14a0..000000000 --- a/config_templates/logback.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - ${LOG_DIR}/${project.build.finalName}.log - - UTF-8 - %d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{0} [%file:%line] - %msg%n - - - - ${LOG_DIR}/archived/${project.build.finalName}.%d{yyyy-MM-dd}.%i.log - - - 5MB - - - - - - - UTF-8 - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} [%file:%line] - %msg%n - - - - - - - - - - From d26382e66e95c59e528ad3d412bcdee418e91632 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 23:36:27 +0200 Subject: [PATCH 43/46] 4 8 logging --- parent/pom.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/parent/pom.xml b/parent/pom.xml index e908f5fb5..a4485a921 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -115,6 +115,20 @@ ${logback.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + runtime + + + + ch.qos.logback + logback-classic + ${logback.version} + + junit From fe2c6c5a1a531c422c4e3e83566774d0035ed563 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 23:36:38 +0200 Subject: [PATCH 44/46] 4 9 context --- config_templates/context.xml | 49 ++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 config_templates/context.xml diff --git a/config_templates/context.xml b/config_templates/context.xml new file mode 100644 index 000000000..40bb8aa0c --- /dev/null +++ b/config_templates/context.xml @@ -0,0 +1,49 @@ + + + + + + + + WEB-INF/web.xml + ${catalina.base}/conf/web.xml + + + + + + + + + From dcfc741ea655db813cbc50379c5a9e8bfa7220a3 Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 23:51:52 +0200 Subject: [PATCH 45/46] 4 10 persist --- config_templates/sql/initDB.sql | 15 ++++++ persist/pom.xml | 46 ++++++++++++++++ .../masterjava/persist/DBIProvider.java | 52 +++++++++++++++++++ .../masterjava/persist/dao/AbstractDao.java | 5 ++ .../masterjava/persist/dao/UserDao.java | 37 +++++++++++++ .../masterjava/persist/model/BaseEntity.java | 37 +++++++++++++ .../masterjava/persist}/model/User.java | 43 ++++++++++----- .../masterjava/persist}/model/UserFlag.java | 2 +- .../masterjava/persist/DBITestProvider.java | 20 +++++++ .../masterjava/persist/UserTestData.java | 37 +++++++++++++ .../persist/dao/AbstractDaoTest.java | 16 ++++++ .../masterjava/persist/dao/UserDaoTest.java | 35 +++++++++++++ pom.xml | 1 + web/upload/pom.xml | 5 ++ .../masterjava/upload/UploadServlet.java | 2 +- .../masterjava/upload/UserProcessor.java | 4 +- 16 files changed, 341 insertions(+), 16 deletions(-) create mode 100644 config_templates/sql/initDB.sql create mode 100644 persist/pom.xml create mode 100644 persist/src/main/java/ru/javaops/masterjava/persist/DBIProvider.java create mode 100644 persist/src/main/java/ru/javaops/masterjava/persist/dao/AbstractDao.java create mode 100644 persist/src/main/java/ru/javaops/masterjava/persist/dao/UserDao.java create mode 100644 persist/src/main/java/ru/javaops/masterjava/persist/model/BaseEntity.java rename {web/upload/src/main/java/ru/javaops/masterjava => persist/src/main/java/ru/javaops/masterjava/persist}/model/User.java (69%) rename {web/upload/src/main/java/ru/javaops/masterjava => persist/src/main/java/ru/javaops/masterjava/persist}/model/UserFlag.java (68%) create mode 100644 persist/src/test/java/ru/javaops/masterjava/persist/DBITestProvider.java create mode 100644 persist/src/test/java/ru/javaops/masterjava/persist/UserTestData.java create mode 100644 persist/src/test/java/ru/javaops/masterjava/persist/dao/AbstractDaoTest.java create mode 100644 persist/src/test/java/ru/javaops/masterjava/persist/dao/UserDaoTest.java diff --git a/config_templates/sql/initDB.sql b/config_templates/sql/initDB.sql new file mode 100644 index 000000000..888ba8141 --- /dev/null +++ b/config_templates/sql/initDB.sql @@ -0,0 +1,15 @@ +DROP TABLE IF EXISTS users; +DROP SEQUENCE IF EXISTS user_seq; +DROP TYPE IF EXISTS user_flag; + +CREATE TYPE user_flag AS ENUM ('active', 'deleted', 'superuser'); + +CREATE SEQUENCE user_seq START 100000; + +CREATE TABLE users ( + id INTEGER PRIMARY KEY DEFAULT nextval('user_seq'), + full_name TEXT NOT NULL, + email TEXT NOT NULL, + flag user_flag NOT NULL +); + diff --git a/persist/pom.xml b/persist/pom.xml new file mode 100644 index 000000000..6efb20ca3 --- /dev/null +++ b/persist/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + + ru.javaops + parent + ../parent/pom.xml + 1.0-SNAPSHOT + + + persist + 1.0-SNAPSHOT + Persist + + + + ${project.groupId} + common + ${project.version} + + + org.jdbi + jdbi + 2.78 + + + com.bertoncelj.jdbi.entitymapper + jdbi-entity-mapper + 1.0.0 + + + org.jdbi + jdbi + + + + + org.postgresql + postgresql + 42.1.4 + + + \ No newline at end of file diff --git a/persist/src/main/java/ru/javaops/masterjava/persist/DBIProvider.java b/persist/src/main/java/ru/javaops/masterjava/persist/DBIProvider.java new file mode 100644 index 000000000..7cfaab77f --- /dev/null +++ b/persist/src/main/java/ru/javaops/masterjava/persist/DBIProvider.java @@ -0,0 +1,52 @@ +package ru.javaops.masterjava.persist; + +import org.skife.jdbi.v2.DBI; +import org.skife.jdbi.v2.logging.SLF4JLog; +import org.skife.jdbi.v2.tweak.ConnectionFactory; +import org.slf4j.Logger; +import ru.javaops.masterjava.persist.dao.AbstractDao; + +import javax.naming.InitialContext; +import javax.sql.DataSource; + +import static org.slf4j.LoggerFactory.getLogger; + +public class DBIProvider { + private static final Logger log = getLogger(DBIProvider.class); + + private volatile static ConnectionFactory connectionFactory = null; + + private static class DBIHolder { + static final DBI jDBI; + + static { + final DBI dbi; + if (connectionFactory != null) { + log.info("Init jDBI with connectionFactory"); + dbi = new DBI(connectionFactory); + } else { + try { + log.info("Init jDBI with JNDI"); + InitialContext ctx = new InitialContext(); + dbi = new DBI((DataSource) ctx.lookup("java:/comp/env/jdbc/masterjava")); + } catch (Exception ex) { + throw new IllegalStateException("PostgreSQL initialization failed", ex); + } + } + jDBI = dbi; + jDBI.setSQLLog(new SLF4JLog()); + } + } + + public static void init(ConnectionFactory connectionFactory) { + DBIProvider.connectionFactory = connectionFactory; + } + + public static DBI getDBI() { + return DBIHolder.jDBI; + } + + public static T getDao(Class daoClass) { + return DBIHolder.jDBI.onDemand(daoClass); + } +} diff --git a/persist/src/main/java/ru/javaops/masterjava/persist/dao/AbstractDao.java b/persist/src/main/java/ru/javaops/masterjava/persist/dao/AbstractDao.java new file mode 100644 index 000000000..8b3ee1099 --- /dev/null +++ b/persist/src/main/java/ru/javaops/masterjava/persist/dao/AbstractDao.java @@ -0,0 +1,5 @@ +package ru.javaops.masterjava.persist.dao; + +public interface AbstractDao { + void clean(); +} diff --git a/persist/src/main/java/ru/javaops/masterjava/persist/dao/UserDao.java b/persist/src/main/java/ru/javaops/masterjava/persist/dao/UserDao.java new file mode 100644 index 000000000..e0230cccf --- /dev/null +++ b/persist/src/main/java/ru/javaops/masterjava/persist/dao/UserDao.java @@ -0,0 +1,37 @@ +package ru.javaops.masterjava.persist.dao; + +import com.bertoncelj.jdbi.entitymapper.EntityMapperFactory; +import org.skife.jdbi.v2.sqlobject.*; +import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapperFactory; +import ru.javaops.masterjava.persist.model.User; + +import java.util.List; + +@RegisterMapperFactory(EntityMapperFactory.class) +public abstract class UserDao implements AbstractDao { + + public User insert(User user) { + if (user.isNew()) { + int id = insertGeneratedId(user); + user.setId(id); + } else { + insertWitId(user); + } + return user; + } + + @SqlUpdate("INSERT INTO users (full_name, email, flag) VALUES (:fullName, :email, CAST(:flag AS user_flag)) ") + @GetGeneratedKeys + abstract int insertGeneratedId(@BindBean User user); + + @SqlUpdate("INSERT INTO users (id, full_name, email, flag) VALUES (:id, :fullName, :email, CAST(:flag AS user_flag)) ") + abstract void insertWitId(@BindBean User user); + + @SqlQuery("SELECT * FROM users ORDER BY full_name, email LIMIT :it") + public abstract List getWithLimit(@Bind int limit); + + // http://stackoverflow.com/questions/13223820/postgresql-delete-all-content + @SqlUpdate("TRUNCATE users") + @Override + public abstract void clean(); +} diff --git a/persist/src/main/java/ru/javaops/masterjava/persist/model/BaseEntity.java b/persist/src/main/java/ru/javaops/masterjava/persist/model/BaseEntity.java new file mode 100644 index 000000000..415d3d037 --- /dev/null +++ b/persist/src/main/java/ru/javaops/masterjava/persist/model/BaseEntity.java @@ -0,0 +1,37 @@ +package ru.javaops.masterjava.persist.model; + +abstract public class BaseEntity { + protected BaseEntity() { + } + + protected BaseEntity(Integer id) { + this.id = id; + } + + protected Integer id; + + public Integer getId() { + return id; + } + + protected void setId(Integer id) { + this.id = id; + } + + public boolean isNew() { + return id == null; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BaseEntity baseEntity = (BaseEntity) o; + return id != null && id.equals(baseEntity.id); + } + + @Override + public int hashCode() { + return id == null ? 0 : id; + } +} diff --git a/web/upload/src/main/java/ru/javaops/masterjava/model/User.java b/persist/src/main/java/ru/javaops/masterjava/persist/model/User.java similarity index 69% rename from web/upload/src/main/java/ru/javaops/masterjava/model/User.java rename to persist/src/main/java/ru/javaops/masterjava/persist/model/User.java index d7c3f8cd3..f4445cb50 100644 --- a/web/upload/src/main/java/ru/javaops/masterjava/model/User.java +++ b/persist/src/main/java/ru/javaops/masterjava/persist/model/User.java @@ -1,28 +1,31 @@ -package ru.javaops.masterjava.model; +package ru.javaops.masterjava.persist.model; + +import com.bertoncelj.jdbi.entitymapper.Column; import java.util.Objects; -public class User { - private final Integer id; - private final String fullName; - private final String email; - private final UserFlag flag; +public class User extends BaseEntity { + @Column("full_name") + private String fullName; + + private String email; + + private UserFlag flag; + + public User() { + } public User(String fullName, String email, UserFlag flag) { this(null, fullName, email, flag); } public User(Integer id, String fullName, String email, UserFlag flag) { - this.id = id; + super(id); this.fullName = fullName; this.email = email; this.flag = flag; } - public Integer getId() { - return id; - } - public String getFullName() { return fullName; } @@ -35,6 +38,22 @@ public UserFlag getFlag() { return flag; } + public void setId(Integer id) { + this.id = id; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public void setEmail(String email) { + this.email = email; + } + + public void setFlag(UserFlag flag) { + this.flag = flag; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -60,4 +79,4 @@ public String toString() { ", flag=" + flag + ')'; } -} +} \ No newline at end of file diff --git a/web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java b/persist/src/main/java/ru/javaops/masterjava/persist/model/UserFlag.java similarity index 68% rename from web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java rename to persist/src/main/java/ru/javaops/masterjava/persist/model/UserFlag.java index 603626ae1..bc2f69183 100644 --- a/web/upload/src/main/java/ru/javaops/masterjava/model/UserFlag.java +++ b/persist/src/main/java/ru/javaops/masterjava/persist/model/UserFlag.java @@ -1,4 +1,4 @@ -package ru.javaops.masterjava.model; +package ru.javaops.masterjava.persist.model; /** * gkislin diff --git a/persist/src/test/java/ru/javaops/masterjava/persist/DBITestProvider.java b/persist/src/test/java/ru/javaops/masterjava/persist/DBITestProvider.java new file mode 100644 index 000000000..2b2f1d71b --- /dev/null +++ b/persist/src/test/java/ru/javaops/masterjava/persist/DBITestProvider.java @@ -0,0 +1,20 @@ +package ru.javaops.masterjava.persist; + +import java.sql.DriverManager; + +public class DBITestProvider { + public static void initDBI() { + initDBI("jdbc:postgresql://localhost:5432/masterjava", "user", "password"); + } + + public static void initDBI(String dbUrl, String dbUser, String dbPassword) { + DBIProvider.init(() -> { + try { + Class.forName("org.postgresql.Driver"); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("PostgreSQL driver not found", e); + } + return DriverManager.getConnection(dbUrl, dbUser, dbPassword); + }); + } +} \ No newline at end of file diff --git a/persist/src/test/java/ru/javaops/masterjava/persist/UserTestData.java b/persist/src/test/java/ru/javaops/masterjava/persist/UserTestData.java new file mode 100644 index 000000000..7c13c0499 --- /dev/null +++ b/persist/src/test/java/ru/javaops/masterjava/persist/UserTestData.java @@ -0,0 +1,37 @@ +package ru.javaops.masterjava.persist; + +import com.google.common.collect.ImmutableList; +import ru.javaops.masterjava.persist.dao.UserDao; +import ru.javaops.masterjava.persist.model.User; +import ru.javaops.masterjava.persist.model.UserFlag; + +import java.util.List; + +public class UserTestData { + public static User ADMIN; + public static User DELETED; + public static User FULL_NAME; + public static User USER1; + public static User USER2; + public static User USER3; + public static List FIST5_USERS; + + public static void init() { + ADMIN = new User("Admin", "admin@javaops.ru", UserFlag.superuser); + DELETED = new User("Deleted", "deleted@yandex.ru", UserFlag.deleted); + FULL_NAME = new User("Full Name", "gmail@gmail.com", UserFlag.active); + USER1 = new User("User1", "user1@gmail.com", UserFlag.active); + USER2 = new User("User2", "user2@yandex.ru", UserFlag.active); + USER3 = new User("User3", "user3@yandex.ru", UserFlag.active); + FIST5_USERS = ImmutableList.of(ADMIN, DELETED, FULL_NAME, USER1, USER2); + } + + public static void setUp() { + UserDao dao = DBIProvider.getDao(UserDao.class); + dao.clean(); + DBIProvider.getDBI().useTransaction((conn, status) -> { + FIST5_USERS.forEach(dao::insert); + dao.insert(USER3); + }); + } +} diff --git a/persist/src/test/java/ru/javaops/masterjava/persist/dao/AbstractDaoTest.java b/persist/src/test/java/ru/javaops/masterjava/persist/dao/AbstractDaoTest.java new file mode 100644 index 000000000..a65302fdd --- /dev/null +++ b/persist/src/test/java/ru/javaops/masterjava/persist/dao/AbstractDaoTest.java @@ -0,0 +1,16 @@ +package ru.javaops.masterjava.persist.dao; + +import ru.javaops.masterjava.persist.DBIProvider; +import ru.javaops.masterjava.persist.DBITestProvider; + +public abstract class AbstractDaoTest { + static { + DBITestProvider.initDBI(); + } + + protected DAO dao; + + protected AbstractDaoTest(Class daoClass) { + this.dao = DBIProvider.getDao(daoClass); + } +} diff --git a/persist/src/test/java/ru/javaops/masterjava/persist/dao/UserDaoTest.java b/persist/src/test/java/ru/javaops/masterjava/persist/dao/UserDaoTest.java new file mode 100644 index 000000000..b833a0577 --- /dev/null +++ b/persist/src/test/java/ru/javaops/masterjava/persist/dao/UserDaoTest.java @@ -0,0 +1,35 @@ +package ru.javaops.masterjava.persist.dao; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import ru.javaops.masterjava.persist.UserTestData; +import ru.javaops.masterjava.persist.model.User; + +import java.util.List; + +import static ru.javaops.masterjava.persist.UserTestData.FIST5_USERS; + +public class UserDaoTest extends AbstractDaoTest { + + public UserDaoTest() { + super(UserDao.class); + } + + @BeforeClass + public static void init() throws Exception { + UserTestData.init(); + } + + @Before + public void setUp() throws Exception { + UserTestData.setUp(); + } + + @Test + public void getWithLimit() { + List users = dao.getWithLimit(5); + Assert.assertEquals(FIST5_USERS, users); + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 43674e646..c7e9c65d2 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ parent-web common + persist test web diff --git a/web/upload/pom.xml b/web/upload/pom.xml index 9dac14170..99acbac12 100644 --- a/web/upload/pom.xml +++ b/web/upload/pom.xml @@ -21,6 +21,11 @@ + + ${project.groupId} + persist + ${project.version} + com.j2html j2html diff --git a/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java b/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java index 21c73a8e5..1652f4f45 100644 --- a/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java +++ b/web/upload/src/main/java/ru/javaops/masterjava/upload/UploadServlet.java @@ -1,7 +1,7 @@ package ru.javaops.masterjava.upload; import org.thymeleaf.context.WebContext; -import ru.javaops.masterjava.model.User; +import ru.javaops.masterjava.persist.model.User; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; diff --git a/web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java b/web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java index f8c574bf8..5cb3deb56 100644 --- a/web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java +++ b/web/upload/src/main/java/ru/javaops/masterjava/upload/UserProcessor.java @@ -1,7 +1,7 @@ package ru.javaops.masterjava.upload; -import ru.javaops.masterjava.model.User; -import ru.javaops.masterjava.model.UserFlag; +import ru.javaops.masterjava.persist.model.User; +import ru.javaops.masterjava.persist.model.UserFlag; import ru.javaops.masterjava.xml.schema.ObjectFactory; import ru.javaops.masterjava.xml.util.JaxbParser; import ru.javaops.masterjava.xml.util.JaxbUnmarshaller; From cbcd4753fa45069394f77883e448e2644644af7b Mon Sep 17 00:00:00 2001 From: IHOR PETROV Date: Wed, 30 Jan 2019 23:51:57 +0200 Subject: [PATCH 46/46] 4 8 logging --- 4_9_context.patch | 57 ----------------------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 4_9_context.patch diff --git a/4_9_context.patch b/4_9_context.patch deleted file mode 100644 index 09b29d41f..000000000 --- a/4_9_context.patch +++ /dev/null @@ -1,57 +0,0 @@ -Index: config_templates/context.xml -IDEA additional info: -Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP -<+>UTF-8 -=================================================================== ---- config_templates/context.xml (revision ) -+++ config_templates/context.xml (revision ) -@@ -0,0 +1,49 @@ -+ -+ -+ -+ -+ -+ -+ -+ WEB-INF/web.xml -+ ${catalina.base}/conf/web.xml -+ -+ -+ -+ -+ -+ -+ -+ -+