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/13] 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/13] 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 8d6415b915523d6ccf874fa9aeb56bf7b3d6c5b7 Mon Sep 17 00:00:00 2001 From: Def Neo Date: Sat, 17 Mar 2018 10:23:47 +0300 Subject: [PATCH 03/13] aply patches lesson 2 --- pom.xml | 67 ++++- .../javaops/masterjava/matrix/MainMatrix.java | 8 +- .../masterjava/matrix/MatrixBenchmark.java | 85 +++++++ .../javaops/masterjava/matrix/MatrixUtil.java | 124 ++++++++-- .../masterjava/service/MailService.java | 72 +++++- .../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 ++++++++++++ .../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 ++++ .../xml/util/StaxStreamProcessor.java | 56 +++++ .../masterjava/xml/util/XPathProcessor.java | 58 +++++ .../masterjava/xml/util/XsltProcessor.java | 43 ++++ src/main/resources/cities.xsl | 9 + src/main/resources/payload.xsd | 56 +++++ .../masterjava/xml/util/JaxbParserTest.java | 40 +++ .../xml/util/StaxStreamProcessorTest.java | 36 +++ .../xml/util/XPathProcessorTest.java | 26 ++ .../xml/util/XsltProcessorTest.java | 18 ++ src/test/resources/city.xml | 4 + src/test/resources/payload.xml | 23 ++ 25 files changed, 1526 insertions(+), 24 deletions(-) create mode 100644 src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java 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/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/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java create mode 100644 src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java 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/main/resources/payload.xsd create mode 100644 src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java create mode 100644 src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java create mode 100644 src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java create mode 100644 src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java create mode 100644 src/test/resources/city.xml create mode 100644 src/test/resources/payload.xml diff --git a/pom.xml b/pom.xml index 39e811e08..884be4839 100644 --- a/pom.xml +++ b/pom.xml @@ -24,16 +24,81 @@ org.apache.maven.plugins maven-compiler-plugin - 3.1 + 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 + diff --git a/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java b/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java index ec1c8a691..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; @@ -24,13 +20,13 @@ 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; 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/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 diff --git a/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java index 80a344ac2..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; @@ -58,4 +154,4 @@ public static boolean compare(int[][] matrixA, int[][] matrixB) { } return true; } -} +} \ No newline at end of file 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 { 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/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/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/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/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/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/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/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 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 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)); + } + } +} 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 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 0451473b9ee7a6d6abe0961783e0c535c5dd15e6 Mon Sep 17 00:00:00 2001 From: rgaponov Date: Sun, 15 Apr 2018 11:30:25 +0300 Subject: [PATCH 04/13] 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 229728fc7de78087164dfbfbfc09244ee37252c4 Mon Sep 17 00:00:00 2001 From: rgaponov Date: Sun, 15 Apr 2018 11:45:30 +0300 Subject: [PATCH 05/13] add gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ad02a2599..22c29b21f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ out target *.iml -log \ No newline at end of file +log +/patches/ From 76f98f2ee90927138465ca4f85c0b6567a695cee Mon Sep 17 00:00:00 2001 From: rgaponov Date: Sun, 15 Apr 2018 11:50:12 +0300 Subject: [PATCH 06/13] add JAXB --- src/main/java/ru/javaops/masterjava/Main.java | 14 -- .../java/ru/javaops/masterjava/MainXml.java | 129 ++++++++++++++++++ 2 files changed, 129 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..5f5f55b99 --- /dev/null +++ b/src/test/java/ru/javaops/masterjava/MainXml.java @@ -0,0 +1,129 @@ +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 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); + } + + 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.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( + 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(); + } +} From 7b79ac1222466ab3c0f99d2331e8e7c4642f12db Mon Sep 17 00:00:00 2001 From: rgaponov Date: Sun, 15 Apr 2018 11:53:49 +0300 Subject: [PATCH 07/13] Add StaxStreamProcessor --- pom.xml | 13 +++++++++++++ .../xml/util/StaxStreamProcessor.java | 17 ++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 884be4839..880943475 100644 --- a/pom.xml +++ b/pom.xml @@ -93,6 +93,19 @@ guava 21.0 + + one.util + streamex + RELEASE + + + + com.j2html + j2html + RELEASE + + + junit junit 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..8ad82c582 100644 --- a/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java +++ b/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java @@ -20,15 +20,26 @@ public XMLStreamReader getReader() { } 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 { From f6b2479a61f412146e132ba1af868e36b1dfea45 Mon Sep 17 00:00:00 2001 From: rgaponov Date: Sun, 15 Apr 2018 12:14:18 +0300 Subject: [PATCH 08/13] add out directory --- src/test/java/ru/javaops/masterjava/MainXml.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/ru/javaops/masterjava/MainXml.java b/src/test/java/ru/javaops/masterjava/MainXml.java index 5f5f55b99..0b18e644b 100644 --- a/src/test/java/ru/javaops/masterjava/MainXml.java +++ b/src/test/java/ru/javaops/masterjava/MainXml.java @@ -29,7 +29,7 @@ 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) { + if (args.length != 2) { System.out.println("Required argument: projectName"); System.exit(1); } From a22c5f5115c69344af69baa2f3233ff5edd0e675 Mon Sep 17 00:00:00 2001 From: rgaponov Date: Sun, 15 Apr 2018 12:37:36 +0300 Subject: [PATCH 09/13] add StaxProcessor --- .../masterjava/xml/util/JaxbParser.java | 5 +++ .../masterjava/xml/util/JaxbUnmarshaller.java | 7 +++- .../xml/util/StaxStreamProcessor.java | 38 ++++++++++++------- .../java/ru/javaops/masterjava/MainXml.java | 16 +++----- 4 files changed, 42 insertions(+), 24 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 8ad82c582..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,31 +15,43 @@ public StaxStreamProcessor(InputStream is) throws XMLStreamException { reader = FACTORY.createXMLStreamReader(is); } - public XMLStreamReader getReader() { - return reader; + 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; } - public boolean doUntil(int stopEvent, String value) throws XMLStreamException { - return doUntilAny(stopEvent, value) != null; + 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 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 { diff --git a/src/test/java/ru/javaops/masterjava/MainXml.java b/src/test/java/ru/javaops/masterjava/MainXml.java index 0b18e644b..fb57c48a3 100644 --- a/src/test/java/ru/javaops/masterjava/MainXml.java +++ b/src/test/java/ru/javaops/masterjava/MainXml.java @@ -47,6 +47,7 @@ public static void main(String[] args) throws Exception { } System.out.println(); + System.out.println("byStax"); users = processByStax(projectName, payloadUrl); users.forEach(System.out::println); } @@ -80,16 +81,12 @@ private static Set processByStax(String projectName, URL payloadUrl) throw // 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 +96,11 @@ private static Set processByStax(String projectName, URL payloadUrl) throw // 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); } } From 071c4e7009f2d7d1cc2f38d91b696d9a44086b14 Mon Sep 17 00:00:00 2001 From: rgaponov Date: Sun, 15 Apr 2018 12:49:50 +0300 Subject: [PATCH 10/13] Add xsltParser --- .../masterjava/xml/util/XsltProcessor.java | 4 ++ src/main/resources/groups.xsl | 37 +++++++++++++++++++ .../java/ru/javaops/masterjava/MainXml.java | 16 ++++++++ 3 files changed, 57 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 diff --git a/src/test/java/ru/javaops/masterjava/MainXml.java b/src/test/java/ru/javaops/masterjava/MainXml.java index fb57c48a3..d8ea43ac6 100644 --- a/src/test/java/ru/javaops/masterjava/MainXml.java +++ b/src/test/java/ru/javaops/masterjava/MainXml.java @@ -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 javax.xml.stream.events.XMLEvent; import java.io.InputStream; @@ -50,6 +51,12 @@ public static void main(String[] args) throws Exception { System.out.println("byStax"); users = processByStax(projectName, payloadUrl); users.forEach(System.out::println); + + System.out.println("by xslt"); + 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 { @@ -122,4 +129,13 @@ private static String toHtml(Set users, String projectName) { 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 76bf9843636ef969d419498a0699ed776698cddf Mon Sep 17 00:00:00 2001 From: rgaponov Date: Sun, 15 Apr 2018 16:46:52 +0300 Subject: [PATCH 11/13] add multimodule project --- common/pom.xml | 21 +++++++++ parent/pom.xml | 69 ++++++++++++++++++++++++++++ pom.xml | 120 +++++-------------------------------------------- upload/pom.xml | 39 ++++++++++++++++ 4 files changed, 140 insertions(+), 109 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 880943475..0085819cf 100644 --- a/pom.xml +++ b/pom.xml @@ -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 + + 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 ec13ecbb5ee77269ff0c0e9ba157811e1866d763 Mon Sep 17 00:00:00 2001 From: rgaponov Date: Sun, 15 Apr 2018 20:47:27 +0300 Subject: [PATCH 12/13] add multimaven build --- {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 (97%) 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 97% rename from src/test/java/ru/javaops/masterjava/MainXml.java rename to web/upload/src/test/java/ru/javaops/masterjava/MainXml.java index d8ea43ac6..bf696a6e4 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.*; @@ -75,9 +74,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 6f02296ceb6da901f8d614a810d067affff7d21c Mon Sep 17 00:00:00 2001 From: rgaponov Date: Sun, 15 Apr 2018 22:12:59 +0300 Subject: [PATCH 13/13] apply pom structure patch --- .../src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java | 0 .../main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java | 0 .../src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java | 0 .../src/main/java/ru/javaops/masterjava/xml/schema/CityType.java | 0 .../src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java | 0 .../src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java | 0 .../main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java | 0 .../src/main/java/ru/javaops/masterjava/xml/schema/Payload.java | 0 .../src/main/java/ru/javaops/masterjava/xml/schema/Project.java | 0 .../src/main/java/ru/javaops/masterjava/xml/schema/User.java | 0 .../main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java | 0 .../src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java | 0 .../java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java | 0 .../src/main/java/ru/javaops/masterjava/xml/util/Schemas.java | 0 .../java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java | 0 .../main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java | 0 .../main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java | 0 .../{ => web/upload/web/upload}/src/main/resources/cities.xsl | 0 .../{ => web/upload/web/upload}/src/main/resources/groups.xsl | 0 .../{ => web/upload/web/upload}/src/main/resources/payload.xsd | 0 .../web/upload}/src/test/java/ru/javaops/masterjava/MainXml.java | 0 .../test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java | 0 .../ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java | 0 .../java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java | 0 .../java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java | 0 .../{ => web/upload/web/upload}/src/test/resources/city.xml | 0 .../{ => web/upload/web/upload}/src/test/resources/payload.xml | 0 27 files changed, 0 insertions(+), 0 deletions(-) rename test/{ => test/test}/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java (100%) rename test/{ => test/test}/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java (100%) rename test/{ => test/test}/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/schema/Project.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/schema/User.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java (100%) rename web/upload/{ => web/upload/web/upload}/src/main/resources/cities.xsl (100%) rename web/upload/{ => web/upload/web/upload}/src/main/resources/groups.xsl (100%) rename web/upload/{ => web/upload/web/upload}/src/main/resources/payload.xsd (100%) rename web/upload/{ => web/upload/web/upload}/src/test/java/ru/javaops/masterjava/MainXml.java (100%) rename web/upload/{ => web/upload/web/upload}/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java (100%) rename web/upload/{ => web/upload/web/upload}/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java (100%) rename web/upload/{ => web/upload/web/upload}/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java (100%) rename web/upload/{ => web/upload/web/upload}/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java (100%) rename web/upload/{ => web/upload/web/upload}/src/test/resources/city.xml (100%) rename web/upload/{ => web/upload/web/upload}/src/test/resources/payload.xml (100%) diff --git a/test/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java b/test/test/test/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java similarity index 100% rename from test/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java rename to test/test/test/src/main/java/ru/javaops/masterjava/matrix/MainMatrix.java diff --git a/test/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java b/test/test/test/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java similarity index 100% rename from test/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java rename to test/test/test/src/main/java/ru/javaops/masterjava/matrix/MatrixBenchmark.java diff --git a/test/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java b/test/test/test/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java similarity index 100% rename from test/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java rename to test/test/test/src/main/java/ru/javaops/masterjava/matrix/MatrixUtil.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/CityType.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/FlagType.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/GroupType.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/ObjectFactory.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Payload.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Project.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Project.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Project.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/Project.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/User.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/User.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/schema/User.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/schema/User.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbMarshaller.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbParser.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/JaxbUnmarshaller.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/Schemas.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/StaxStreamProcessor.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/XPathProcessor.java diff --git a/web/upload/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java b/web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java similarity index 100% rename from web/upload/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java rename to web/upload/web/upload/web/upload/src/main/java/ru/javaops/masterjava/xml/util/XsltProcessor.java diff --git a/web/upload/src/main/resources/cities.xsl b/web/upload/web/upload/web/upload/src/main/resources/cities.xsl similarity index 100% rename from web/upload/src/main/resources/cities.xsl rename to web/upload/web/upload/web/upload/src/main/resources/cities.xsl diff --git a/web/upload/src/main/resources/groups.xsl b/web/upload/web/upload/web/upload/src/main/resources/groups.xsl similarity index 100% rename from web/upload/src/main/resources/groups.xsl rename to web/upload/web/upload/web/upload/src/main/resources/groups.xsl diff --git a/web/upload/src/main/resources/payload.xsd b/web/upload/web/upload/web/upload/src/main/resources/payload.xsd similarity index 100% rename from web/upload/src/main/resources/payload.xsd rename to web/upload/web/upload/web/upload/src/main/resources/payload.xsd diff --git a/web/upload/src/test/java/ru/javaops/masterjava/MainXml.java b/web/upload/web/upload/web/upload/src/test/java/ru/javaops/masterjava/MainXml.java similarity index 100% rename from web/upload/src/test/java/ru/javaops/masterjava/MainXml.java rename to web/upload/web/upload/web/upload/src/test/java/ru/javaops/masterjava/MainXml.java diff --git a/web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java b/web/upload/web/upload/web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java similarity index 100% rename from web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java rename to web/upload/web/upload/web/upload/src/test/java/ru/javaops/masterjava/xml/util/JaxbParserTest.java diff --git a/web/upload/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java b/web/upload/web/upload/web/upload/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java similarity index 100% rename from web/upload/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java rename to web/upload/web/upload/web/upload/src/test/java/ru/javaops/masterjava/xml/util/StaxStreamProcessorTest.java diff --git a/web/upload/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java b/web/upload/web/upload/web/upload/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java similarity index 100% rename from web/upload/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java rename to web/upload/web/upload/web/upload/src/test/java/ru/javaops/masterjava/xml/util/XPathProcessorTest.java diff --git a/web/upload/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java b/web/upload/web/upload/web/upload/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java similarity index 100% rename from web/upload/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java rename to web/upload/web/upload/web/upload/src/test/java/ru/javaops/masterjava/xml/util/XsltProcessorTest.java diff --git a/web/upload/src/test/resources/city.xml b/web/upload/web/upload/web/upload/src/test/resources/city.xml similarity index 100% rename from web/upload/src/test/resources/city.xml rename to web/upload/web/upload/web/upload/src/test/resources/city.xml diff --git a/web/upload/src/test/resources/payload.xml b/web/upload/web/upload/web/upload/src/test/resources/payload.xml similarity index 100% rename from web/upload/src/test/resources/payload.xml rename to web/upload/web/upload/web/upload/src/test/resources/payload.xml