diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..d39a9a0 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,73 @@ +# Java Maven CircleCI 2.0 configuration file +# +# Check https://circleci.com/docs/2.0/language-java/ for more details +# +version: 2 + +references: + build: &build + working_directory: ~/repo + + environment: + # Customize the JVM maximum heap limit + MAVEN_OPTS: -Xmx2048m + JACOCO: false + + steps: + - checkout + + # Download and cache dependencies + - restore_cache: + keys: + - v2-dependencies-{{ checksum "pom.xml" }} + # fallback to using the latest cache if no exact match is found + - v2-dependencies- + + - run: + name: Go Offline with Maven + command: mvn verify -DskipTests + + - save_cache: + paths: + - ~/.m2 + key: v2-dependencies-{{ checksum "pom.xml" }} + + # run tests! + - run: + name: Run integration tests + command: mvn verify + +workflows: + version: 2 + integration-tests: + jobs: + - zulu-6 + - zulu-7 + - zulu-8 + - zulu-9 + - zulu-11 + +jobs: + zulu-6: + docker: + - image: wavesoftware/circleci-zulujdk:6 + <<: *build + zulu-7: + docker: + - image: wavesoftware/circleci-zulujdk:7 + <<: *build + zulu-8: + docker: + - image: wavesoftware/circleci-zulujdk:8 + <<: *build + zulu-9: + docker: + - image: wavesoftware/circleci-zulujdk:9 + <<: *build + zulu-11: + docker: + - image: wavesoftware/circleci-zulujdk:11 + <<: *build + + + diff --git a/.editorconfig b/.editorconfig index 0f8ba0c..eb6626d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,4 +9,7 @@ end_of_line = lf insert_final_newline = true charset = utf-8 indent_style = space -indent_size = 4 \ No newline at end of file +indent_size = 4 + +[*.yml] +indent_size = 2 diff --git a/.gitignore b/.gitignore index 8888c96..224fad4 100644 --- a/.gitignore +++ b/.gitignore @@ -11,10 +11,7 @@ # Eclipse IDE /.classpath /.project -/.settings/org.eclipse.core.resources.prefs -/.settings/org.eclipse.jdt.core.prefs -/.settings/org.eclipse.m2e.core.prefs -/.settings/org.eclipse.jdt.ui.prefs +/.settings # Netbeans IDE /nbactions.xml diff --git a/.travis.yml b/.travis.yml index e221ec7..ec44618 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,28 +1,26 @@ language: java -script: mvn clean install --fail-at-end +dist: trusty +before_script: mvn dependency:go-offline +script: mvn clean verify --fail-at-end notifications: email: - on_failure: true + on_failure: change matrix: include: - - jdk: openjdk6 - env: JACOCO=true - - jdk: openjdk7 - env: JACOCO=true COVERALLS=true - - jdk: oraclejdk7 - env: JACOCO=true - - jdk: oraclejdk8 - env: JACOCO=true - - jdk: openjdk7 - env: JACOCO=true GDMSESSION=sonar - - jdk: openjdk7 - env: JACOCO=true SONAR=publish - script: mvn clean install sonar:sonar --fail-at-end - - jdk: openjdk6 - env: JACOCO=false - - jdk: openjdk7 - env: JACOCO=false - - jdk: oraclejdk7 - env: JACOCO=false - - jdk: oraclejdk8 - env: JACOCO=false + # Quality testing + - jdk: oraclejdk8 + env: JACOCO=true RELEASE_CHECKS=true + - jdk: oraclejdk8 + env: JACOCO=true COVERALLS=true + - jdk: oraclejdk8 + env: JACOCO=true SONAR=publish + script: mvn clean verify sonar:sonar --fail-at-end + # Performance testing + - jdk: openjdk7 + env: JACOCO=false + - jdk: openjdk8 + env: JACOCO=false + - jdk: oraclejdk9 + env: JACOCO=false + - jdk: oraclejdk11 + env: JACOCO=false diff --git a/LICENSE b/LICENSE index 099ac17..d1c0c37 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2015 Wave Software + Copyright 2015-2018 Wave Software Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index a100426..b93625d 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,30 @@ # EID Runtime Exceptions and Utilities -[![Build Status](https://travis-ci.org/wavesoftware/java-eid-exceptions.svg?branch=master)](https://travis-ci.org/wavesoftware/java-eid-exceptions) [![Coverage Status](https://coveralls.io/repos/wavesoftware/java-eid-exceptions/badge.svg?branch=master&service=github)](https://coveralls.io/github/wavesoftware/java-eid-exceptions?branch=master) [![SonarQube Tech Debt](https://img.shields.io/sonar/http/sonar-ro.wavesoftware.pl/pl.wavesoftware:eid-exceptions/tech_debt.svg)](http://sonar-ro.wavesoftware.pl/dashboard/index/2600) [![Dependency Status](https://www.versioneye.com/user/projects/55aafc74306535001b000440/badge.svg?style=flat)](https://www.versioneye.com/user/projects/55aafc74306535001b000440) [![Maven Central](https://img.shields.io/maven-central/v/pl.wavesoftware/eid-exceptions.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22pl.wavesoftware%22%20AND%20a%3A%22eid-exceptions%22) +[![Build Status](https://travis-ci.org/wavesoftware/java-eid-exceptions.svg?branch=master)](https://travis-ci.org/wavesoftware/java-eid-exceptions) [![Coverage Status](https://coveralls.io/repos/wavesoftware/java-eid-exceptions/badge.svg?branch=master&service=github)](https://coveralls.io/github/wavesoftware/java-eid-exceptions?branch=master) [![SonarQube Tech Debt](https://img.shields.io/sonar/https/sonar.wavesoftware.pl/pl.wavesoftware%3Aeid-exceptions/tech_debt.svg)](https://sonar.wavesoftware.pl/dashboard?id=pl.wavesoftware%3Aeid-exceptions) [![Maven Central](https://img.shields.io/maven-central/v/pl.wavesoftware/eid-exceptions.svg)](https://search.maven.org/artifact/pl.wavesoftware/eid-exceptions/1.2.0/jar) This small library holds a set of exceptions and utilities that implements idea of fast, reusable, error codes that can be simply thrown fast in case of unpredictable and unrecoverable application failure. It is meant to be used for application bugs. -## Idea +## The Idea -The idea is to use a set of simple runtime exceptions. They should always take the Exception ID (Eid) object in the making. This eid object will then be reported when displaying or logging that exception. It can also be viewed on the professional fatal error window of the application as a bug reference. EidRuntimeExceptions contains also additional unique ID to distinguish each single exception from others with same Eid. This approach simplifies the management of exceptions in the application and allows developers to focus on functionalities rather than coming up with the correct statement for the exception. +The main idea of this library is to use a set of simple runtime exceptions to speedup development and make it more professional in the same time. Those exceptions should always take the Exception ID (Eid for short) object on construction. The Eid object should be generated by developer while writing code and committed in the constructor of an exception. This eid object will then be reported when that exception is being displayed or logged. -This approach is best to use with tools and plugins like: +This approach simplifies the management of exceptions in the application and allows developers to focus on functionality and code quality, rather than coming up with the correct statement for the exception. + +This error number is perfect to be displayed on the error "500" page for your application as a bug reference. It's good idea, because it is static, so wil l not change in subsequent invocations, but it also do not disclose the actual reason why bug occurred. + +This approach is best to use with tools and IDE plugins like: - * [EidGenerator for Netbeans IDE](http://plugins.netbeans.org/plugin/53137/exception-id-eid-generator) * [Generating Exception Id number in Intellij IDEA with Live Templates](https://github.com/wavesoftware/java-eid-exceptions/wiki/Generating%20Exception%20Id%20number%20in%20Intellij%20IDEA%20with%20Live%20Templates) + * [EidGenerator for Netbeans IDE](http://plugins.netbeans.org/plugin/53137/exception-id-eid-generator) + +Error page can say something like: + +> We are deeply sorry. A fatal error occurred. +> The reference number is: 20150721:100554 +> +> Wait a couple of minutes, and try again. If the same error number persists, call IT support. + +That error page is easy to implement, because all those exceptions implement `EidContainer` interface. Example: @@ -43,7 +56,7 @@ This classes shouldn't be used in any public API or library. It is designed to b pl.wavesoftware eid-exceptions - 1.1.0 + 1.2.0 ``` @@ -107,20 +120,26 @@ checkElementIndex(index, list.size(), "20150721:115749"); #### Formatted message support -From release `1.1.0` there have been added methods to support additional formatted messages for `checkArgument`, `checkState`, `checkNotNull` and `checkElementIndex` method. Those method versions can sometimes be used to pass additional information to exceptions that will be displayed in log files. +From release `1.2.0` methods have been added to support additional formatted messages for `checkArgument`, +`checkState`, `checkNotNull` and `checkElementIndex` method. Those method versions can sometimes be used to pass additional information to exceptions that will be displayed in log files. -Message formatting is done using `String.format(String, Object[])` method. +From release `2.0.0` message formatting is done using `MessageFormat#format(String, Object[])` method. For example: ```java -checkState(transation.isValid(), "20151119:120238", "Invalid transaction: %s, transaction); +checkState( + transation.isValid(), "20151119:120238", + "Invalid transaction: {0}", transaction +); ``` Will produce output similar to; ``` -pl.wavesoftware.eid.exceptions.EidIllegalStateException: [20151119:120238] => Invalid transaction: +pl.wavesoftware.eid.exceptions.EidIllegalStateException: + ↵ [20151119:120238] => Invalid transaction: + ↵ ``` #### Functional try to execute blocks @@ -132,8 +151,19 @@ There are two versions. One with `UnsafeSupplier` and one with `UnsafeProcedure` Example: ```java -InputStream is = EidPreconditions.tryToExecute(new UnsafeSupplier() { - @Override +import static pl.wavesoftware.eid.utils.EidExecutions.tryToExecute; +// [..] +InputStream is = tryToExecute( + () -> openResource("project.properties"), + "20150718:121521" +); +``` + +or with JDK < 8 + +```java +InputStream is = EidExecutions.tryToExecute(new UnsafeSupplier() { + @Override @Nonnull public InputStream get() throws IOException { return this.getClass().getClassLoader() .getResourceAsStream("project.properties"); @@ -141,30 +171,64 @@ InputStream is = EidPreconditions.tryToExecute(new UnsafeSupplier() }, "20150718:121521"); ``` -or with Java 8: - -```java -import static pl.wavesoftware.eid.utils.EidPreconditions.tryToExecute; -// [..] -InputStream is = tryToExecute(() -> { resource("project.properties"); }, "20150718:121521"); -``` - #### Logging -Eid object can also be useful in logging. That are `makeLogMessage` method provided to do that. Message formatting is done using `String.format(String, Object[])` method. +Eid object can also be useful in logging. That is `message` method provided to do that. Message formatting is done using +`MessageFormat.format(String, Object[])` method. For example: ```java -log.debug(new Eid("20151119:121814").makeLogMessage("REST request received: %s", request)); +log.debug(DefaultEid + .eid("20151119:121814") + .message("REST request received: {0}", request).toString() +); ``` will unfold to something similar to: ``` -2017-01-08T16:45:34,334 DEBUG [a.b.c.RestBroker] [20151119:121814] REST request received: flow=ShowLastTransactions step=Confirm> +2017-01-08T16:45:34,334 DEBUG [a.b.c.RestBroker] + ↵ [20151119:121814] REST request received: + ↵ flow=ShowLastTransactions step=Confirm> ``` -###Contributing +#### Configuration + +From release `2.0.0` configuration interfaces have been added. There are 2 ways to configure Eid library. + +##### Configuration using Java's ServiceLoader mechanism + +Java `ServiceLoader` mechanism is standard for extending libraries. To do that, create on your classpath, a file: + +`META-INF/services/pl.wavesoftware.eid.api.Configurator` + +In that file, place a fully qualified class name of your class that implements `Configurator` interface. It should be called first time you reference an Eid, or and of the eid exceptions, or utility preconditions class. + +##### Programmatic configuration + +You can also configure Eid library programmatically. To do just that, use `EidModule.getBinding().getConfigurationSystem().configure()` method. + +```java +// configure +Configurator original = EidModul.getBinding() + .getConfigurationSystem() + .configure(configuration -> + configuration.uniqueIdGenerator(() -> constUniq) + ); + +// restore original configuration with: +EidModule.getBinding() + .getConfigurationSystem() + .configure(original); +``` + +Note, that method returns a configurator that can be used to restore configuration to the state before you invoke this configuration method. + +#### Validation + +On `2.0.0` release optional validation have been added. If you configure a `Validator` using either of configuration methods, each new Eid will be validated for correctness. Note that this will happen lazily for `EidPreconditions` and `EidExecutions` utility methods. + +### Contributing Contributions are welcome! @@ -184,6 +248,17 @@ Even if you can't contribute code, if you have an idea for an improvement please ### Releases +- 2.0.0 + - Complete overhaul of library structure + - More obvious exceptions constructors + - Better configuration + - Optional validation + +- 1.2.0 + - Major performance tweaks and tests for `EidPreconditions` methods #4 + - Major performance tweaks and tests for `Eid` class #2 + - Switched to new OSSRH maven template + - Switched to Git Flow via jgitflow plugin - 1.1.0 - Adding support for formatted messages in exceptions and also in utility methods of `EidPreconditions` - 1.0.1 diff --git a/pom.xml b/pom.xml index f2d4513..728bdea 100644 --- a/pom.xml +++ b/pom.xml @@ -1,15 +1,32 @@ + + 4.0.0 pl.wavesoftware eid-exceptions - 1.2.0 + 2.0.0 jar EID Runtime Exceptions and Utilities - This small library holds a set of Exceptions that implements idea of fast, reusable, error codes - that can be simple thrown fast in case of unpredictable and unrecoverable application failure. + This small library holds a set of Exceptions that implements idea of + fast, reusable, error codes that can be simple thrown fast in case of + unpredictable and unrecoverable application failure. http://wavesoftware.github.io/java-eid-exceptions/ 2015 @@ -36,10 +53,6 @@ - - ${maven.required.version} - - scm:git:https://github.com/wavesoftware/java-eid-exceptions.git scm:git:git@github.com:wavesoftware/java-eid-exceptions.git @@ -68,8 +81,6 @@ - apache20 - 3.0.4 UTF-8 UTF-8 ${project.build.directory}/sonar @@ -93,7 +104,6 @@ com.google.code.findbugs jsr305 3.0.1 - jar @@ -110,28 +120,22 @@ 1.7.1 test - - org.hamcrest - hamcrest-all - 1.3 - test - org.openjdk.jmh jmh-core - 1.11.3 + 1.16 test org.openjdk.jmh jmh-generator-annprocess - 1.11.3 + 1.16 test - org.slf4j - slf4j-simple - 1.7.20 + ch.qos.logback + logback-classic + 1.2.3 test @@ -149,18 +153,17 @@ - - org.codehaus.mojo + org.sonarsource.scanner.maven sonar-maven-plugin - 3.0.1 + 3.5.0.1254 - external.atlassian.jgitflow + com.manamind.jgitflow jgitflow-maven-plugin - 1.0-m5.1 + 1.0.0 true @@ -201,7 +204,7 @@ -Werror - -Xlint:all + -Xlint:all,-options,-processing @@ -296,6 +299,11 @@ maven-site-plugin 3.5 + + org.codehaus.gmaven + groovy-maven-plugin + 2.1 + @@ -360,7 +368,7 @@ - org.codehaus.mojo + org.sonarsource.scanner.maven sonar-maven-plugin @@ -376,12 +384,11 @@ org.codehaus.gmaven groovy-maven-plugin - 2.0 org.codehaus.groovy groovy-all - 2.4.6 + 2.4.15 @@ -456,6 +463,26 @@ + + + release-checks + + + env.RELEASE_CHECKS + true + + + + + + maven-source-plugin + + + maven-javadoc-plugin + + + + diff --git a/src/main/java/pl/wavesoftware/eid/DefaultEid.java b/src/main/java/pl/wavesoftware/eid/DefaultEid.java new file mode 100644 index 0000000..a37219a --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/DefaultEid.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pl.wavesoftware.eid; + +import pl.wavesoftware.eid.api.Configurator; +import pl.wavesoftware.eid.api.EidContainer; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; +import pl.wavesoftware.eid.api.SerializableSupplier; +import pl.wavesoftware.eid.api.Supplier; +import pl.wavesoftware.eid.api.Validator; + +import javax.annotation.Nullable; + +import static pl.wavesoftware.eid.system.EidModule.MODULE; + +/** + *

The Idea

+ *

+ * The main idea of this library is to use a set of simple runtime exceptions to + * speedup development and make it more professional in the same time. Those + * exceptions should always take the Exception ID (Eid for short) object on + * construction. The Eid object should be generated by developer while writing + * code and committed in the constructor of an exception. This eid object will + * then be reported when that exception is being displayed or logged. + *


+ * This approach simplifies the management of exceptions in the application and + * allows developers to focus on functionality and code quality, rather than + * coming up with the correct statement for the exception. + *


+ * This error number is perfect to be displayed on the error "500" page for your + * application as a bug reference. It's good idea, because it is static, so wil + * l not change in subsequent invocations, but it also do not disclose the + * actual reason why bug occurred. + *


+ * This approach is best to use with tools and IDE plugins like: + *

+ *

+ * Error page can say something like: + *


+ *

+ * We are deeply sorry. A fatal error occurred.
+ * The reference number is: 20150721:100554
+ *
+ * Wait a couple of minutes, and try again. If the + * same error number persists, call IT support. + *
+ *


+ * That error page is easy to implement, because all those exceptions implement + * {@link EidContainer} interface. + *


+ * Usage example: + *

+ * throw new EidIllegalStateException("20150721:100554", cause);
+ * 
+ * Example log: + *
+ * pl.wavesoftware.eid.exceptions.EidIllegalStateException: [20150721:100554]<g0qrwx> => Zipfile in invalid format
+ * 	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
+ * 	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
+ *
+ * Caused by: java.util.zip.DataFormatException: Zipfile in invalid format
+ * 	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
+ * 	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
+ * 	... 62 more
+ * 
+ *

+ * Eid number contains also additional unique ID to distinguish each single + * exception from others with same Eid. + * + *

Caution

+ *

+ * Those classes shouldn't be used in any public API or library - those should + * have proper checked exceptions build in design. It's designed to be used for + * in-house development of end user applications which will report bugs in + * standardized error pages or post them to issue tracker. + *


+ * Remember! You should never catch a runtime exception, in place other then + * appropriate error page. + * + *

Notice

+ *

+ * Check out {@code EidPreconditions} class for ease of use utility checks. + *

+ * You can tweak behavior of Eid with {@link Configurator}. + * + * @author Krzysztof Suszynski + * @see EidContainer + * @see Configurator + * @since 2.0.0 + */ +public class DefaultEid implements Eid { + + private static final long serialVersionUID = 20181029193034L; + + private transient String id; + @Nullable + private transient String ref; + private final SerializableSupplier uniqueId = MODULE + .getBinding() + .getFactories() + .getLazyFactory() + .lazy(new Supplier() { + @Override + public String get() { + return MODULE.getBinding() + .getConfigurationSystem() + .getConfiguration() + .getIdGenerator() + .generateUniqId(); + } + }); + + /** + * Constructor a single value of exception ID. + * + * @param id the exception id, should be uniquely generated by developer + */ + public DefaultEid(CharSequence id) { + this.id = validate(id).toString(); + this.ref = null; + } + + /** + * Constructor with two values an exception ID and reference of some sort. + * The second reference can be used to hold reference from external system. + * + * @param id the exception id, should be uniquely generated by developer + * @param ref a reference from external system + */ + public DefaultEid(CharSequence id, CharSequence ref) { + this.id = validate(id).toString(); + this.ref = ref.toString(); + } + + /** + * A static factory method for Eid object that takes a single value of + * exception ID. + * + * @param id the exception id, should be uniquely generated by developer + * @return a created Eid object + */ + public static Eid eid(String id) { + return new DefaultEid(id); + } + + @Override + public String getId() { + return id; + } + + @Override + @Nullable + public String getRef() { + return ref; + } + + @Override + public boolean hasRef() { + return getRef() != null; + } + + @Override + public String getUnique() { + return uniqueId.get(); + } + + @Override + public EidMessage message( + CharSequence messageTemplate, + Object... templateArguments + ) { + return MODULE.getBinding() + .getFactories() + .getMessageFactory() + .create( + this, + messageTemplate, + templateArguments + ); + } + + @Override + public String toString() { + return MODULE.getBinding() + .getConfigurationSystem() + .getConfiguration() + .getFormatter() + .format(this); + } + + /* + Suppress warnings id here for null check. Users can pass null event if it's + forbidden. + */ + @SuppressWarnings({"ConstantConditions", "squid:S2583"}) + private static CharSequence validate(CharSequence id) { + if (id == null) { + throw new IllegalArgumentException("Exception ID can't be null"); + } + if (isInvalid(id)) { + throw new IllegalArgumentException( + "Invalid ID given as an Exception ID: " + id + ); + } + return id; + } + + private static boolean isInvalid(CharSequence id) { + Validator validator = getValidator(); + return validator != null && !validator.isValid(id); + } + + @Nullable + private static Validator getValidator() { + return MODULE.getBinding() + .getConfigurationSystem() + .getConfiguration() + .getValidator(); + } +} diff --git a/src/main/java/pl/wavesoftware/eid/ReturnTypesAreNonnullByDefault.java b/src/main/java/pl/wavesoftware/eid/ReturnTypesAreNonnullByDefault.java deleted file mode 100644 index ea08182..0000000 --- a/src/main/java/pl/wavesoftware/eid/ReturnTypesAreNonnullByDefault.java +++ /dev/null @@ -1,17 +0,0 @@ -package pl.wavesoftware.eid; - -import javax.annotation.Nonnull; -import javax.annotation.meta.TypeQualifierDefault; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @author Krzysztof Suszynski - * @since 2016-03-26 - */ -@Nonnull -@TypeQualifierDefault(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface ReturnTypesAreNonnullByDefault { -} diff --git a/src/main/java/pl/wavesoftware/eid/api/Binding.java b/src/main/java/pl/wavesoftware/eid/api/Binding.java new file mode 100644 index 0000000..dafc208 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/Binding.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +/** + * A binding of Eid library. This interface can be used to completely + * replace original binding with your custom implementation. + * + *

To replace implementation use {@link java.util.ServiceLoader} like: + * + *

META-INF/services/pl.wavesoftware.eid.api.Binding
+ *

+ * In that file, place a fully qualified class name of your class that implements + * {@link Binding} interface. It should be called first time you reference an + * {@link Eid}, or and of the eid exceptions, or utility preconditions class. + * + *

Usually it's way easier to just reconfigure existing configuration using + * {@link Configurator} interface. + * + * @author Krzysztof Suszynski + * @see Configurator + * @see java.util.ServiceLoader + * @since 2.0.0 + */ +public interface Binding { + + /** + * Gets a configuration system + * + * @return a configuration system + */ + ConfigurationSystem getConfigurationSystem(); + + /** + * Get bound Eid factories to be used to perform various Eid + * related operations. + * + * @return a factories for various Eid related things. + */ + EidFactories getFactories(); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/Configuration.java b/src/main/java/pl/wavesoftware/eid/api/Configuration.java new file mode 100644 index 0000000..ae4e931 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/Configuration.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +import javax.annotation.Nullable; +import java.util.Locale; +import java.util.TimeZone; + +/** + * Represents a configuration of Eid library. To reconfigure use + * {@link Configurator} interface. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + * @see Configurator + */ +public interface Configuration { + /** + * Gets a Eid formatter + * + * @return a formatter of Eid + */ + Formatter getFormatter(); + + /** + * Gets a Eid unique ID generator + * + * @return unique ID generator + */ + UniqueIdGenerator getIdGenerator(); + + /** + * Gets a Eid validator if set. Returns null if validator wasn't configured. + * + * @return an Eid validator, or null + */ + @Nullable + Validator getValidator(); + + /** + * Gets a locale to be used when formatting texts. Returns null if locale + * isn't set. + * + * @return a locale to be used when formatting texts, or null + */ + @Nullable + Locale getLocale(); + + /** + * Gets a time zone to be used when formatting texts. Returns null if time + * zone isn't set. + * + * @return a time zone to be used when formatting texts, or null + */ + @Nullable + TimeZone getTimeZone(); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/ConfigurationBuilder.java b/src/main/java/pl/wavesoftware/eid/api/ConfigurationBuilder.java new file mode 100644 index 0000000..5a38723 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/ConfigurationBuilder.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +import javax.annotation.Nullable; +import java.util.Locale; +import java.util.TimeZone; + +/** + * Use {@link Configurator} to configure Eid settings. + * + * @author Krzysztof Suszynski + * @see Configurator + * @since 2.0.0 + */ +public interface ConfigurationBuilder { + + /** + * Configures a unique ID generator used by Eid objects to generate unique + * part of Eid number. + * + * @param generator a generator of unique ID + * @return a self reference for ease of use + */ + ConfigurationBuilder uniqueIdGenerator(UniqueIdGenerator generator); + + /** + * Configures a formatter to be used by Eid numbers. + * + * @param formatter a formatter to be used by Eid formatting and displaying + * @return a self reference for ease of use + */ + ConfigurationBuilder formatter(Formatter formatter); + + /** + * Sets a locale to be used when formatting texts. If not set default system + * locale will be used (platform specific). See {@link Locale#getDefault()}. + * + * @param locale a locale to be used, if {@code null} was given default + * locale will be used + * @return a self reference for ease of use + * @see Locale#getDefault() + */ + ConfigurationBuilder locale(@Nullable Locale locale); + + /** + * Sets a time zone to be used when formatting texts. If not set, default + * system time zone will be used (platform specific). See + * {@link TimeZone#getDefault()}. + * + * @param zone a time zone to be used, if {@code null} was given default + * time zone will be used + * @return a self reference for ease of use + * @see TimeZone#getDefault() + */ + ConfigurationBuilder timezone(@Nullable TimeZone zone); + + /** + * Configures a validator that will be called on each Eid number. By + * default, there is no validator configured for maximum speed. Using this + * validator you can enforce a standardization of Eid numbers. + * + * @param validator a validator to be used, if {@code null} was given + * validator will not be used. + * @return a self reference for ease of use + */ + ConfigurationBuilder validator(@Nullable Validator validator); + + /** + * Gets an object that is a future configuration, to be used to cross + * configure elements of the configuration. + *

+ * It might throw exceptions if configuration isn't completed so use it + * only if configuration is done. + * + * @return a future configuration + */ + Configuration getFutureConfiguration(); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/ConfigurationSystem.java b/src/main/java/pl/wavesoftware/eid/api/ConfigurationSystem.java new file mode 100644 index 0000000..6cad443 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/ConfigurationSystem.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +/** + * A configuration provider interface. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public interface ConfigurationSystem { + /** + * Get a configuration object + * + * @return a configuration object + */ + Configuration getConfiguration(); + + /** + * Configures an Eid library programmatically. Note, that method returns a + * configurator that can be used to restore configuration to the state + * before you invoke this configuration method. + * + * @param configurator a configurator to use to configure Eid library + * @return a reference to a configurator that can be used to restore + * previous configuration + */ + Configurator configure(Configurator configurator); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/Configurator.java b/src/main/java/pl/wavesoftware/eid/api/Configurator.java new file mode 100644 index 0000000..5cbd831 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/Configurator.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +import java.util.ServiceLoader; + +/** + * You can use this interface with Java's {@link ServiceLoader} class. + *

+ * To do that, create on your classpath, a file: + *

META-INF/services/pl.wavesoftware.eid.api.Configurator
+ * + * In that file, place a fully qualified class name of your class that implements + * {@link Configurator} interface. It should be called first time you + * reference an {@link Eid}, or and of the eid exceptions, or utility + * preconditions class. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + * @see ServiceLoader + */ +public interface Configurator { + + /** + * Configures an Eid configuration. + * + * @param configuration a configuration to be configured + */ + void configure(ConfigurationBuilder configuration); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/Eid.java b/src/main/java/pl/wavesoftware/eid/api/Eid.java new file mode 100644 index 0000000..67414b5 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/Eid.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +import javax.annotation.Nullable; +import java.io.Serializable; + +/** + *

The Idea

+ *

+ * The main idea of this library is to use a set of simple runtime exceptions to + * speedup development and make it more professional in the same time. Those + * exceptions should always take the Exception ID (Eid for short) object on + * construction. The Eid object should be generated by developer while writing + * code and committed in the constructor of an exception. This eid object will + * then be reported when that exception is being displayed or logged. + *


+ * This approach simplifies the management of exceptions in the application and + * allows developers to focus on functionality and code quality, rather than + * coming up with the correct statement for the exception. + *


+ * This error number is perfect to be displayed on the error "500" page for your + * application as a bug reference. It's good idea, because it is static, so wil + * l not change in subsequent invocations, but it also do not disclose the + * actual reason why bug occurred. + *


+ * This approach is best to use with tools and IDE plugins like: + *

+ *

+ * Error page can say something like: + *


+ *

+ * We are deeply sorry. A fatal error occurred.
+ * The reference number is: 20150721:100554
+ *
+ * Wait a couple of minutes, and try again. If the + * same error number persists, call IT support. + *
+ *


+ * That error page is easy to implement, because all those exceptions implement + * {@link EidContainer} interface. + *


+ * Usage example: + *

+ * throw new EidIllegalStateException("20150721:100554", cause);
+ * 
+ * Example log: + *
+ * pl.wavesoftware.eid.exceptions.EidIllegalStateException: [20150721:100554]<g0qrwx> => Zipfile in invalid format
+ * 	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
+ * 	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
+ *
+ * Caused by: java.util.zip.DataFormatException: Zipfile in invalid format
+ * 	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
+ * 	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
+ * 	... 62 more
+ * 
+ *

+ * Eid number contains also additional unique ID to distinguish each single + * exception from others with same Eid. + * + *

Caution

+ *

+ * Those classes shouldn't be used in any public API or library - those should + * have proper checked exceptions build in design. It's designed to be used for + * in-house development of end user applications which will report bugs in + * standardized error pages or post them to issue tracker. + *


+ * Remember! You should never catch a runtime exception, in place other then + * appropriate error page. + * + *

Notice

+ *

+ * Check out {@code EidPreconditions} class for ease of use utility checks. + *

+ * You can tweak behavior of Eid with {@link Configurator}. + * + * @author Krzysztof Suszynski + * @see EidContainer + * @see Configurator + * @since 2.0.0 + */ +public interface Eid extends Serializable { + /** + * Getter for constant Exception ID + * + * @return ID of exception + */ + String getId(); + + /** + * Get an external reference passed to Exception ID + * + * @return an external reference, or null if not set + */ + @Nullable + String getRef(); + + /** + * Do this Exception ID has an external reference number? + * + * @return true, if has an external reference + */ + boolean hasRef(); + + /** + * Gets unique generated string for this instance of Eid + * + * @return a unique string + */ + String getUnique(); + + /** + * Creates a message object from this Eid, with given message template and + * template arguments. Message template and arguments will be interpolated + * using {@link java.text.MessageFormat#format(String, Object...)} method. + * + * @param messageTemplate a message format + * @param templateArguments a message format arguments that will be + * interpolated to format string + * @return a message object + */ + EidMessage message( + CharSequence messageTemplate, + Object... templateArguments + ); +} diff --git a/src/main/java/pl/wavesoftware/eid/exceptions/EidContainer.java b/src/main/java/pl/wavesoftware/eid/api/EidContainer.java similarity index 77% rename from src/main/java/pl/wavesoftware/eid/exceptions/EidContainer.java rename to src/main/java/pl/wavesoftware/eid/api/EidContainer.java index a0231e9..50c279d 100644 --- a/src/main/java/pl/wavesoftware/eid/exceptions/EidContainer.java +++ b/src/main/java/pl/wavesoftware/eid/api/EidContainer.java @@ -1,11 +1,11 @@ /* - * Copyright 2015 Krzysztof Suszyński . + * Copyright (c) 2018 Wave Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -13,12 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package pl.wavesoftware.eid.exceptions; +package pl.wavesoftware.eid.api; /** - * Indicate that object contains a Eid object + * Indicate that object contains a {@link Eid} object * * @author Krzysztof Suszynski + * @see Eid */ public interface EidContainer { diff --git a/src/main/java/pl/wavesoftware/eid/api/EidFactories.java b/src/main/java/pl/wavesoftware/eid/api/EidFactories.java new file mode 100644 index 0000000..818642f --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/EidFactories.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +/** + * Represents an Eid library bound factories. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public interface EidFactories { + + /** + * Gets an Eid message factory. + * + * @return a factory for Eid messages. + */ + EidMessageFactory getMessageFactory(); + + /** + * Gets a factory for lazy objects. + * + * @return a lazy objects factory. + */ + LazyFactory getLazyFactory(); + + /** + * Gets a Eid object factory. + * + * @return a factory for Eid objects + */ + EidFactory getEidFactory(); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/EidFactory.java b/src/main/java/pl/wavesoftware/eid/api/EidFactory.java new file mode 100644 index 0000000..6a5afb9 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/EidFactory.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +/** + * An Eid object factory + * + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public interface EidFactory { + /** + * Constructs a single value of exception ID. + * + * @param id the exception id, should be uniquely generated by developer + * @return a created Eid object + */ + Eid create(CharSequence id); + + /** + * Constructs with two values an exception ID and reference of some sort. + * The second reference can be used to hold reference from external system. + * + * @param id the exception id, should be uniquely generated by developer + * @param ref a reference from external system + * @return a created Eid object + */ + Eid create(CharSequence id, CharSequence ref); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/EidMessage.java b/src/main/java/pl/wavesoftware/eid/api/EidMessage.java new file mode 100644 index 0000000..a7f7fd1 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/EidMessage.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +/** + * The Eid message represents a message that contains a user given message + * with arguments, as well as Eid object. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public interface EidMessage extends CharSequence, EidContainer { + + /** + * Get a formatted message + * + * @return a formatted message + */ + CharSequence getFormattedMessage(); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/EidMessageFactory.java b/src/main/java/pl/wavesoftware/eid/api/EidMessageFactory.java new file mode 100644 index 0000000..59a9049 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/EidMessageFactory.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +/** + * Represents a factory for Eid messages. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public interface EidMessageFactory { + /** + * Create a Exception ID message, from Eid, message template and + * template arguments. + * + * @param eid an Exception ID object + * @param messageTemplate message template in form accepted by + * {@link java.text.MessageFormat#format(String, Object...)} + * @param templateArguments a template arguments to be used to interpolate + * into message + * @return a create message with Eid number + */ + EidMessage create( + Eid eid, + CharSequence messageTemplate, + Object[] templateArguments + ); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/Formatter.java b/src/main/java/pl/wavesoftware/eid/api/Formatter.java new file mode 100644 index 0000000..31589d1 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/Formatter.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +/** + * Represents a formatter that will be used to display an Eid number in logs + * or screen. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public interface Formatter { + /** + * Formats an Eid number to string + * + * @param eid an eid number + * @return a string with formatted Eid number + */ + String format(Eid eid); + + /** + * Formats an Eid paired with a message. + * + * @param eid an eid number to format + * @param message a message to be pair to eid + * @return a string with formatted eid and message + */ + String format(Eid eid, String message); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/LazyFactory.java b/src/main/java/pl/wavesoftware/eid/api/LazyFactory.java new file mode 100644 index 0000000..ba6174e --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/LazyFactory.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +import java.io.Serializable; + +/** + * A factory for a lazy objects. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public interface LazyFactory { + /** + * Creates a lazy supplier of a given supplier of serializable value + * + * @param supplier a supplier of serializable value + * @param a serializable type + * @return a lazy, serializable, supplier + */ + SerializableSupplier lazy(Supplier supplier); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/ReturnTypesAreNonnullByDefault.java b/src/main/java/pl/wavesoftware/eid/api/ReturnTypesAreNonnullByDefault.java new file mode 100644 index 0000000..e7c20e2 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/ReturnTypesAreNonnullByDefault.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +import javax.annotation.Nonnull; +import javax.annotation.meta.TypeQualifierDefault; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * This annotation can be applied to a package, class or method to indicate that + * the method return types in that element are nonnull by default unless + * there is: + *

    + *
  • An explicit nullness annotation + *
  • The method overrides a method in a superclass (in which case the + * annotation of the corresponding parameter in the superclass applies) + *
  • there is a default parameter annotation applied to a more tightly + * nested element. + *
+ * + * @author Krzysztof Suszynski + * @since 2016-03-26 + */ +@Nonnull +@TypeQualifierDefault(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ReturnTypesAreNonnullByDefault { +} diff --git a/src/main/java/pl/wavesoftware/eid/api/SerializableSupplier.java b/src/main/java/pl/wavesoftware/eid/api/SerializableSupplier.java new file mode 100644 index 0000000..1b55972 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/SerializableSupplier.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +import java.io.Serializable; + +/** + * A serializable supplier. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + * @param a type of this supplier, must be serializable + */ +public interface SerializableSupplier + extends Supplier, Serializable { +} diff --git a/src/main/java/pl/wavesoftware/eid/api/Supplier.java b/src/main/java/pl/wavesoftware/eid/api/Supplier.java new file mode 100644 index 0000000..aa88a93 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/Supplier.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +/** + * A supplier, inspired by Java 8 type of the same name. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + * @param a type of object that this supplier provides + */ +public interface Supplier { + /** + * Gets an object + * + * @return an object + */ + T get(); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/UniqueIdGenerator.java b/src/main/java/pl/wavesoftware/eid/api/UniqueIdGenerator.java new file mode 100644 index 0000000..f809fc7 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/UniqueIdGenerator.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +/** + * It is used to generate unique ID for each EID object. It's mustn't be secure + * because it just indicate EID object while logging. + * + * @author Krzysztof Suszynski + * @since 1.0.0 + */ +public interface UniqueIdGenerator { + + /** + * Generates a unique string ID + * + * @return a generated unique ID + */ + String generateUniqId(); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/Validator.java b/src/main/java/pl/wavesoftware/eid/api/Validator.java new file mode 100644 index 0000000..2211d0d --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/Validator.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +/** + * Implementing this validator and configuring it can help you assure that every + * Eid in your project, conform to your rules. + *


+ * Keep in mind that validation adds a little bit of cost, to every Eid creation, + * even if that particular Eid don't turn up to be used. + *


+ * To use your {@code Validator}, use {@link Configurator}. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + * @see Configurator + */ +public interface Validator { + /** + * Checks an ID that will be used as an Exception ID. + * + * @param id an id to check + * @return true, if given ID is valid + */ + boolean isValid(CharSequence id); +} diff --git a/src/main/java/pl/wavesoftware/eid/api/package-info.java b/src/main/java/pl/wavesoftware/eid/api/package-info.java new file mode 100644 index 0000000..1d0abe6 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/api/package-info.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Krzysztof Suszynski + * @since 2018-10-31 + */ +@ParametersAreNonnullByDefault +@ReturnTypesAreNonnullByDefault +package pl.wavesoftware.eid.api; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/pl/wavesoftware/eid/exceptions/Eid.java b/src/main/java/pl/wavesoftware/eid/exceptions/Eid.java deleted file mode 100644 index 5c7f217..0000000 --- a/src/main/java/pl/wavesoftware/eid/exceptions/Eid.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright 2015 Krzysztof Suszyński . - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package pl.wavesoftware.eid.exceptions; - -import javax.annotation.Nullable; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import static java.lang.Math.abs; - -/** - * This class shouldn't be used in any public API or library. It is designed to be used for in-house development - * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. - *

- * Exception identifier for all Eid Runtime Exceptions. - * - * @author Krzysztof Suszynski - */ -public class Eid implements Serializable { - - public static final String DEFAULT_FORMAT = "[%s]<%s>"; - - public static final String DEFAULT_REF_FORMAT = "[%s|%s]<%s>"; - - public static final String DEFAULT_MESSAGE_FORMAT = "%s => %s"; - - public static final UniqIdGenerator DEFAULT_UNIQ_ID_GENERATOR = new StdUniqIdGenerator(); - - private static final long serialVersionUID = -9876432123423401L; - - private static final int FORMAT_NUM_SPEC = 2; - - private static final int REF_FORMAT_NUM_SPEC = 3; - - private static final int MESSAGE_FORMAT_NUM_SPEC = 2; - - private static final String EMPTY_REF = ""; - - private static String messageFormat = DEFAULT_MESSAGE_FORMAT; - - private static UniqIdGenerator uniqIdGenerator = DEFAULT_UNIQ_ID_GENERATOR; - - private static String format = DEFAULT_FORMAT; - - private static String refFormat = DEFAULT_REF_FORMAT; - - private final String id; - - private final String ref; - - private String uniqueId; - - /** - * Constructor - * - * @param id the exception id, must be unique developer inserted string, from date - * @param ref an optional reference - */ - public Eid(String id, @Nullable String ref) { - this.id = id; - this.ref = ref == null ? EMPTY_REF : ref; - } - - /** - * Constructor - * - * @param id the exception id, must be unique developer inserted string, from date - */ - public Eid(String id) { - this.id = id; - this.ref = EMPTY_REF; - } - - /** - * Sets a format that will be used for all Eid exceptions when printing a detail message. - *

- * Format must be non-null and contain two format specifiers "%s" - * - * @param format a format that will be used, must be non-null and contain two format specifiers "%s" - * @return previously used format - * @throws IllegalArgumentException if given format hasn't got two format specifiers "%s", or if given format was - * null - */ - public static String setMessageFormat(String format) { - validateFormat(format, MESSAGE_FORMAT_NUM_SPEC); - String oldFormat = Eid.messageFormat; - Eid.messageFormat = format; - return oldFormat; - } - - /** - * Gets actually set message format - * - * @return actually set message format - */ - public static String getMessageFormat() { - return messageFormat; - } - - /** - * Sets the actual unique ID generator that will be used to generate IDs for all Eid objects. It will return previously used - * generator. - * - * @param uniqIdGenerator new instance of unique ID generator - * @return a previously used unique ID generator - * @throws IllegalArgumentException if given generator was null - */ - public static UniqIdGenerator setUniqIdGenerator(UniqIdGenerator uniqIdGenerator) { - if (uniqIdGenerator == null) { - throw new IllegalArgumentException("Unique ID generator can't be null, but given one"); - } - UniqIdGenerator previous = Eid.uniqIdGenerator; - Eid.uniqIdGenerator = uniqIdGenerator; - return previous; - } - - /** - * Sets the actual format that will be used in {@link #toString()} method. It will return previously used format. - * - * @param format a format compliant with {@link String#format(String, Object...)} with 2 object arguments - * @return a previously used format - * @throws IllegalArgumentException if given format hasn't got two format specifiers "%s", or if given format was - * null - */ - public static String setFormat(String format) { - validateFormat(format, FORMAT_NUM_SPEC); - String previously = Eid.format; - Eid.format = format; - return previously; - } - - /** - * Sets the actual format that will be used in {@link #toString()} method - * - * @param refFormat a format compliant with {@link String#format(String, Object...)} with 3 object arguments - * @return a previously used format - * @throws IllegalArgumentException if given format hasn't got tree format specifiers "%s", or if given format was - * null - */ - public static String setRefFormat(String refFormat) { - validateFormat(refFormat, REF_FORMAT_NUM_SPEC); - String previously = Eid.refFormat; - Eid.refFormat = refFormat; - return previously; - } - - /** - * Makes a log message from this EID object - *

- * This method is for convenience of usage of EID in logging. You can use it like this: - *

-     * log.debug(new Eid("20151025:202129").makeLogMessage("A request: %s", request));
-     * 
- * @param logMessageFormat a log message format as accepted by {@link String#format(String, Object...)} - * @param parameters a parameters for logMessageFormat to by passed to {@link String#format(String, Object...)} - * @return a formatted message - */ - public String makeLogMessage(String logMessageFormat, Object... parameters) { - String message = String.format(logMessageFormat, parameters); - return String.format(getMessageFormat(), this.toString(), message); - } - - @Override - public String toString() { - if ("".equals(ref)) { - return String.format(format, id, getUniq()); - } - return String.format(refFormat, id, ref, getUniq()); - } - - /** - * Getter for constant Exception ID - * - * @return ID of exception - */ - public String getId() { - return id; - } - - /** - * Get custom ref passed to Exception ID - * - * @return ID of exception - */ - public String getRef() { - return ref; - } - - /** - * Gets unique generated string for this instance of Eid - * - * @return a unique string - */ - public String getUniq() { - if (uniqueId == null) { - uniqueId = uniqIdGenerator.generateUniqId(); - } - return uniqueId; - } - - private static void validateFormat(String format, int numSpecifiers) { - if (format == null) { - throw new IllegalArgumentException("Format can't be null, but just received one"); - } - List specifiers = new ArrayList(); - for (int i = 0; i < numSpecifiers; i++) { - specifiers.add(i + "-test-id"); - } - String formatted = String.format(format, specifiers.toArray()); - for (String specifier : specifiers) { - if (!formatted.contains(specifier)) { - throw new IllegalArgumentException("Given format contains to little format specifiers, " - + "expected " + numSpecifiers + " but given \"" + format + "\""); - } - } - } - - /** - * It is used to generate unique ID for each EID object. It's mustn't be secure because it just indicate EID object while - * logging. - */ - public interface UniqIdGenerator { - - /** - * Generates a unique string ID - * - * @return a generated unique ID - */ - String generateUniqId(); - } - - private static final class StdUniqIdGenerator implements UniqIdGenerator { - - private static final int BASE36 = 36; - - private final Random random; - - private StdUniqIdGenerator() { - this.random = getUnsecuredFastRandom(); - } - - @Override - public String generateUniqId() { - long first = abs(random.nextLong() + 1); - int second = abs(random.nextInt(Integer.MAX_VALUE)); - int calc = (int) (first + second); - return Integer.toString(abs(calc), BASE36); - } - - private static Random getUnsecuredFastRandom() { - return new Random(System.currentTimeMillis()); - } - - } - -} diff --git a/src/main/java/pl/wavesoftware/eid/exceptions/EidIllegalArgumentException.java b/src/main/java/pl/wavesoftware/eid/exceptions/EidIllegalArgumentException.java index 253b88f..7a9c433 100644 --- a/src/main/java/pl/wavesoftware/eid/exceptions/EidIllegalArgumentException.java +++ b/src/main/java/pl/wavesoftware/eid/exceptions/EidIllegalArgumentException.java @@ -1,11 +1,11 @@ /* - * Copyright 2015 Krzysztof Suszyński . + * Copyright (c) 2015 Wave Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -15,81 +15,204 @@ */ package pl.wavesoftware.eid.exceptions; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; + +import javax.annotation.Nullable; + /** - * This class shouldn't be used in any public API or library. It is designed to be used for in-house development - * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + * This exception is Eid version of Java's {@link IllegalArgumentException} that + * holds an {@link Eid} object. It can be used to process it in application + * central error handler. *

- * This is Eid version of {@link IllegalArgumentException} + * Caution! This class shouldn't be used in any public API or + * library. It is designed to be used for in-house development of end user + * applications which will report bugs in standardized error pages or post them + * to issue tracker. * * @see IllegalArgumentException * @see EidRuntimeException * @author Krzysztof Suszynski + * @since 0.1.0 */ public class EidIllegalArgumentException extends EidRuntimeException { private static final long serialVersionUID = -9876432123423427L; /** - * @see EidRuntimeException#EidRuntimeException(String, String, Throwable) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} - * @param ref see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} + * Constructs a new runtime exception with the specified Exception ID as + * it's detail message, that's {@code new Eid(eid).toString()}. + *

+ * The cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param eid an exception ID as character sequence */ - public EidIllegalArgumentException(String eid, String ref, Throwable cause) { - super(eid, ref, cause); + public EidIllegalArgumentException(CharSequence eid) { + super(eid); } /** - * @see EidRuntimeException#EidRuntimeException(String, Throwable) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(String, Throwable)} + * Constructs a new runtime exception with the specified Exception ID and + * detail message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param eid an exception ID as character sequence + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidIllegalArgumentException(String eid, Throwable cause) { - super(eid, cause); + public EidIllegalArgumentException(CharSequence eid, String message) { + super(eid, message); } /** - * @see EidRuntimeException#EidRuntimeException(String, String) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, String)} - * @param ref see description on {@link EidRuntimeException#EidRuntimeException(String, String)} + * Constructs a new runtime exception with the specified Eid message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the Eid message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidIllegalArgumentException(String eid, String ref) { - super(eid, ref); + public EidIllegalArgumentException(EidMessage message) { + super(message); } /** - * @see EidRuntimeException#EidRuntimeException(Eid, Throwable) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(Eid, Throwable)} + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param eid an exception ID as character sequence + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or */ - public EidIllegalArgumentException(Eid id, Throwable cause) { - super(id, cause); + public EidIllegalArgumentException( + CharSequence eid, String message, @Nullable Throwable cause + ) { + super(eid, message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param message the Eid message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidIllegalArgumentException( + EidMessage message, @Nullable Throwable cause + ) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID and + * cause. + *

+ * A detail message of eid.toString() + (cause==null ? "" : cause.toString()) + * (which typically contains the class and detail message of + * cause). + *

+ * This constructor is useful for runtime exceptions that are little more + * than wrappers for other throwables. + * + * @param eid an exception ID as character sequence + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidIllegalArgumentException( + CharSequence eid, @Nullable Throwable cause + ) { + super(eid, cause); } /** - * @see EidRuntimeException#EidRuntimeException(Eid) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid)} + * Constructs a new runtime exception with the specified Exception ID as + * it's detail message, that's {@code eid.toString()}. + *

+ * The cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param id an exception ID */ public EidIllegalArgumentException(Eid id) { super(id); } /** - * @see EidRuntimeException#EidRuntimeException(Eid, String, Object...) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} - * @param messageFormat see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} - * @param parameters see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} + * Constructs a new runtime exception with the specified Exception ID and + * detail message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param id an exception ID + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidIllegalArgumentException(Eid id, String messageFormat, Object... parameters) { - super(id, messageFormat, parameters); + public EidIllegalArgumentException(Eid id, String message) { + super(id, message); } /** - * @return {@link IllegalArgumentException} class + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param id an exception ID + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or */ - @Override - public Class getStandardJdkClass() { - return IllegalArgumentException.class; + public EidIllegalArgumentException( + Eid id, String message, @Nullable Throwable cause + ) { + super(id, message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID and + * cause. + *

+ * A detail message of eid.toString() + (cause==null ? "" : cause.toString()) + * (which typically contains the class and detail message of + * cause). + *

+ * This constructor is useful for runtime exceptions that are little more + * than wrappers for other throwables. + * + * @param id an exception ID + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidIllegalArgumentException(Eid id, @Nullable Throwable cause) { + super(id, cause); } } diff --git a/src/main/java/pl/wavesoftware/eid/exceptions/EidIllegalStateException.java b/src/main/java/pl/wavesoftware/eid/exceptions/EidIllegalStateException.java index a2c8b72..1558847 100644 --- a/src/main/java/pl/wavesoftware/eid/exceptions/EidIllegalStateException.java +++ b/src/main/java/pl/wavesoftware/eid/exceptions/EidIllegalStateException.java @@ -1,11 +1,11 @@ /* - * Copyright 2015 Krzysztof Suszyński . + * Copyright (c) 2015 Wave Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -15,81 +15,204 @@ */ package pl.wavesoftware.eid.exceptions; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; + +import javax.annotation.Nullable; + /** - * This class shouldn't be used in any public API or library. It is designed to be used for in-house development - * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + * This exception is Eid version of Java's {@link IllegalStateException} that + * holds an {@link Eid} object. It can be used to process it in application + * central error handler. *

- * This id Eid version of {@link IllegalStateException} + * Caution! This class shouldn't be used in any public API or + * library. It is designed to be used for in-house development of end user + * applications which will report bugs in standardized error pages or post them + * to issue tracker. * * @see IllegalStateException * @see EidRuntimeException * @author Krzysztof Suszynski + * @since 0.1.0 */ public class EidIllegalStateException extends EidRuntimeException { private static final long serialVersionUID = -9876432123423443L; /** - * @see EidRuntimeException#EidRuntimeException(String, String, Throwable) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} - * @param ref see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} + * Constructs a new runtime exception with the specified Exception ID as + * it's detail message, that's {@code new Eid(eid).toString()}. + *

+ * The cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param eid an exception ID as character sequence */ - public EidIllegalStateException(String eid, String ref, Throwable cause) { - super(eid, ref, cause); + public EidIllegalStateException(CharSequence eid) { + super(eid); } /** - * @see EidRuntimeException#EidRuntimeException(String, Throwable) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(String, Throwable)} + * Constructs a new runtime exception with the specified Exception ID and + * detail message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param eid an exception ID as character sequence + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidIllegalStateException(String eid, Throwable cause) { - super(eid, cause); + public EidIllegalStateException(CharSequence eid, String message) { + super(eid, message); } /** - * @see EidRuntimeException#EidRuntimeException(String, String) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, String)} - * @param ref see description on {@link EidRuntimeException#EidRuntimeException(String, String)} + * Constructs a new runtime exception with the specified Eid message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the Eid message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidIllegalStateException(String eid, String ref) { - super(eid, ref); + public EidIllegalStateException(EidMessage message) { + super(message); } /** - * @see EidRuntimeException#EidRuntimeException(Eid, Throwable) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(Eid, Throwable)} + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param eid an exception ID as character sequence + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or */ - public EidIllegalStateException(Eid id, Throwable cause) { - super(id, cause); + public EidIllegalStateException( + CharSequence eid, String message, @Nullable Throwable cause + ) { + super(eid, message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param message the Eid message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidIllegalStateException( + EidMessage message, @Nullable Throwable cause + ) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID and + * cause. + *

+ * A detail message of eid.toString() + (cause==null ? "" : cause.toString()) + * (which typically contains the class and detail message of + * cause). + *

+ * This constructor is useful for runtime exceptions that are little more + * than wrappers for other throwables. + * + * @param eid an exception ID as character sequence + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidIllegalStateException( + CharSequence eid, @Nullable Throwable cause + ) { + super(eid, cause); } /** - * @see EidRuntimeException#EidRuntimeException(Eid) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid)} + * Constructs a new runtime exception with the specified Exception ID as + * it's detail message, that's {@code eid.toString()}. + *

+ * The cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param id an exception ID */ public EidIllegalStateException(Eid id) { super(id); } /** - * @see EidRuntimeException#EidRuntimeException(Eid, String, Object...) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} - * @param messageFormat see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} - * @param parameters see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} + * Constructs a new runtime exception with the specified Exception ID and + * detail message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param id an exception ID + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidIllegalStateException(Eid id, String messageFormat, Object... parameters) { - super(id, messageFormat, parameters); + public EidIllegalStateException(Eid id, String message) { + super(id, message); } /** - * @return {@link IllegalStateException} class + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param id an exception ID + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or */ - @Override - public Class getStandardJdkClass() { - return IllegalStateException.class; + public EidIllegalStateException( + Eid id, String message, @Nullable Throwable cause + ) { + super(id, message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID and + * cause. + *

+ * A detail message of eid.toString() + (cause==null ? "" : cause.toString()) + * (which typically contains the class and detail message of + * cause). + *

+ * This constructor is useful for runtime exceptions that are little more + * than wrappers for other throwables. + * + * @param id an exception ID + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidIllegalStateException(Eid id, @Nullable Throwable cause) { + super(id, cause); } } diff --git a/src/main/java/pl/wavesoftware/eid/exceptions/EidIndexOutOfBoundsException.java b/src/main/java/pl/wavesoftware/eid/exceptions/EidIndexOutOfBoundsException.java index ff0cf14..13be2b1 100644 --- a/src/main/java/pl/wavesoftware/eid/exceptions/EidIndexOutOfBoundsException.java +++ b/src/main/java/pl/wavesoftware/eid/exceptions/EidIndexOutOfBoundsException.java @@ -1,11 +1,11 @@ /* - * Copyright 2015 Krzysztof Suszyński . + * Copyright (c) 2015 Wave Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -15,81 +15,206 @@ */ package pl.wavesoftware.eid.exceptions; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; + +import javax.annotation.Nullable; + /** - * This class shouldn't be used in any public API or library. It is designed to be used for in-house development - * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + * This exception is Eid version of Java's {@link IndexOutOfBoundsException} that + * holds an {@link Eid} object. It can be used to process it in application + * central error handler. *

- * This id Eid version of {@link IndexOutOfBoundsException} + * Caution! This class shouldn't be used in any public API or + * library. It is designed to be used for in-house development of end user + * applications which will report bugs in standardized error pages or post them + * to issue tracker. * * @see IndexOutOfBoundsException * @see EidRuntimeException * @author Krzysztof Suszynski + * @since 0.1.0 */ public class EidIndexOutOfBoundsException extends EidRuntimeException { private static final long serialVersionUID = -9876432123423451L; /** - * @see EidRuntimeException#EidRuntimeException(String, String, Throwable) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} - * @param ref see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} + * Constructs a new runtime exception with the specified Exception ID as + * it's detail message, that's {@code new Eid(eid).toString()}. + *

+ * The cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param eid an exception ID as character sequence */ - public EidIndexOutOfBoundsException(String eid, String ref, Throwable cause) { - super(eid, ref, cause); + public EidIndexOutOfBoundsException(CharSequence eid) { + super(eid); } /** - * @see EidRuntimeException#EidRuntimeException(String, Throwable) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(String, Throwable)} + * Constructs a new runtime exception with the specified Exception ID and + * detail message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param eid an exception ID as character sequence + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidIndexOutOfBoundsException(String eid, Throwable cause) { - super(eid, cause); + public EidIndexOutOfBoundsException(CharSequence eid, String message) { + super(eid, message); } /** - * @see EidRuntimeException#EidRuntimeException(String, String) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, String)} - * @param ref see description on {@link EidRuntimeException#EidRuntimeException(String, String)} + * Constructs a new runtime exception with the specified Eid message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the Eid message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidIndexOutOfBoundsException(String eid, String ref) { - super(eid, ref); + public EidIndexOutOfBoundsException(EidMessage message) { + super(message); } /** - * @see EidRuntimeException#EidRuntimeException(Eid, Throwable) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(Eid, Throwable)} + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param eid an exception ID as character sequence + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or */ - public EidIndexOutOfBoundsException(Eid id, Throwable cause) { - super(id, cause); + public EidIndexOutOfBoundsException( + CharSequence eid, String message, @Nullable Throwable cause + ) { + super(eid, message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param message the Eid message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidIndexOutOfBoundsException( + EidMessage message, @Nullable Throwable cause + ) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID and + * cause. + *

+ * A detail message of eid.toString() + (cause==null ? "" : cause.toString()) + * (which typically contains the class and detail message of + * cause). + *

+ * This constructor is useful for runtime exceptions that are little more + * than wrappers for other throwables. + * + * @param eid an exception ID as character sequence + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidIndexOutOfBoundsException( + CharSequence eid, @Nullable Throwable cause + ) { + super(eid, cause); } /** - * @see EidRuntimeException#EidRuntimeException(Eid) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid)} + * Constructs a new runtime exception with the specified Exception ID as + * it's detail message, that's {@code eid.toString()}. + *

+ * The cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param id an exception ID */ public EidIndexOutOfBoundsException(Eid id) { super(id); } /** - * @see EidRuntimeException#EidRuntimeException(Eid, String, Object...) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} - * @param messageFormat see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} - * @param parameters see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} + * Constructs a new runtime exception with the specified Exception ID and + * detail message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param id an exception ID + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidIndexOutOfBoundsException(Eid id, String messageFormat, Object... parameters) { - super(id, messageFormat, parameters); + public EidIndexOutOfBoundsException(Eid id, String message) { + super(id, message); } /** - * @return {@link IndexOutOfBoundsException} class + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param id an exception ID + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or */ - @Override - public Class getStandardJdkClass() { - return IndexOutOfBoundsException.class; + public EidIndexOutOfBoundsException( + Eid id, String message, @Nullable Throwable cause + ) { + super(id, message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID and + * cause. + *

+ * A detail message of eid.toString() + (cause==null ? "" : cause.toString()) + * (which typically contains the class and detail message of + * cause). + *

+ * This constructor is useful for runtime exceptions that are little more + * than wrappers for other throwables. + * + * @param id an exception ID + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidIndexOutOfBoundsException( + Eid id, @Nullable Throwable cause + ) { + super(id, cause); } } diff --git a/src/main/java/pl/wavesoftware/eid/exceptions/EidNullPointerException.java b/src/main/java/pl/wavesoftware/eid/exceptions/EidNullPointerException.java index 6c04e4d..8a0fe91 100644 --- a/src/main/java/pl/wavesoftware/eid/exceptions/EidNullPointerException.java +++ b/src/main/java/pl/wavesoftware/eid/exceptions/EidNullPointerException.java @@ -1,11 +1,11 @@ /* - * Copyright 2015 Krzysztof Suszyński . + * Copyright (c) 2015 Wave Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -15,81 +15,204 @@ */ package pl.wavesoftware.eid.exceptions; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; + +import javax.annotation.Nullable; + /** - * This class shouldn't be used in any public API or library. It is designed to be used for in-house development - * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + * This exception is Eid version of Java's {@link NullPointerException} that + * holds an {@link Eid} object. It can be used to process it in application + * central error handler. *

- * This id Eid version of {@link NullPointerException} + * Caution! This class shouldn't be used in any public API or + * library. It is designed to be used for in-house development of end user + * applications which will report bugs in standardized error pages or post them + * to issue tracker. * * @see NullPointerException * @see EidRuntimeException * @author Krzysztof Suszynski + * @since 0.1.0 */ public class EidNullPointerException extends EidRuntimeException { private static final long serialVersionUID = -9876432123423469L; /** - * @see EidRuntimeException#EidRuntimeException(String, String, Throwable) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} - * @param ref see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(String, String, Throwable)} + * Constructs a new runtime exception with the specified Exception ID as + * it's detail message, that's {@code new Eid(eid).toString()}. + *

+ * The cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param eid an exception ID as character sequence */ - public EidNullPointerException(String eid, String ref, Throwable cause) { - super(eid, ref, cause); + public EidNullPointerException(CharSequence eid) { + super(eid); } /** - * @see EidRuntimeException#EidRuntimeException(String, Throwable) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(String, Throwable)} + * Constructs a new runtime exception with the specified Exception ID and + * detail message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param eid an exception ID as character sequence + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidNullPointerException(String eid, Throwable cause) { - super(eid, cause); + public EidNullPointerException(CharSequence eid, String message) { + super(eid, message); } /** - * @see EidRuntimeException#EidRuntimeException(String, String) - * @param eid see description on {@link EidRuntimeException#EidRuntimeException(String, String)} - * @param ref see description on {@link EidRuntimeException#EidRuntimeException(String, String)} + * Constructs a new runtime exception with the specified Eid message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the Eid message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidNullPointerException(String eid, String ref) { - super(eid, ref); + public EidNullPointerException(EidMessage message) { + super(message); } /** - * @see EidRuntimeException#EidRuntimeException(Eid, Throwable) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid, Throwable)} - * @param cause see description on {@link EidRuntimeException#EidRuntimeException(Eid, Throwable)} + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param eid an exception ID as character sequence + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or */ - public EidNullPointerException(Eid id, Throwable cause) { - super(id, cause); + public EidNullPointerException( + CharSequence eid, String message, @Nullable Throwable cause + ) { + super(eid, message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param message the Eid message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidNullPointerException( + EidMessage message, @Nullable Throwable cause + ) { + super(message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID and + * cause. + *

+ * A detail message of eid.toString() + (cause==null ? "" : cause.toString()) + * (which typically contains the class and detail message of + * cause). + *

+ * This constructor is useful for runtime exceptions that are little more + * than wrappers for other throwables. + * + * @param eid an exception ID as character sequence + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidNullPointerException( + CharSequence eid, @Nullable Throwable cause + ) { + super(eid, cause); } /** - * @see EidRuntimeException#EidRuntimeException(Eid) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid)} + * Constructs a new runtime exception with the specified Exception ID as + * it's detail message, that's {@code eid.toString()}. + *

+ * The cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param id an exception ID */ public EidNullPointerException(Eid id) { super(id); } /** - * @see EidRuntimeException#EidRuntimeException(Eid, String, Object...) - * @param id see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} - * @param messageFormat see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} - * @param parameters see description on {@link EidRuntimeException#EidRuntimeException(Eid, String, Object...)} + * Constructs a new runtime exception with the specified Exception ID and + * detail message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param id an exception ID + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidNullPointerException(Eid id, String messageFormat, Object... parameters) { - super(id, messageFormat, parameters); + public EidNullPointerException(Eid id, String message) { + super(id, message); } /** - * @return {@link NullPointerException} class + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param id an exception ID + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or */ - @Override - public Class getStandardJdkClass() { - return NullPointerException.class; + public EidNullPointerException( + Eid id, String message, @Nullable Throwable cause + ) { + super(id, message, cause); + } + + /** + * Constructs a new runtime exception with the specified Exception ID and + * cause. + *

+ * A detail message of eid.toString() + (cause==null ? "" : cause.toString()) + * (which typically contains the class and detail message of + * cause). + *

+ * This constructor is useful for runtime exceptions that are little more + * than wrappers for other throwables. + * + * @param id an exception ID + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + */ + public EidNullPointerException(Eid id, @Nullable Throwable cause) { + super(id, cause); } } diff --git a/src/main/java/pl/wavesoftware/eid/exceptions/EidRuntimeException.java b/src/main/java/pl/wavesoftware/eid/exceptions/EidRuntimeException.java index bb4fc35..a3d636d 100644 --- a/src/main/java/pl/wavesoftware/eid/exceptions/EidRuntimeException.java +++ b/src/main/java/pl/wavesoftware/eid/exceptions/EidRuntimeException.java @@ -1,11 +1,11 @@ /* - * Copyright 2015 Krzysztof Suszyński . + * Copyright (c) 2015 Wave Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -15,74 +15,186 @@ */ package pl.wavesoftware.eid.exceptions; +import pl.wavesoftware.eid.api.EidContainer; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; +import pl.wavesoftware.eid.system.EidModule; + +import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Locale; /** - * This class shouldn't be used in any public API or library. It is designed to be used for in-house development - * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. - *

- * This exception class is baseline of all Eid runtime exception classes. It is designed to ease of use and provide strict ID for - * given Exception usage. This approach speed up development of large application and helps support teams to by giving the both - * static and random ID for each possible unpredicted bug. + * This exception class is baseline of all Eid runtime exception classes. It is + * designed to ease of use and provide strict ID for given Exception usage. + * This approach speed up development of large application and helps support + * teams to by giving the both static and random ID for each possible + * unpredicted bug. *

* This is best to use with tools and plugins like - * EidGenerator for Netbeans IDE - *

- * Caution! There is no constructor with just a string, for reason that this forces users to add Eid in all - * places that earlier uses {@link RuntimeException}. + * + * Generating Exception ID number in Intellij IDEA with Live Templates or + * + * EidGenerator for Netbeans IDE + *

+ * Caution! This class shouldn't be used in any public API or + * library. It is designed to be used for in-house development of end user + * applications which will report bugs in standardized error pages or post them + * to issue tracker. *

* For convenience use {@link pl.wavesoftware.eid.utils.EidPreconditions} * * @author Krzysztof Suszynski + * @see pl.wavesoftware.eid.utils.EidPreconditions + * @see Eid + * @since 0.1.0 */ public class EidRuntimeException extends RuntimeException implements EidContainer { - private static final long serialVersionUID = -9876432123423587L; - + private static final long serialVersionUID = 20181029202308L; private final Eid eid; /** - * Constructs a new runtime exception with the specified exception Id and ref code. The cause is not initialized, and may - * subsequently be initialized by a call to {@link #initCause}. + * Constructs a new runtime exception with the specified Exception ID as + * it's detail message, that's {@code new Eid(eid).toString()}. + *

+ * The cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param eid an exception ID as character sequence + */ + public EidRuntimeException(CharSequence eid) { + this( + EidModule.MODULE + .getBinding() + .getFactories() + .getEidFactory() + .create(eid) + ); + } + + /** + * Constructs a new runtime exception with the specified Exception ID and + * detail message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param eid an exception ID as character sequence + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public EidRuntimeException(CharSequence eid, String message) { + this( + EidModule.MODULE + .getBinding() + .getFactories() + .getEidFactory() + .create(eid), + message + ); + } + + /** + * Constructs a new runtime exception with the specified Eid message. + *

+ * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. + * + * @param message the Eid message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public EidRuntimeException(EidMessage message) { + super(message.toString()); + this.eid = message.getEid(); + } + + /** + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. * - * @param eid exception ID - * @param ref the ref code for Eid + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param eid an exception ID as character sequence + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) */ - public EidRuntimeException(String eid, String ref) { - this(new Eid(eid, ref)); + public EidRuntimeException( + CharSequence eid, String message, @Nullable Throwable cause + ) { + this( + EidModule.MODULE + .getBinding() + .getFactories() + .getEidFactory() + .create(eid), + message, + cause + ); } /** - * Constructs a new runtime exception with the specified cause, a exception Id and detail message of - * eid.toString() + " => " + (cause==null ? null : cause.toString()) (which typically contains - * the class and detail message of cause). This constructor is useful for runtime exceptions - * that are little more than wrappers for other throwable. + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. * - * @param eid exception ID - * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null - * value is permitted, and indicates that the cause is nonexistent or unknown.) + * @param message the Eid message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) */ - public EidRuntimeException(String eid, Throwable cause) { - this(new Eid(eid), cause); + public EidRuntimeException(EidMessage message, @Nullable Throwable cause) { + this(message.getEid(), message.getFormattedMessage().toString(), cause); } /** - * Constructs a new runtime exception with the specified a exception Id, ref code and cause. + * Constructs a new runtime exception with the specified Exception ID and + * cause. + *

+ * A detail message of eid.toString() + (cause==null ? "" : cause.toString()) + * (which typically contains the class and detail message of + * cause). + *

+ * This constructor is useful for runtime exceptions that are little more + * than wrappers for other throwables. * - * @param eid exception ID - * @param ref the ref code for Eid - * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is - * permitted, and indicates that the cause is nonexistent or unknown.) + * @param eid an exception ID as character sequence + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) */ - public EidRuntimeException(String eid, String ref, Throwable cause) { - this(new Eid(eid, ref), cause); + public EidRuntimeException(CharSequence eid, @Nullable Throwable cause) { + this( + EidModule.MODULE + .getBinding() + .getFactories() + .getEidFactory() + .create(eid), + cause + ); } /** - * Constructs a new runtime exception with the specified Eid object + * Constructs a new runtime exception with the specified Exception ID as + * it's detail message, that's {@code eid.toString()}. + *

+ * The cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. * - * @param id exception ID + * @param id an exception ID */ public EidRuntimeException(Eid id) { super(id.toString()); @@ -90,35 +202,64 @@ public EidRuntimeException(Eid id) { } /** - * Constructs a new runtime exception with the specified Eid object and cause + * Constructs a new runtime exception with the specified Exception ID and + * detail message. *

- * The detail message is computed as String.format(Eid.getMessageFormat(), id.toString(), message(cause)) + * The cause is not initialized, and may subsequently be initialized by a + * call to {@link #initCause}. * - * @param id exception ID - * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is - * permitted, and indicates that the cause is nonexistent or unknown.) + * @param id an exception ID + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. */ - public EidRuntimeException(Eid id, Throwable cause) { - super(String.format( - Locale.ENGLISH, Eid.getMessageFormat(), id.toString(), message(cause) - ), cause); - eid = id; + public EidRuntimeException(Eid id, String message) { + super(id.message(message).toString()); + this.eid = id; + } + + /** + * Constructs a new runtime exception with the specified Exception ID, + * detail message and cause. + * + *

+ * Note that the detail message associated with cause is + * not automatically incorporated in this runtime exception's + * detail message. + * + * @param id an exception ID + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + */ + public EidRuntimeException( + Eid id, String message, @Nullable Throwable cause + ) { + super(id.message(message).toString(), cause); + this.eid = id; } /** - * Constructs a new runtime exception with specified Eid object and custom message + * Constructs a new runtime exception with the specified Exception ID and + * cause. + *

+ * A detail message of eid.toString() + (cause==null ? "" : cause.toString()) + * (which typically contains the class and detail message of + * cause). *

- * The detail message is computed as: - *

String.format(Eid.getMessageFormat(), id.toString(), String.format(messageFormat, parameters))
- * @param id exception ID - * @param messageFormat message format in form of {@link String#format(String, Object...)} - * @param parameters parameters in form of {@link String#format(String, Object...)} + * This constructor is useful for runtime exceptions that are little more + * than wrappers for other throwables. + * + * @param id an exception ID + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) */ - public EidRuntimeException(Eid id, String messageFormat, Object... parameters) { - super(String.format( - Locale.ENGLISH, Eid.getMessageFormat(), id.toString(), - String.format(Locale.ENGLISH, messageFormat, parameters) - )); + public EidRuntimeException(Eid id, @Nullable Throwable cause) { + super(messageOf(id, cause), cause); eid = id; } @@ -127,18 +268,21 @@ public Eid getEid() { return eid; } - /** - * Returns a standard JDK class that this ones is base on. It doesn't mean this class extends that class. - * - * @return a standard JDK class of exception, in this case {@link RuntimeException} class. - */ - public Class getStandardJdkClass() { - return RuntimeException.class; + private static String messageOf(Eid eid, @Nullable Throwable cause) { + if (cause != null) { + return eid.message(messageOf(cause)).toString(); + } + return eid.toString(); } - private static String message(Throwable cause) { - String msg = coalesce(cause.getLocalizedMessage(), cause.getMessage()); - return coalesce(msg, cause.toString()); + @Nonnull + private static String messageOf(Throwable cause) { + String value = coalesce( + coalesce(cause.getLocalizedMessage(), cause.getMessage()), + cause.toString() + ); + assert value != null : "20181214:234625"; + return value; } @Nullable @@ -149,5 +293,4 @@ private static T coalesce(@Nullable T first, @Nullable T second) { return first; } } - } diff --git a/src/main/java/pl/wavesoftware/eid/exceptions/package-info.java b/src/main/java/pl/wavesoftware/eid/exceptions/package-info.java index 36bcc60..f7abc0c 100644 --- a/src/main/java/pl/wavesoftware/eid/exceptions/package-info.java +++ b/src/main/java/pl/wavesoftware/eid/exceptions/package-info.java @@ -1,7 +1,25 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @author Krzysztof Suszynski * @since 29.03.16 */ @javax.annotation.ParametersAreNonnullByDefault -@pl.wavesoftware.eid.ReturnTypesAreNonnullByDefault +@ReturnTypesAreNonnullByDefault package pl.wavesoftware.eid.exceptions; + +import pl.wavesoftware.eid.api.ReturnTypesAreNonnullByDefault; diff --git a/src/main/java/pl/wavesoftware/eid/impl/BindingImpl.java b/src/main/java/pl/wavesoftware/eid/impl/BindingImpl.java new file mode 100644 index 0000000..39223eb --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/BindingImpl.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Binding; +import pl.wavesoftware.eid.api.ConfigurationSystem; +import pl.wavesoftware.eid.api.EidFactories; + +/** + * An internal implementation. Do not use manually. + *


+ * A default binding implementation. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public final class BindingImpl implements Binding { + + private final ConfigurationSystem system = new ConfigurationSystemImpl(); + private final EidFactories factories = new EidFactoriesImpl(this); + + @Override + public ConfigurationSystem getConfigurationSystem() { + return system; + } + + @Override + public EidFactories getFactories() { + return factories; + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/ConfigurationImpl.java b/src/main/java/pl/wavesoftware/eid/impl/ConfigurationImpl.java new file mode 100644 index 0000000..a1e2247 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/ConfigurationImpl.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Configuration; +import pl.wavesoftware.eid.api.ConfigurationBuilder; +import pl.wavesoftware.eid.api.Formatter; +import pl.wavesoftware.eid.api.UniqueIdGenerator; +import pl.wavesoftware.eid.api.Validator; + +import javax.annotation.Nullable; +import java.util.Locale; +import java.util.TimeZone; + +import static pl.wavesoftware.eid.impl.InternalChecks.checkNotNull; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +final class ConfigurationImpl implements MutableConfiguration { + + private Formatter formatter; + private UniqueIdGenerator generator; + @Nullable + private Validator validator; + @Nullable + private Locale locale; + @Nullable + private TimeZone zone; + + ConfigurationImpl() { + // nothing here + } + + ConfigurationImpl(MutableConfiguration settings) { + checkNotNull(settings, "20181218:002046"); + this.formatter = settings.getFormatter(); + this.generator = settings.getIdGenerator(); + this.validator = settings.getValidator(); + this.locale = settings.getLocale(); + this.zone = settings.getTimeZone(); + } + + @Override + public ConfigurationBuilder uniqueIdGenerator(UniqueIdGenerator generator) { + this.generator = checkNotNull(generator, "20181218:002002"); + return this; + } + + @Override + public ConfigurationBuilder formatter(Formatter formatter) { + this.formatter = checkNotNull(formatter, "20181218:002018"); + return this; + } + + @Override + public ConfigurationBuilder locale(@Nullable Locale locale) { + this.locale = locale; + return this; + } + + @Override + public ConfigurationBuilder timezone(@Nullable TimeZone zone) { + this.zone = zone; + return this; + } + + @Override + public ConfigurationBuilder validator(@Nullable Validator validator) { + this.validator = validator; + return this; + } + + @Override + public Configuration getFutureConfiguration() { + return this; + } + + @Override + public Formatter getFormatter() { + return formatter; + } + + @Override + public UniqueIdGenerator getIdGenerator() { + return generator; + } + + @Nullable + @Override + public Validator getValidator() { + return validator; + } + + @Nullable + @Override + public Locale getLocale() { + return locale; + } + + @Nullable + @Override + public TimeZone getTimeZone() { + return zone; + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/ConfigurationSystemImpl.java b/src/main/java/pl/wavesoftware/eid/impl/ConfigurationSystemImpl.java new file mode 100644 index 0000000..0c94382 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/ConfigurationSystemImpl.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Configuration; +import pl.wavesoftware.eid.api.ConfigurationBuilder; +import pl.wavesoftware.eid.api.ConfigurationSystem; +import pl.wavesoftware.eid.api.Configurator; +import pl.wavesoftware.eid.api.Supplier; + +import java.util.ServiceLoader; + +/** + * @author Krzysztof Suszynski + * @since 2018-10-29 + */ +final class ConfigurationSystemImpl implements ConfigurationSystem { + + private Lazy configuration = + Lazy.of(new MutableConfigurationSupplier()); + + ConfigurationSystemImpl() { + // nothing here + } + + @Override + public Configuration getConfiguration() { + return configuration.get(); + } + + @Override + public Configurator configure(Configurator configurator) { + MutableConfiguration configured = configuration.get(); + MutableConfiguration mutable = new ConfigurationImpl(configured); + configurator.configure(mutable); + configuration = Lazy.of(mutable); + return new RestoreConfigurator(configured); + } + + private static final class MutableConfigurationSupplier + implements Supplier { + + @Override + public MutableConfiguration get() { + return loadConfiguration(); + } + + private static MutableConfiguration loadConfiguration() { + MutableConfiguration mutableConfiguration = new ConfigurationImpl(); + new DefaultConfigurator().configure(mutableConfiguration); + ServiceLoader configurators = + ServiceLoader.load(Configurator.class); + + for (Configurator configurator : configurators) { + configurator.configure(mutableConfiguration); + } + return mutableConfiguration; + } + } + + private static final class RestoreConfigurator + implements Configurator { + private final MutableConfiguration configuration; + + RestoreConfigurator(MutableConfiguration configuration) { + this.configuration = configuration; + } + + /* + Suppress is for forcing nullable values to non null methods + for copy constructor. + */ + @SuppressWarnings("ConstantConditions") + @Override + public void configure(ConfigurationBuilder builder) { + builder.formatter(configuration.getFormatter()) + .uniqueIdGenerator(configuration.getIdGenerator()) + .validator(configuration.getValidator()) + .locale(configuration.getLocale()); + } + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/DefaultConfigurator.java b/src/main/java/pl/wavesoftware/eid/impl/DefaultConfigurator.java new file mode 100644 index 0000000..e66db0c --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/DefaultConfigurator.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Configurator; +import pl.wavesoftware.eid.api.ConfigurationBuilder; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +final class DefaultConfigurator implements Configurator { + @Override + public void configure(ConfigurationBuilder configuration) { + configuration + .formatter(new DefaultFormatter(configuration.getFutureConfiguration())) + .uniqueIdGenerator(new DefaultUniqueIdGenerator()); + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/DefaultEidMessage.java b/src/main/java/pl/wavesoftware/eid/impl/DefaultEidMessage.java new file mode 100644 index 0000000..d4f6631 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/DefaultEidMessage.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Configuration; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; + +import java.io.Serializable; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +final class DefaultEidMessage implements EidMessage, Serializable { + private static final long serialVersionUID = 20181029192322L; + + private final EidTextRepresentation represntation; + + DefaultEidMessage( + Eid eid, + Configuration configuration, + CharSequence messageFormat, + Object[] arguments + ) { + this.represntation = new EidTextRepresentation( + eid, + new TextMessage(configuration, messageFormat, arguments), + configuration + ); + } + + @Override + public int length() { + return represntation.get().length(); + } + + @Override + public char charAt(int index) { + return represntation.get().charAt(index); + } + + @Override + public CharSequence subSequence(int start, int end) { + return represntation.get().subSequence(start, end); + } + + @Override + public Eid getEid() { + return represntation.getEid(); + } + + @Override + public String toString() { + return represntation.get(); + } + + @Override + public CharSequence getFormattedMessage() { + return represntation.getTextMessage().get(); + } + +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/DefaultFormatter.java b/src/main/java/pl/wavesoftware/eid/impl/DefaultFormatter.java new file mode 100644 index 0000000..c1fc2f9 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/DefaultFormatter.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Configuration; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.Formatter; + +import javax.annotation.Nullable; +import java.util.Locale; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +final class DefaultFormatter implements Formatter { + + private static final String FORMAT = "[%s]<%s>"; + private static final String REF_FORMAT = "[%s|%s]<%s>"; + private static final String MSG_FORMAT = "%s => %s"; + + private final Configuration configuration; + + DefaultFormatter(Configuration configuration) { + this.configuration = configuration; + } + + @Override + public String format(Eid eid) { + String fmt; + Object[] params; + if (eid.getRef() == null) { + fmt = FORMAT; + params = new Object[]{ + eid.getId(), + eid.getUnique() + }; + } else { + fmt = REF_FORMAT; + params = new Object[]{ + eid.getId(), + eid.getRef(), + eid.getUnique() + }; + } + java.util.Formatter formatter = getStringFormatter() + .format(fmt, params); + return formatter.toString(); + } + + @Override + public String format(Eid eid, String message) { + return getStringFormatter() + .format( + MSG_FORMAT, + format(eid), + message + ).toString(); + } + + private java.util.Formatter getStringFormatter() { + @Nullable + Locale locale = configuration.getLocale(); + if (locale != null) { + return new java.util.Formatter(locale); + } else { + return new java.util.Formatter(); + } + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/DefaultUniqueIdGenerator.java b/src/main/java/pl/wavesoftware/eid/impl/DefaultUniqueIdGenerator.java new file mode 100644 index 0000000..12cc3f2 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/DefaultUniqueIdGenerator.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.UniqueIdGenerator; + +import java.util.Random; + +/** + * @author Krzysztof Suszynski + */ +final class DefaultUniqueIdGenerator implements UniqueIdGenerator { + + private static final int BASE36 = 36; + private static final int MIN = 60466176; + + private final Random random; + + DefaultUniqueIdGenerator() { + this.random = getUnsecuredFastRandom(); + } + + @Override + public String generateUniqId() { + int calc = random.nextInt(Integer.MAX_VALUE - MIN) + MIN; + return Integer.toString(calc, BASE36); + } + + /* + Using random for speed, security of generating random unique id is + not important. + */ + @SuppressWarnings("squid:S2245") + private static Random getUnsecuredFastRandom() { + return new Random(System.currentTimeMillis()); + } + +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/EidFactoriesImpl.java b/src/main/java/pl/wavesoftware/eid/impl/EidFactoriesImpl.java new file mode 100644 index 0000000..b1c29a5 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/EidFactoriesImpl.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Binding; +import pl.wavesoftware.eid.api.EidFactories; +import pl.wavesoftware.eid.api.EidFactory; +import pl.wavesoftware.eid.api.EidMessageFactory; +import pl.wavesoftware.eid.api.LazyFactory; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-17 + */ +final class EidFactoriesImpl implements EidFactories { + private final EidMessageFactory eidMessageFactory; + private final LazyFactory lazyFactory; + private final EidFactory eidFactory; + + EidFactoriesImpl(Binding binding) { + eidMessageFactory = new EidMessageFactoryImpl(binding); + lazyFactory = new LazyFactoryImpl(); + eidFactory = new EidFactoryImpl(); + } + + @Override + public EidMessageFactory getMessageFactory() { + return eidMessageFactory; + } + + @Override + public LazyFactory getLazyFactory() { + return lazyFactory; + } + + @Override + public EidFactory getEidFactory() { + return eidFactory; + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/EidFactoryImpl.java b/src/main/java/pl/wavesoftware/eid/impl/EidFactoryImpl.java new file mode 100644 index 0000000..b5e1ef3 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/EidFactoryImpl.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.DefaultEid; +import pl.wavesoftware.eid.api.EidFactory; +import pl.wavesoftware.eid.api.Eid; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-17 + */ +final class EidFactoryImpl implements EidFactory { + @Override + public Eid create(CharSequence id) { + return new DefaultEid(id); + } + + @Override + public Eid create(CharSequence id, CharSequence ref) { + return new DefaultEid(id, ref); + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/EidMessageFactoryImpl.java b/src/main/java/pl/wavesoftware/eid/impl/EidMessageFactoryImpl.java new file mode 100644 index 0000000..34cb967 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/EidMessageFactoryImpl.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Binding; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; +import pl.wavesoftware.eid.api.EidMessageFactory; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-17 + */ +final class EidMessageFactoryImpl implements EidMessageFactory { + private final Binding binding; + + EidMessageFactoryImpl(Binding binding) { + this.binding = binding; + } + + @Override + public EidMessage create( + Eid eid, + CharSequence messageTemplate, + Object[] templateArguments + ) { + return new DefaultEidMessage( + eid, + binding.getConfigurationSystem().getConfiguration(), + messageTemplate, + templateArguments + ); + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/EidTextRepresentation.java b/src/main/java/pl/wavesoftware/eid/impl/EidTextRepresentation.java new file mode 100644 index 0000000..52323fe --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/EidTextRepresentation.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Configuration; +import pl.wavesoftware.eid.api.EidContainer; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.Supplier; + +import java.io.Serializable; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +final class EidTextRepresentation implements EidContainer, Serializable { + private static final long serialVersionUID = 20181029231519L; + + private final Eid eid; + private final TextMessage textMessage; + private final SerializableLazy actual; + + EidTextRepresentation( + final Eid eid, + final TextMessage textMessage, + final Configuration configuration + ) { + this.eid = eid; + this.textMessage = textMessage; + this.actual = SerializableLazy.serializableOf(new Supplier() { + @Override + public String get() { + return configuration.getFormatter() + .format(eid, textMessage.get()); + } + }); + } + + @Override + public Eid getEid() { + return eid; + } + + TextMessage getTextMessage() { + return textMessage; + } + + String get() { + return actual.get(); + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/InternalChecks.java b/src/main/java/pl/wavesoftware/eid/impl/InternalChecks.java new file mode 100644 index 0000000..50a5baa --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/InternalChecks.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import javax.annotation.Nullable; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +final class InternalChecks { + private InternalChecks() { + // nothing here + } + + @SuppressWarnings("squid:S1695") + static T checkNotNull(@Nullable T value, String message) { + if (value == null) { + throw new IllegalArgumentException(message); + } + return value; + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/Lazy.java b/src/main/java/pl/wavesoftware/eid/impl/Lazy.java new file mode 100644 index 0000000..6dd95ed --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/Lazy.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Supplier; + +import static pl.wavesoftware.eid.impl.InternalChecks.checkNotNull; + + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +class Lazy implements Supplier { + private volatile Supplier supplier; + private T value; + + Lazy(Supplier supplier) { + this.supplier = checkNotNull(supplier, "20181124:004511"); + } + + protected Lazy() { + // nothing + } + + private Lazy(T value) { + this.value = value; + } + + static Lazy of(Supplier supplier) { + return new Lazy(supplier); + } + + static Lazy of(R value) { + return new Lazy(value); + } + + @Override + public T get() { + if (supplier != null) { + synchronized (this) { + if (supplier != null) { + T calculated = supplier.get(); + supplier = null; + value = calculated; + } + } + } + return value; + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/LazyFactoryImpl.java b/src/main/java/pl/wavesoftware/eid/impl/LazyFactoryImpl.java new file mode 100644 index 0000000..7fa4da8 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/LazyFactoryImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.LazyFactory; +import pl.wavesoftware.eid.api.SerializableSupplier; +import pl.wavesoftware.eid.api.Supplier; + +import java.io.Serializable; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-17 + */ +final class LazyFactoryImpl implements LazyFactory { + @Override + public SerializableSupplier lazy(Supplier supplier) { + return SerializableLazy.serializableOf(supplier); + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/MessageSupplier.java b/src/main/java/pl/wavesoftware/eid/impl/MessageSupplier.java new file mode 100644 index 0000000..1e7b614 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/MessageSupplier.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Configuration; +import pl.wavesoftware.eid.api.Supplier; + +import javax.annotation.Nullable; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.Locale; +import java.util.TimeZone; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +final class MessageSupplier + implements Supplier { + + private final Configuration configuration; + private final CharSequence messageFormat; + private final Object[] arguments; + + MessageSupplier( + Configuration configuration, + CharSequence messageFormat, + Object[] arguments + ) { + this.configuration = configuration; + this.messageFormat = messageFormat; + this.arguments = arguments.clone(); + } + + @Override + public String get() { + return getFormatter().format(arguments); + } + + private MessageFormat getFormatter() { + @Nullable + Locale locale = configuration.getLocale(); + MessageFormat format; + if (locale == null) { + format = new MessageFormat(messageFormat.toString()); + } else { + format = new MessageFormat(messageFormat.toString(), locale); + } + return ensureTimeZone(format); + } + + private MessageFormat ensureTimeZone(MessageFormat messageFormat) { + @Nullable + TimeZone zone = configuration.getTimeZone(); + if (zone != null) { + Object[] formats = messageFormat.getFormats(); + for (Object format : formats) { + if (format instanceof SimpleDateFormat) { + ((SimpleDateFormat) format).setTimeZone(zone); + } + } + } + return messageFormat; + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/MutableConfiguration.java b/src/main/java/pl/wavesoftware/eid/impl/MutableConfiguration.java new file mode 100644 index 0000000..1efea26 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/MutableConfiguration.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.ConfigurationBuilder; +import pl.wavesoftware.eid.api.Configuration; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +interface MutableConfiguration + extends Configuration, ConfigurationBuilder { +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/SerializableLazy.java b/src/main/java/pl/wavesoftware/eid/impl/SerializableLazy.java new file mode 100644 index 0000000..5ca9726 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/SerializableLazy.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.SerializableSupplier; +import pl.wavesoftware.eid.api.Supplier; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * @author Krzysztof Suszynski + * @since 2018-11-24 + */ +final class SerializableLazy + extends Lazy + implements SerializableSupplier { + + private static final long serialVersionUID = 20181124011908L; + private volatile T serializable; + + private SerializableLazy(Supplier supplier) { + super(supplier); + } + + static SerializableLazy serializableOf(Supplier supplier) { + return new SerializableLazy(supplier); + } + + @Override + public T get() { + if (serializable == null) { + synchronized (this) { + if (serializable == null) { + serializable = super.get(); + } + } + } + return serializable; + } + + /** + * Ensures that the value is evaluated before serialization. + * + * @param stream An object serialization stream. + * @throws java.io.IOException If an error occurs writing to the stream. + */ + private void writeObject(ObjectOutputStream stream) throws IOException { + // evaluates the values if it isn't evaluated yet! + get(); + stream.defaultWriteObject(); + } +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/TextMessage.java b/src/main/java/pl/wavesoftware/eid/impl/TextMessage.java new file mode 100644 index 0000000..8df32a5 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/TextMessage.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Configuration; + +import java.io.Serializable; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +final class TextMessage implements Serializable { + private static final long serialVersionUID = 20181029231527L; + + private final SerializableLazy message; + + TextMessage( + Configuration configuration, + CharSequence messageFormat, + Object[] arguments + ) { + message = SerializableLazy.serializableOf(new MessageSupplier( + configuration, messageFormat, arguments + )); + } + + String get() { + return message.get(); + } + +} diff --git a/src/main/java/pl/wavesoftware/eid/impl/package-info.java b/src/main/java/pl/wavesoftware/eid/impl/package-info.java new file mode 100644 index 0000000..b4e7b9c --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/impl/package-info.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +@ReturnTypesAreNonnullByDefault +@ParametersAreNonnullByDefault +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.ReturnTypesAreNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/pl/wavesoftware/eid/package-info.java b/src/main/java/pl/wavesoftware/eid/package-info.java new file mode 100644 index 0000000..0c6dc48 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/package-info.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Krzysztof Suszynski + * @since 2018-10-25 + */ +@ReturnTypesAreNonnullByDefault +@ParametersAreNonnullByDefault +package pl.wavesoftware.eid; + +import pl.wavesoftware.eid.api.ReturnTypesAreNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/pl/wavesoftware/eid/system/BindingChooser.java b/src/main/java/pl/wavesoftware/eid/system/BindingChooser.java new file mode 100644 index 0000000..11fd51d --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/system/BindingChooser.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.system; + +import pl.wavesoftware.eid.api.Binding; +import pl.wavesoftware.eid.impl.BindingImpl; + +import java.io.Serializable; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +final class BindingChooser implements Serializable { + private static final long serialVersionUID = 20181218003610L; + + Binding chooseImplementation(Iterable bindings) { + Binding best = null; + for (Binding bond : bindings) { + if (best == null || !isCoreImplementation(bond)) { + best = bond; + } + } + assert best != null : "20181106:000523"; + return best; + } + + private static boolean isCoreImplementation(Binding bond) { + return bond.getClass() == BindingImpl.class; + } +} diff --git a/src/main/java/pl/wavesoftware/eid/system/EidModule.java b/src/main/java/pl/wavesoftware/eid/system/EidModule.java new file mode 100644 index 0000000..4ef2796 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/system/EidModule.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.system; + +import pl.wavesoftware.eid.api.Binding; + +import java.util.ServiceLoader; + +/** + * Represents a EID library module, and it's configuration binding. + *

+ * Utilizing {@link #getBinding()} method it is possible to reconfigure this + * module to perform differently then the default behavior. + * + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public enum EidModule { + MODULE; + + private final Binding binding; + + EidModule() { + ServiceLoader loader = ServiceLoader.load(Binding.class); + BindingChooser chooser = new BindingChooser(); + binding = chooser.chooseImplementation(loader); + } + + /** + * Provides a binding to Eid library. It can be used to reconfigure + * configuration programmatically. + * + * @return a binding interface + */ + public Binding getBinding() { + return binding; + } +} diff --git a/src/main/java/pl/wavesoftware/eid/system/package-info.java b/src/main/java/pl/wavesoftware/eid/system/package-info.java new file mode 100644 index 0000000..298d604 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/system/package-info.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +@ParametersAreNonnullByDefault +@ReturnTypesAreNonnullByDefault +package pl.wavesoftware.eid.system; + +import pl.wavesoftware.eid.api.ReturnTypesAreNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/pl/wavesoftware/eid/utils/EidExecutions.java b/src/main/java/pl/wavesoftware/eid/utils/EidExecutions.java new file mode 100644 index 0000000..13fff81 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/utils/EidExecutions.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.utils; + +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.exceptions.EidRuntimeException; + +import static pl.wavesoftware.eid.utils.EidUtil.ensureEid; + +/** + *

Functional try to execute blocks

+ * Using functional blocks to handle operations, that are intended to operate + * properly, simplify the code and makes it more readable. It's also good way to + * deal with untested, uncovered {@code catch} blocks. It's easy and gives + * developers nice way of dealing with countless operations that suppose to work + * as intended. + *

+ * Example: + *

+ * InputStream is = EidExecutions.tryToExecute(new UnsafeSupplier<InputStream>() {
+ *     @Override
+ *     public InputStream get() throws IOException {
+ *         return this.getClass().getClassLoader()
+ *             .getResourceAsStream("project.properties");
+ *     }
+ * }, "20150718:121521");
+ * 
+ * + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public final class EidExecutions { + + private EidExecutions() { + // nothing here + } + + /** + * Tries to execute code in given unsafe supplier code block, and if + * exception is thrown, it will gets rethrown as a {@link EidRuntimeException} + * with eid given as a argument. This is because this exception is + * treated as a software bug! + *

+ * Example: + *

+     * Document doc = EidExecutions.tryToExecute(new UnsafeSupplier<Document>}() {
+     *     @Override
+     *     public Document get() throws SAXException, IOException {
+     *         DocumentBuilder docBuilder = ...
+     *         return docBuilder.parse(new InputSource(reader));
+     *     }
+     * }, new Eid("20150718:121521"));
+     * 
+ * + * @param return type + * @param supplier unsafe supplier code to be executed within a try-catch + * block + * @param eid unique developer identifier from date for ex.: + * "20150716:123200" + * @return A block of code return type, if exception is not thrown + * @throws EidRuntimeException if code block thrown any exception, which + * in that case is wrapped in EidRuntimeException + */ + public static R tryToExecute( + final UnsafeSupplier supplier, + final Eid eid + ) { + try { + return supplier.get(); + } catch (Exception throwable) { + throw new EidRuntimeException(ensureEid(eid), throwable); + } + } + + /** + * Tries to execute code in given unsafe procedure code block, and if + * exception is thrown, it will gets rethrown as a {@link EidRuntimeException} + * with eid given as a argument. This is because this exception is treated + * as a software bug! + *

+ * Example: + *

+     * EidExecutions.tryToExecute(new UnsafeProcedure() {
+     *     @Override
+     *     public void execute() throws SQLException {
+     *         stmt.executeQuery(userPersist);
+     *     }
+     * }, new Eid("20151117:184627"));
+     * 
+ * + * @param procedure unsafe procedure code to be executed within a try-catch + * block + * @param eid unique developer identifier from date for ex.: + * "20150716:123200" + * @throws EidRuntimeException if code block thrown any exception, which in + * that case is wrapped in EidRuntimeException + */ + public static void tryToExecute( + final UnsafeProcedure procedure, + final Eid eid + ) { + try { + procedure.execute(); + } catch (Exception throwable) { + throw new EidRuntimeException(ensureEid(eid), throwable); + } + } + + /** + * For more info in JavaDoc see {@link + * EidExecutions#tryToExecute(UnsafeSupplier, Eid)} + *

+ * Please, note that for performance reasons, Eid is not evaluated until + * it's needed. If you are using {@code Validator}, + * please use {@link #tryToExecute(UnsafeSupplier, Eid)} instead. + * + * @param return type + * @param supplier unsafe supplier code to be executed within a try-catch + * block + * @param eid unique developer identifier from date for ex.: + * "20150716:123200" + * @return A block of code return type, if exception is not thrown + * @throws EidRuntimeException if code block thrown any exception, which in + * that case is wrapped in EidRuntimeException + * @see EidExecutions#tryToExecute(UnsafeSupplier, Eid) + */ + public static R tryToExecute( + final UnsafeSupplier supplier, + final String eid + ) { + try { + return supplier.get(); + } catch (Exception throwable) { + throw new EidRuntimeException(ensureEid(eid), throwable); + } + } + + /** + * For more info in JavaDoc see {@link + * EidExecutions#tryToExecute(UnsafeProcedure, Eid)} + *

+ * Please, note that for performance reasons, Eid is not evaluated until + * it's needed. If you are using {@code Validator}, + * please use {@link #tryToExecute(UnsafeProcedure, Eid)} instead. + * + * @param procedure unsafe procedure code to be executed within a try-catch + * block + * @param eid unique developer identifier from date for ex.: + * "20150716:123200" + * @throws EidRuntimeException if code block thrown any exception, which in + * that case is wrapped in EidRuntimeException + * @see EidExecutions#tryToExecute(UnsafeProcedure, Eid) + */ + public static void tryToExecute( + final UnsafeProcedure procedure, + final String eid + ) { + try { + procedure.execute(); + } catch (Exception throwable) { + throw new EidRuntimeException(ensureEid(eid), throwable); + } + } +} diff --git a/src/main/java/pl/wavesoftware/eid/utils/EidPreconditions.java b/src/main/java/pl/wavesoftware/eid/utils/EidPreconditions.java index d19d261..9a0187d 100644 --- a/src/main/java/pl/wavesoftware/eid/utils/EidPreconditions.java +++ b/src/main/java/pl/wavesoftware/eid/utils/EidPreconditions.java @@ -1,11 +1,11 @@ /* - * Copyright 2015 Krzysztof Suszyński . + * Copyright (c) 2015 Wave Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,7 +16,7 @@ package pl.wavesoftware.eid.utils; -import pl.wavesoftware.eid.exceptions.Eid; +import pl.wavesoftware.eid.api.Eid; import pl.wavesoftware.eid.exceptions.EidIllegalArgumentException; import pl.wavesoftware.eid.exceptions.EidIllegalStateException; import pl.wavesoftware.eid.exceptions.EidIndexOutOfBoundsException; @@ -25,26 +25,33 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.text.MessageFormat; + +import static pl.wavesoftware.eid.utils.EidUtil.ensureEid; /** + * This class consists of static convenience methods that help a method or + * constructor check whether it was invoked correctly (whether its + * preconditions have been met). These methods generally accept a + * {@code boolean} expression which is expected to be {@code true} (or in the + * case of {@link #checkNotNull(Object, String)}, an object reference which is + * expected to be non-null). When {@code false} (or {@code null}) is passed + * instead, the {@link EidPreconditions} method throws an unchecked exception, + * which helps the calling method communicate to its caller that + * caller has made a mistake. *

- * This class shouldn't be used in any public API or library. It is designed to be used for in-house - * development of end user applications which will report Bugs in standardized error pages or post them to issue - * tracker. - *

- * Static convenience methods that help a method or constructor check whether it was invoked correctly (whether its - * preconditions have been met). These methods generally accept a {@code boolean} expression which is expected - * to be {@code true} (or in the case of {@link #checkNotNull(Object, String)}, an object reference which is expected - * to be non-null). When {@code false} (or {@code null}) is passed instead, the {@link EidPreconditions} method throws - * an unchecked exception, which helps the calling method communicate to its caller that caller has made - * a mistake. - *

- * Each method accepts a EID String or {@link Eid} object, which is designed to ease of use and provide strict ID for - * given Exception usage. This approach speed up development of large application and helps support teams to by giving + * Each method accepts a EID String or {@link Eid} object, which is designed to + * ease of use and provide strict ID for given Exception usage. This approach + * speed up development of large application and helps support teams to by giving * the both static and random ID for each possible unpredicted bug. *

* This is best to use with tools and plugins like - * EidGenerator for Netbeans IDE + *

*

* Example: *

@@ -64,9 +71,10 @@
  * 
*

* In this example, {@link #checkArgument(boolean, String)} throws an {@link EidIllegalArgumentException} to indicate - * that {@code exampleBadCaller} made an error in its call to {@code sqrt}. Exception, when it will be printed - * will contain user given Eid and also randomly generated ID. Those fields can be displayed to user on error page on - * posted directly to issue tracker. + * that {@code exampleBadCaller} made an error in its call to + * {@code sqrt}. Exception, when it will be printed will contain user given Eid + * and also randomly generated ID. Those fields can be displayed to user on + * error page on posted directly to issue tracker. *

* Example: *

@@ -78,99 +86,129 @@
  *     throw ex;
  * }
  * 
- *

Functional try to execute blocks

- * Using functional blocks to handle operations, that are intended to operate properly, simplify the code and makes it more - * readable. It's also good way to deal with untested, uncovered {@code catch} blocks. It's easy and gives developers nice way of - * dealing with countless operations that suppose to work as intended. - *

- * Example: - *

- * InputStream is = EidPreconditions.tryToExecute(new UnsafeSupplier<InputStream>() {
- *     @Override
- *     public InputStream get() throws IOException {
- *         return this.getClass().getClassLoader()
- *             .getResourceAsStream("project.properties");
- *     }
- * }, "20150718:121521");
- * 
+ * Caution! This class shouldn't be used in any public API or + * library. It is designed to be used for in-house development of end user + * applications which will report bugs in standardized error pages or post them + * to issue tracker. * * @author Krzysztof Suszynski * @since 0.1.0 (idea imported from Guava Library and COI code) */ public final class EidPreconditions { - protected EidPreconditions() { - throw new EidRuntimeException("20150718:083450", "This should not be accessed"); + EidPreconditions() { + throw new EidRuntimeException( + "20150718:083450", "This should not be accessed" + ); } /** - * Ensures the truth of an expression involving one or more parameters to the calling method. + * Ensures the truth of an expression involving one or more parameters to + * the calling method. + *

+ * Please, note that for performance reasons, Eid is not evaluated until + * it's needed. If you are using {@code Validator}, + * please use {@link #checkArgument(boolean, Eid)} instead. * * @param expression a boolean expression - * @param eid the exception ID to use if the check fails; will be converted to - * {@link pl.wavesoftware.eid.exceptions.Eid} + * @param eid the exception ID to use if the check fails; will be + * converted to {@link Eid} * @throws EidIllegalArgumentException if {@code expression} is false */ - public static void checkArgument(final boolean expression, final String eid) { + public static void checkArgument( + final boolean expression, + final String eid + ) { if (!expression) { throw new EidIllegalArgumentException(ensureEid(eid)); } } /** - * Ensures the truth of an expression involving one or more parameters to the calling method. + * Ensures the truth of an expression involving one or more parameters to + * the calling method. + *

+ * Please, note that for performance reasons, Eid is not evaluated until + * it's needed. If you are using {@code Validator}, + * please use {@link #checkArgument(boolean, Eid, String, Object[])} instead. * * @param expression a boolean expression - * @param eid the exception ID to use if the check fails; will be converted to - * {@link pl.wavesoftware.eid.exceptions.Eid} - * @param messageFormat message format in form of {@link String#format(String, Object...)} - * @param parameters parameters fo message format in for of {@link String#format(String, Object...)} + * @param eid the exception ID to use if the check fails; will be + * converted to {@link Eid} + * @param messageFormat message format in form accepted by + * {@link MessageFormat#format(String, Object...)} + * @param parameters parameters fo message format in accepted by + * {@link MessageFormat#format(String, Object...)} * @throws EidIllegalArgumentException if {@code expression} is false */ - public static void checkArgument(final boolean expression, final String eid, - final String messageFormat, final Object... parameters) { + public static void checkArgument( + final boolean expression, + final String eid, + final String messageFormat, + final Object... parameters + ) { if (!expression) { - throw new EidIllegalArgumentException(ensureEid(eid), messageFormat, parameters); + throw new EidIllegalArgumentException( + ensureEid(eid).message(messageFormat, parameters) + ); } } /** - * Ensures the truth of an expression involving one or more parameters to the calling method. + * Ensures the truth of an expression involving one or more parameters to + * the calling method. * * @param expression a boolean expression - * @param eid the exception ID to use if the check fails; will be converted to - * {@link pl.wavesoftware.eid.exceptions.Eid} + * @param eid the exception ID to use if the check fails; will be + * converted to {@link Eid} * @throws EidIllegalArgumentException if {@code expression} is false */ - public static void checkArgument(final boolean expression, final Eid eid) { + public static void checkArgument( + final boolean expression, + final Eid eid + ) { if (!expression) { throw new EidIllegalArgumentException(ensureEid(eid)); } } /** - * Ensures the truth of an expression involving one or more parameters to the calling method. + * Ensures the truth of an expression involving one or more parameters to + * the calling method. * * @param expression a boolean expression - * @param eid the exception ID to use if the check fails; will be converted to - * {@link pl.wavesoftware.eid.exceptions.Eid} - * @param messageFormat message format in form of {@link String#format(String, Object...)} - * @param parameters parameters fo message format in for of {@link String#format(String, Object...)} + * @param eid the exception ID to use if the check fails; will be + * converted to {@link Eid} + * @param messageFormat message format in form accepted by + * {@link MessageFormat#format(String, Object...)} + * @param parameters parameters fo message format in accepted by + * {@link MessageFormat#format(String, Object...)} * @throws EidIllegalArgumentException if {@code expression} is false */ - public static void checkArgument(final boolean expression, final Eid eid, - final String messageFormat, final Object... parameters) { + public static void checkArgument( + final boolean expression, + final Eid eid, + final String messageFormat, + final Object... parameters + ) { if (!expression) { - throw new EidIllegalArgumentException(ensureEid(eid), messageFormat, parameters); + throw new EidIllegalArgumentException( + ensureEid(eid).message(messageFormat, parameters) + ); } } /** - * Ensures the truth of an expression involving the state of the calling instance, but not involving any parameters to the - * calling method. + * Ensures the truth of an expression involving the state of the calling + * instance, but not involving any parameters to the calling method. + *

+ * Please, note that for performance reasons, Eid is not evaluated until + * it's needed. If you are using {@code Validator}, + * please use {@link #checkState(boolean, Eid)} instead. * * @param expression a boolean expression - * @param eid the exception message to use if the check fails; will be converted to a string using + * @param eid the exception message to use if the check fails; will + * be converted to a string using * {@link String#valueOf(Object)} * @throws EidIllegalStateException if {@code expression} is false */ @@ -181,67 +219,99 @@ public static void checkState(final boolean expression, final String eid) { } /** - * Ensures the truth of an expression involving the state of the calling instance, but not involving any parameters to the - * calling method. + * Ensures the truth of an expression involving the state of the calling + * instance, but not involving any parameters to the calling method. + *

+ * Please, note that for performance reasons, Eid is not evaluated until + * it's needed. If you are using {@code Validator}, + * please use {@link #checkState(boolean, Eid, String, Object[])} instead. * * @param expression a boolean expression - * @param eid the exception message to use if the check fails; will be converted to a string using + * @param eid the exception message to use if the check fails; + * will be converted to a string using * {@link String#valueOf(Object)} - * @param messageFormat message format in form of {@link String#format(String, Object...)} - * @param parameters parameters fo message format in for of {@link String#format(String, Object...)} + * @param messageFormat message format in form accepted by + * {@link MessageFormat#format(String, Object...)} + * @param parameters parameters fo message format in accepted by + * {@link MessageFormat#format(String, Object...)} * @throws EidIllegalStateException if {@code expression} is false */ - public static void checkState(final boolean expression, final String eid, - final String messageFormat, final Object... parameters) { + public static void checkState( + final boolean expression, + final String eid, + final String messageFormat, + final Object... parameters + ) { if (!expression) { - throw new EidIllegalStateException(ensureEid(eid), messageFormat, parameters); + throw new EidIllegalStateException( + ensureEid(eid).message(messageFormat, parameters) + ); } } /** - * Ensures the truth of an expression involving the state of the calling instance, but not involving any parameters to the - * calling method. + * Ensures the truth of an expression involving the state of the calling + * instance, but not involving any parameters to the calling method. * * @param expression a boolean expression - * @param eid the exception message to use if the check fails; will be converted to a string using + * @param eid the exception message to use if the check fails; will + * be converted to a string using * {@link String#valueOf(Object)} * @throws EidIllegalStateException if {@code expression} is false */ - public static void checkState(final Boolean expression, final Eid eid) { + public static void checkState(final boolean expression, final Eid eid) { if (!expression) { throw new EidIllegalStateException(ensureEid(eid)); } } /** - * Ensures the truth of an expression involving the state of the calling instance, but not involving any parameters to the - * calling method. + * Ensures the truth of an expression involving the state of the calling + * instance, but not involving any parameters to the calling method. * * @param expression a boolean expression - * @param eid the exception message to use if the check fails; will be converted to a string using + * @param eid the exception message to use if the check fails; + * will be converted to a string using * {@link String#valueOf(Object)} - * @param messageFormat message format in form of {@link String#format(String, Object...)} - * @param parameters parameters fo message format in for of {@link String#format(String, Object...)} + * @param messageFormat message format in form accepted by + * {@link MessageFormat#format(String, Object...)} + * @param parameters parameters fo message format in accepted by + * {@link MessageFormat#format(String, Object...)} * @throws EidIllegalStateException if {@code expression} is false */ - public static void checkState(final boolean expression, final Eid eid, - final String messageFormat, final Object... parameters) { + public static void checkState( + final boolean expression, + final Eid eid, + final String messageFormat, + final Object... parameters + ) { if (!expression) { - throw new EidIllegalStateException(ensureEid(eid), messageFormat, parameters); + throw new EidIllegalStateException( + ensureEid(eid).message(messageFormat, parameters) + ); } } /** - * Ensures that an object reference passed as a parameter to the calling method is not null. + * Ensures that an object reference passed as a parameter to the calling + * method is not null. + *

+ * Please, note that for performance reasons, Eid is not evaluated until + * it's needed. If you are using {@code Validator}, + * please use {@link #checkNotNull(Object, Eid)} instead. * * @param type of object reference being checked * @param reference an object reference - * @param eid the exception message to use if the check fails; will be converted to a string using + * @param eid the exception message to use if the check fails; will be + * converted to a string using * {@link String#valueOf(Object)} * @return the non-null reference that was validated * @throws EidNullPointerException if {@code reference} is null */ - public static T checkNotNull(@Nullable final T reference, final String eid) { + public static T checkNotNull( + @Nullable final T reference, + final String eid + ) { if (reference == null) { throw new EidNullPointerException(ensureEid(eid)); } @@ -249,36 +319,55 @@ public static T checkNotNull(@Nullable final T reference, final String eid) } /** - * Ensures that an object reference passed as a parameter to the calling method is not null. + * Ensures that an object reference passed as a parameter to the calling + * method is not null. + *

+ * Please, note that for performance reasons, Eid is not evaluated until + * it's needed. If you are using {@code Validator}, + * please use {@link #checkNotNull(Object, Eid, String, Object[])} instead. * * @param type of object reference being checked * @param reference an object reference - * @param eid the exception message to use if the check fails; will be converted to a string using + * @param eid the exception message to use if the check fails; + * will be converted to a string using * {@link String#valueOf(Object)} - * @param messageFormat message format in form of {@link String#format(String, Object...)} - * @param parameters parameters fo message format in for of {@link String#format(String, Object...)} + * @param messageFormat message format in form accepted by + * {@link MessageFormat#format(String, Object...)} + * @param parameters parameters fo message format in accepted by + * {@link MessageFormat#format(String, Object...)} * @return the non-null reference that was validated * @throws EidNullPointerException if {@code reference} is null */ - public static T checkNotNull(@Nullable final T reference, final String eid, - final String messageFormat, final Object... parameters) { + public static T checkNotNull( + @Nullable final T reference, + final String eid, + final String messageFormat, + final Object... parameters + ) { if (reference == null) { - throw new EidNullPointerException(ensureEid(eid), messageFormat, parameters); + throw new EidNullPointerException( + ensureEid(eid).message(messageFormat, parameters) + ); } return reference; } /** - * Ensures that an object reference passed as a parameter to the calling method is not null. + * Ensures that an object reference passed as a parameter to the calling + * method is not null. * * @param type of object reference being checked * @param reference an object reference - * @param eid the exception message to use if the check fails; will be converted to a string using + * @param eid the exception message to use if the check fails; will + * be converted to a string using * {@link String#valueOf(Object)} * @return the non-null reference that was validated * @throws EidNullPointerException if {@code reference} is null */ - public static T checkNotNull(@Nullable final T reference, final Eid eid) { + public static T checkNotNull( + @Nullable final T reference, + final Eid eid + ) { if (reference == null) { throw new EidNullPointerException(ensureEid(eid)); } @@ -286,35 +375,52 @@ public static T checkNotNull(@Nullable final T reference, final Eid eid) { } /** - * Ensures that an object reference passed as a parameter to the calling method is not null. + * Ensures that an object reference passed as a parameter to the calling + * method is not null. * * @param type of object reference being checked * @param reference an object reference - * @param eid the exception message to use if the check fails; will be converted to a string using + * @param eid the exception message to use if the check fails; + * will be converted to a string using * {@link String#valueOf(Object)} - * @param messageFormat message format in form of {@link String#format(String, Object...)} - * @param parameters parameters fo message format in for of {@link String#format(String, Object...)} + * @param messageFormat message format in form accepted by + * {@link MessageFormat#format(String, Object...)} + * @param parameters parameters fo message format in accepted by + * {@link MessageFormat#format(String, Object...)} * @return the non-null reference that was validated * @throws EidNullPointerException if {@code reference} is null */ @Nonnull - public static T checkNotNull(@Nullable final T reference, final Eid eid, - final String messageFormat, final Object... parameters) { + public static T checkNotNull( + @Nullable final T reference, + final Eid eid, + final String messageFormat, + final Object... parameters + ) { if (reference == null) { - throw new EidNullPointerException(ensureEid(eid), messageFormat, parameters); + throw new EidNullPointerException( + ensureEid(eid).message(messageFormat, parameters) + ); } return reference; } /** - * Ensures that {@code index} specifies a valid element in an array, list or string of size {@code size}. An element - * index may range from zero, inclusive, to {@code size}, exclusive. + * Ensures that {@code index} specifies a valid element in an array, + * list or string of size {@code size}. An element index may range from + * zero, inclusive, to {@code size}, exclusive. + *

+ * Please, note that for performance reasons, Eid is not evaluated until + * it's needed. If you are using {@code Validator}, + * please use {@link #checkElementIndex(int, int, Eid)} instead. * - * @param index a user-supplied index identifying an element of an array, list or string + * @param index a user-supplied index identifying an element of an array, + * list or string * @param size the size of that array, list or string * @param eid the text to use to describe this index in an error message * @return the value of {@code index} - * @throws EidIndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} + * @throws EidIndexOutOfBoundsException if {@code index} is negative or is + * not less than {@code size} * @throws EidIllegalArgumentException if {@code size} is negative */ public static int checkElementIndex(int index, int size, final String eid) { @@ -328,38 +434,61 @@ public static int checkElementIndex(int index, int size, final String eid) { } /** - * Ensures that {@code index} specifies a valid element in an array, list or string of size {@code size}. An element - * index may range from zero, inclusive, to {@code size}, exclusive. + * Ensures that {@code index} specifies a valid element in an array, + * list or string of size {@code size}. An element index may range from + * zero, inclusive, to {@code size}, exclusive. + *

+ * Please, note that for performance reasons, Eid is not evaluated until + * it's needed. If you are using {@code Validator}, + * please use {@link #checkElementIndex(int, int, Eid, String, Object[])} + * instead. * - * @param index a user-supplied index identifying an element of an array, list or string + * @param index a user-supplied index identifying an element of an + * array, list or string * @param size the size of that array, list or string - * @param eid the text to use to describe this index in an error message - * @param messageFormat message format in form of {@link String#format(String, Object...)} - * @param parameters parameters fo message format in for of {@link String#format(String, Object...)} + * @param eid the text to use to describe this index in an error + * message + * @param messageFormat message format in form accepted by + * {@link MessageFormat#format(String, Object...)} + * @param parameters parameters fo message format in accepted by + * {@link MessageFormat#format(String, Object...)} * @return the value of {@code index} - * @throws EidIndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} + * @throws EidIndexOutOfBoundsException if {@code index} is negative or + * isn't less than {@code size} * @throws EidIllegalArgumentException if {@code size} is negative */ - public static int checkElementIndex(int index, int size, final String eid, - final String messageFormat, final Object... parameters) { + public static int checkElementIndex( + int index, + int size, + final String eid, + final String messageFormat, + final Object... parameters + ) { if (isSizeIllegal(size)) { - throw new EidIllegalArgumentException(ensureEid(eid), messageFormat, parameters); + throw new EidIllegalArgumentException( + ensureEid(eid).message(messageFormat, parameters) + ); } if (isIndexAndSizeIllegal(index, size)) { - throw new EidIndexOutOfBoundsException(ensureEid(eid), messageFormat, parameters); + throw new EidIndexOutOfBoundsException( + ensureEid(eid).message(messageFormat, parameters) + ); } return index; } /** - * Ensures that {@code index} specifies a valid element in an array, list or string of size {@code size}. An element - * index may range from zero, inclusive, to {@code size}, exclusive. + * Ensures that {@code index} specifies a valid element in an array, + * list or string of size {@code size}. An element index may range from + * zero, inclusive, to {@code size}, exclusive. * - * @param index a user-supplied index identifying an element of an array, list or string + * @param index a user-supplied index identifying an element of an array, + * list or string * @param size the size of that array, list or string * @param eid the text to use to describe this index in an error message * @return the value of {@code index} - * @throws EidIndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} + * @throws EidIndexOutOfBoundsException if {@code index} is negative or is + * not less than {@code size} * @throws EidIllegalArgumentException if {@code size} is negative */ public static int checkElementIndex(int index, int size, final Eid eid) { @@ -373,170 +502,49 @@ public static int checkElementIndex(int index, int size, final Eid eid) { } /** - * Ensures that {@code index} specifies a valid element in an array, list or string of size {@code size}. An element + * Ensures that {@code index} specifies a valid element in an array, + * list or string of size {@code size}. An element * index may range from zero, inclusive, to {@code size}, exclusive. * - * @param index a user-supplied index identifying an element of an array, list or string + * @param index a user-supplied index identifying an element of an + * array, list or string * @param size the size of that array, list or string - * @param eid the text to use to describe this index in an error message - * @param messageFormat message format in form of {@link String#format(String, Object...)} - * @param parameters parameters fo message format in for of {@link String#format(String, Object...)} + * @param eid the text to use to describe this index in an error + * message + * @param messageFormat message format in form accepted by + * {@link MessageFormat#format(String, Object...)} + * @param parameters parameters fo message format in accepted by + * {@link MessageFormat#format(String, Object...)} * @return the value of {@code index} - * @throws EidIndexOutOfBoundsException if {@code index} is negative or is not less than {@code size} + * @throws EidIndexOutOfBoundsException if {@code index} is negative or is + * not less than {@code size} * @throws EidIllegalArgumentException if {@code size} is negative */ - public static int checkElementIndex(int index, int size, final Eid eid, final String messageFormat, - final Object... parameters) { + public static int checkElementIndex( + int index, + int size, + final Eid eid, + final String messageFormat, + final Object... parameters + ) { if (isSizeIllegal(size)) { - throw new EidIllegalArgumentException(ensureEid(eid), messageFormat, parameters); + throw new EidIllegalArgumentException( + ensureEid(eid).message(messageFormat, parameters) + ); } if (isIndexAndSizeIllegal(index, size)) { - throw new EidIndexOutOfBoundsException(ensureEid(eid), messageFormat, parameters); + throw new EidIndexOutOfBoundsException( + ensureEid(eid).message(messageFormat, parameters) + ); } return index; } private static boolean isIndexAndSizeIllegal(int index, int size) { - return index < 0 || index > size; + return index < 0 || index >= size; } private static boolean isSizeIllegal(int size) { return size < 0; } - - /** - * For more info in JavaDoc see {@link EidPreconditions#tryToExecute(UnsafeSupplier, Eid)} - * - * @param return type - * @param supplier unsafe supplier code to be executed within a try-catch block - * @param eid unique developer identifier from date for ex.: "20150716:123200" - * @return A block of code return type, if exception is not thrown - * @throws EidRuntimeException if code block thrown any exception, which in that case is wrapped in EidRuntimeException - * @see EidPreconditions#tryToExecute(UnsafeSupplier, Eid) - */ - public static R tryToExecute(final UnsafeSupplier supplier, final String eid) { - try { - return supplier.get(); - } catch (Exception throwable) { - throw new EidRuntimeException(ensureEid(eid), throwable); - } - } - - /** - * For more info in JavaDoc see {@link EidPreconditions#tryToExecute(UnsafeProcedure, Eid)} - * - * @param procedure unsafe procedure code to be executed within a try-catch block - * @param eid unique developer identifier from date for ex.: "20150716:123200" - * @throws EidRuntimeException if code block thrown any exception, which in that case is wrapped in EidRuntimeException - * @see EidPreconditions#tryToExecute(UnsafeProcedure, Eid) - */ - public static void tryToExecute(final UnsafeProcedure procedure, final String eid) { - try { - procedure.execute(); - } catch (Exception throwable) { - throw new EidRuntimeException(ensureEid(eid), throwable); - } - } - - /** - * Tries to execute code in given unsafe supplier code block, and if exception is thrown, it will gets rethrown as a - * {@link EidRuntimeException} with eid given as a argument. This is because this exception is threaded as a software bug! - *

- * Example: - *

-     * Document doc = EidPreconditions.tryToExecute(new UnsafeSupplier<Document>}() {
-     *     @Override
-     *     public Document get() throws SAXException, IOException {
-     *         DocumentBuilder docBuilder = ...
-     *         return docBuilder.parse(new InputSource(reader));
-     *     }
-     * }, new Eid("20150718:121521"));
-     * 
- * - * @param return type - * @param supplier unsafe supplier code to be executed within a try-catch block - * @param eid unique developer identifier from date for ex.: "20150716:123200" - * @return A block of code return type, if exception is not thrown - * @throws EidRuntimeException if code block thrown any exception, which in that case is wrapped in EidRuntimeException - */ - public static R tryToExecute(final UnsafeSupplier supplier, final Eid eid) { - try { - return supplier.get(); - } catch (Exception throwable) { - throw new EidRuntimeException(ensureEid(eid), throwable); - } - } - - /** - * Tries to execute code in given unsafe procedure code block, and if exception is thrown, it will gets rethrown as a - * {@link EidRuntimeException} with eid given as a argument. This is because this exception is threaded as a software bug! - *

- * Example: - *

-     * EidPreconditions.tryToExecute(new UnsafeProcedure() {
-     *     @Override
-     *     public void execute() throws EJBException {
-     *         em.persist(user);
-     *     }
-     * }, new Eid("20151117:184627"));
-     * 
- * - * @param procedure unsafe procedure code to be executed within a try-catch block - * @param eid unique developer identifier from date for ex.: "20150716:123200" - * @throws EidRuntimeException if code block thrown any exception, which in that case is wrapped in EidRuntimeException - */ - public static void tryToExecute(final UnsafeProcedure procedure, final Eid eid) { - try { - procedure.execute(); - } catch (Exception throwable) { - throw new EidRuntimeException(ensureEid(eid), throwable); - } - } - - /** - * This unsafe supplier can be used to execute a code block that needs to return some value and can throw some checked - * Exceptions, that you would like not to process, because they are unrecoverable bugs. To be used with - * {@link EidPreconditions#tryToExecute(UnsafeSupplier, Eid)} or - * {@link EidPreconditions#tryToExecute(UnsafeSupplier, String)} methods - * - * @param a return type from unsafe supplier - */ - public interface UnsafeSupplier { - /** - * Executes a supplier function that can throw a checked exception to be cough - * - * @return a return value from unsafe supplier function - * @throws Exception this exception should be set to concrete one ex. IOException - */ - T get() throws Exception; - } - - /** - * This unsafe procedure can be used to execute a code block that can throw some checked Exceptions, that you would - * like not to process, because they are unrecoverable bugs. To be used with - * {@link EidPreconditions#tryToExecute(UnsafeProcedure, Eid)} or - * {@link EidPreconditions#tryToExecute(UnsafeProcedure, String)} methods. - */ - public interface UnsafeProcedure { - /** - * Executes a procedure code that can throw a checked exception to be cough - * - * @throws Exception this exception should be set to concrete one ex. IOException - */ - void execute() throws Exception; - } - - private static Eid ensureEid(@Nullable Eid eid) { - if (eid == null) { - return new Eid("20160329:132823", "EID-NULL"); - } - return eid; - } - - private static Eid ensureEid(@Nullable String eid) { - if (eid == null) { - return new Eid("20160329:133052", "EID-NULL"); - } - return new Eid(eid); - } } diff --git a/src/main/java/pl/wavesoftware/eid/utils/EidUtil.java b/src/main/java/pl/wavesoftware/eid/utils/EidUtil.java new file mode 100644 index 0000000..378909a --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/utils/EidUtil.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.utils; + +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.system.EidModule; + +import javax.annotation.Nullable; + +/** + * @author Krzysztof Suszynski + * @since 2018-10-29 + */ +final class EidUtil { + private EidUtil() { + // nothing here + } + + static Eid ensureEid(@Nullable Eid eid) { + if (eid == null) { + return EidModule.MODULE + .getBinding() + .getFactories() + .getEidFactory() + .create("20160329:132823", "EID-NULL"); + } + return eid; + } + + static Eid ensureEid(@Nullable String eid) { + if (eid == null) { + return EidModule.MODULE + .getBinding() + .getFactories() + .getEidFactory() + .create("20160329:133052", "EID-NULL"); + } + return EidModule.MODULE + .getBinding() + .getFactories() + .getEidFactory() + .create(eid); + } +} diff --git a/src/main/java/pl/wavesoftware/eid/utils/UnsafeProcedure.java b/src/main/java/pl/wavesoftware/eid/utils/UnsafeProcedure.java new file mode 100644 index 0000000..6934ee4 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/utils/UnsafeProcedure.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.utils; + +import pl.wavesoftware.eid.api.Eid; + +/** + * This unsafe procedure can be used to execute a code block that can throw + * some checked Exception, that you would like not to process, because they + * are unrecoverable bugs. + *

+ * To be used with + * {@link EidExecutions#tryToExecute(UnsafeProcedure, Eid)} or + * {@link EidExecutions#tryToExecute(UnsafeProcedure, String)} methods. + */ +public interface UnsafeProcedure { + /** + * Executes a procedure code that can throw a checked exception to be cough + * + * @throws Exception this exception should be set to concrete one ex. IOException + */ + @SuppressWarnings("squid:S00112") + void execute() throws Exception; +} diff --git a/src/main/java/pl/wavesoftware/eid/utils/UnsafeSupplier.java b/src/main/java/pl/wavesoftware/eid/utils/UnsafeSupplier.java new file mode 100644 index 0000000..2898af9 --- /dev/null +++ b/src/main/java/pl/wavesoftware/eid/utils/UnsafeSupplier.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.utils; + +import pl.wavesoftware.eid.api.Eid; + +/** + * This unsafe supplier can be used to execute a code block that needs to + * return some value and can throw some checked Exception, that you would like + * not to process, because they are unrecoverable bugs. + *

+ * To be used with + * {@link EidExecutions#tryToExecute(UnsafeSupplier, Eid)} or + * {@link EidExecutions#tryToExecute(UnsafeSupplier, String)} methods + * + * @param a return type from unsafe supplier + */ +public interface UnsafeSupplier { + /** + * Executes a supplier function that can throw a checked exception to be cough + * + * @return a return value from unsafe supplier function + * @throws Exception this exception should be set to concrete one ex. IOException + */ + @SuppressWarnings("squid:S00112") + T get() throws Exception; +} diff --git a/src/main/java/pl/wavesoftware/eid/utils/package-info.java b/src/main/java/pl/wavesoftware/eid/utils/package-info.java index 003b568..1cd3f35 100644 --- a/src/main/java/pl/wavesoftware/eid/utils/package-info.java +++ b/src/main/java/pl/wavesoftware/eid/utils/package-info.java @@ -1,7 +1,25 @@ +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /** * @author Krzysztof Suszynski * @since 2016-03-26 */ @javax.annotation.ParametersAreNonnullByDefault -@pl.wavesoftware.eid.ReturnTypesAreNonnullByDefault +@ReturnTypesAreNonnullByDefault package pl.wavesoftware.eid.utils; + +import pl.wavesoftware.eid.api.ReturnTypesAreNonnullByDefault; diff --git a/src/main/resources/META-INF/services/pl.wavesoftware.eid.api.Binding b/src/main/resources/META-INF/services/pl.wavesoftware.eid.api.Binding new file mode 100644 index 0000000..534eb01 --- /dev/null +++ b/src/main/resources/META-INF/services/pl.wavesoftware.eid.api.Binding @@ -0,0 +1,17 @@ +# +# Copyright (c) 2018 Wave Software +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +pl.wavesoftware.eid.impl.BindingImpl diff --git a/src/test/groovy/verify-sonar-issues.groovy b/src/test/groovy/verify-sonar-issues.groovy index 2440b53..798a3a6 100644 --- a/src/test/groovy/verify-sonar-issues.groovy +++ b/src/test/groovy/verify-sonar-issues.groovy @@ -1,9 +1,25 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import groovy.json.JsonSlurper String skip = properties.getAt('sonar.skip') if (skip == 'true') { log.info('sonar.skip = true: Skipping Sonar issues file analysis.') - return; + return } String issueFile = properties.getAt('sonar.issues.file') filepath = new File(issueFile) diff --git a/src/test/java/pl/wavesoftware/eid/ConfigurationContext.java b/src/test/java/pl/wavesoftware/eid/ConfigurationContext.java new file mode 100644 index 0000000..cb34e84 --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/ConfigurationContext.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid; + +import pl.wavesoftware.eid.api.Configurator; +import pl.wavesoftware.eid.system.EidModule; + +import java.io.Closeable; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-18 + */ +final class ConfigurationContext implements Closeable { + + private final Configurator saved; + + ConfigurationContext(Configurator configurator) { + this.saved = EidModule.MODULE + .getBinding() + .getConfigurationSystem() + .configure(configurator); + } + + @Override + public void close() { + EidModule.MODULE + .getBinding() + .getConfigurationSystem() + .configure(saved); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/ConfiguratorRule.java b/src/test/java/pl/wavesoftware/eid/ConfiguratorRule.java new file mode 100644 index 0000000..4247865 --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/ConfiguratorRule.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import pl.wavesoftware.eid.api.Configurator; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-17 + */ +public class ConfiguratorRule implements TestRule { + + private final Configurator configurator; + + public ConfiguratorRule(Configurator configurator) { + this.configurator = configurator; + } + + @Override + public Statement apply(final Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + ConfigurationContext context = + new ConfigurationContext(configurator); + try { + base.evaluate(); + } finally { + context.close(); + } + } + }; + } +} diff --git a/src/test/java/pl/wavesoftware/eid/ConstantUniqueIdRule.java b/src/test/java/pl/wavesoftware/eid/ConstantUniqueIdRule.java new file mode 100644 index 0000000..80b30e0 --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/ConstantUniqueIdRule.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid; + +import pl.wavesoftware.eid.api.ConfigurationBuilder; +import pl.wavesoftware.eid.api.Configurator; +import pl.wavesoftware.eid.api.UniqueIdGenerator; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public final class ConstantUniqueIdRule extends ConfiguratorRule { + + public ConstantUniqueIdRule(final String constantId) { + super(new Configurator() { + @Override + public void configure(ConfigurationBuilder configuration) { + configuration.uniqueIdGenerator(new UniqueIdGenerator() { + @Override + public String generateUniqId() { + return constantId; + } + }); + } + }); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/DisableValidatorState.java b/src/test/java/pl/wavesoftware/eid/DisableValidatorState.java new file mode 100644 index 0000000..5237d1f --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/DisableValidatorState.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid; + +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.TearDown; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import pl.wavesoftware.eid.api.ConfigurationBuilder; +import pl.wavesoftware.eid.api.Configurator; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-18 + */ +@State(Scope.Benchmark) +public class DisableValidatorState { + private static final Logger LOGGER = + LoggerFactory.getLogger(DisableValidatorState.class); + private ConfigurationContext context; + + @Setup + public void setup() { + context = + new ConfigurationContext(new Configurator() { + @Override + public void configure(ConfigurationBuilder configuration) { + configuration.validator(null); + LOGGER.debug("Disable validation of Eid numbers"); + } + }); + } + + @TearDown + public void tearDown() { + context.close(); + LOGGER.debug("Restoring configuration context"); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/exceptions/EidIT.java b/src/test/java/pl/wavesoftware/eid/EidIT.java similarity index 61% rename from src/test/java/pl/wavesoftware/eid/exceptions/EidIT.java rename to src/test/java/pl/wavesoftware/eid/EidIT.java index 4a4f502..4fda601 100644 --- a/src/test/java/pl/wavesoftware/eid/exceptions/EidIT.java +++ b/src/test/java/pl/wavesoftware/eid/EidIT.java @@ -1,4 +1,20 @@ -package pl.wavesoftware.eid.exceptions; +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid; import org.junit.ClassRule; import org.junit.Test; @@ -13,8 +29,11 @@ import org.openjdk.jmh.runner.options.TimeValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pl.wavesoftware.eid.exceptions.EidRuntimeException; import pl.wavesoftware.testing.JavaAgentSkip; +import pl.wavesoftware.testing.JavaVersion; import pl.wavesoftware.testing.JmhCleaner; +import pl.wavesoftware.testing.JvmArgs; import java.util.Collection; import java.util.Date; @@ -23,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszynski * @since 2016-03-24 */ public class EidIT { @@ -31,7 +50,10 @@ public class EidIT { private static final int PERCENT = 100; private static final int OPERATIONS = 1000; private static final Logger LOG = LoggerFactory.getLogger(EidIT.class); - private static final double SPEED_THRESHOLD = 0.75d; + private static final double SPEED_THRESHOLD = + JavaVersion.get().greaterOrEqual(JavaVersion.of(8)) + ? 0.9d + : 0.5d; @ClassRule public static RuleChain chain = RuleChain @@ -39,22 +61,22 @@ public class EidIT { .around(JavaAgentSkip.ifActive()); @Test - public void doBenckmarking() throws Exception { + public void benchmark() throws Exception { Options opt = new OptionsBuilder() - .include(this.getClass().getName() + ".*") - .mode(Mode.Throughput) - .timeUnit(TimeUnit.MICROSECONDS) - .operationsPerInvocation(OPERATIONS) - .warmupTime(TimeValue.seconds(1)) - .warmupIterations(2) - .measurementTime(TimeValue.seconds(1)) - .measurementIterations(5) - .threads(4) - .forks(1) - .shouldFailOnError(true) - .shouldDoGC(true) - .jvmArgs("-server", "-Xms256m", "-Xmx256m", "-XX:PermSize=128m", "-XX:MaxPermSize=128m", "-XX:+UseParallelGC") - .build(); + .include(this.getClass().getName() + ".*") + .mode(Mode.Throughput) + .timeUnit(TimeUnit.MILLISECONDS) + .operationsPerInvocation(OPERATIONS) + .warmupTime(TimeValue.seconds(1)) + .warmupIterations(2) + .measurementTime(TimeValue.seconds(1)) + .measurementIterations(5) + .threads(4) + .forks(1) + .shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs(JvmArgs.get()) + .build(); Runner runner = new Runner(opt); Collection results = runner.run(); @@ -74,8 +96,10 @@ public void doBenckmarking() throws Exception { double eidTimes = eidScore / controlScore; - LOG.info(String.format("Control sample method time per operation: %.2f ops / µsec", controlScore)); - LOG.info(String.format("#eid() method time per operation: %.2f ops / µsec", eidScore)); + LOG.info(String.format("Control sample method time per operation: %" + + ".2f ops / msec", controlScore)); + LOG.info(String.format("#eid() method time per operation: %" + + ".2f ops / msec", eidScore)); LOG.info(String.format("%s and is %.2f%%", eidTitle, eidTimes * PERCENT)); assertThat(eidTimes).as(eidTitle).isGreaterThanOrEqualTo(SPEED_THRESHOLD); @@ -89,9 +113,9 @@ public void control(Blackhole bh) { } @Benchmark - public void eid(Blackhole bh) { + public void eid(Blackhole bh, DisableValidatorState state) { for (int i = 0; i < OPERATIONS; i++) { - bh.consume(new Eid("20160330:144947")); + bh.consume(new DefaultEid("20160330:144947")); } } @@ -104,4 +128,5 @@ private static RunResult getRunResultByName(Collection results, Strin } throw new EidRuntimeException("20160324:225412", "Invalid name: " + name); } + } diff --git a/src/test/java/pl/wavesoftware/eid/EidTest.java b/src/test/java/pl/wavesoftware/eid/EidTest.java new file mode 100644 index 0000000..692607c --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/EidTest.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pl.wavesoftware.eid; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public class EidTest { + + @Rule + public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void invalidNullEid() { + // given + String eid = null; + + // then + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Exception ID can't be null"); + + // when + DefaultEid.eid(eid); + } + + @Test + public void invalidEid() { + // given + String eid = "1234"; + + // then + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("Invalid ID given as an Exception ID: 1234"); + + // when + DefaultEid.eid(eid); + } + + @Test + public void testToString() { + // given + DefaultEid instance = new DefaultEid("20150718:012917"); + String expResult = "[20150718:012917]"; + // when + String result = instance.toString(); + // then + assertThat(result).contains(expResult); + assertThat(result).matches("^\\[20150718:012917\\]<[a-zA-Z0-9_-]+>$"); + } + + @Test + public void testToString_Ref() { + // given + DefaultEid instance = new DefaultEid("20150718:013056", "ORA-38101"); + String expResult = "[20150718:013056|ORA-38101]"; + // when + String result = instance.toString(); + // then + assertThat(result).contains(expResult); + } + + @Test + public void testGetId() { + // given + DefaultEid instance = new DefaultEid("20150718:013209"); + String expResult = "20150718:013209"; + // when + String result = instance.getId(); + // then + assertThat(result).isEqualTo(expResult); + } + + @Test + public void testGetRef() { + // given + DefaultEid instance = new DefaultEid("20150718:013314", "ORA-38105"); + String expResult = "ORA-38105"; + // when + String result = instance.getRef(); + // then + assertThat(result).isEqualTo(expResult); + } + + @Test + public void testGetRef_Null() { + // given + Eid instance = DefaultEid.eid("20150718:013236"); + // when + String result = instance.getRef(); + // then + assertThat(result).isNull(); + } + + @Test + public void testGetUniq() { + String id = "20150718:013443"; + DefaultEid instance = new DefaultEid(id); + DefaultEid instance2 = new DefaultEid(id); + String result = instance.getUnique(); + String result2 = instance2.getUnique(); + assertThat(result).isNotEmpty(); + assertThat(result).isNotEqualTo(result2); + } + + @Test + public void message() { + // given + String code = "20151117:192211"; + DefaultEid eid = new DefaultEid(code); + int filesNumber = 18; + + // when + EidMessage message = eid.message("Files: {0}", filesNumber); + + // then + assertThat(message).contains("[20151117:192211]<", "> => Files: 18"); + } + + @Test + public void raceTheSun() throws InterruptedException, ExecutionException { + // given + final DefaultEid eid = new DefaultEid("20181114:223748"); + ExecutorService executorService = Executors.newFixedThreadPool(4); + Callable task = new Callable() { + @Override + public String call() { + return eid.getUnique(); + } + }; + Collection> tasks = + new ArrayList>(20); + for (int i = 0; i < 20; i++) { + tasks.add(task); + } + executorService.invokeAll(tasks); + + // when + List> executed = executorService.invokeAll(tasks); + + // then + Set collected = new HashSet(); + for (Future future : executed) { + collected.add(future.get()); + } + assertThat(collected).hasSize(1); + } + +} diff --git a/src/test/java/pl/wavesoftware/eid/api/TestConfigurator.java b/src/test/java/pl/wavesoftware/eid/api/TestConfigurator.java new file mode 100644 index 0000000..0ae09a4 --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/api/TestConfigurator.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.api; + +import java.util.Locale; +import java.util.TimeZone; +import java.util.regex.Pattern; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public final class TestConfigurator implements Configurator { + + @Override + public void configure(ConfigurationBuilder configuration) { + configuration + .locale(Locale.ENGLISH) + .timezone(TimeZone.getTimeZone("GMT")) + .validator(new PseudoDateValidator()); + } + + private static final class PseudoDateValidator implements Validator { + private final Pattern pattern = Pattern.compile("^\\d{8}:\\d{6}$"); + + @Override + public boolean isValid(CharSequence id) { + return pattern.matcher(id).matches(); + } + } +} diff --git a/src/test/java/pl/wavesoftware/eid/exceptions/A.java b/src/test/java/pl/wavesoftware/eid/exceptions/A.java new file mode 100644 index 0000000..c70f8b4 --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/exceptions/A.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.exceptions; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-16 + */ +class A { + @Override + public String toString() { + return "a"; + } +} diff --git a/src/test/java/pl/wavesoftware/eid/exceptions/AssertionsTest.java b/src/test/java/pl/wavesoftware/eid/exceptions/AssertionsTest.java index 9454ef4..f1bbaf3 100644 --- a/src/test/java/pl/wavesoftware/eid/exceptions/AssertionsTest.java +++ b/src/test/java/pl/wavesoftware/eid/exceptions/AssertionsTest.java @@ -1,8 +1,25 @@ +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.eid.exceptions; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import pl.wavesoftware.eid.DefaultEid; /** * @author Krzysztof Suszyński @@ -19,7 +36,7 @@ public void testJdkAssertions() { thrown.expect(AssertionError.class); // when - assert getTestNumber() < 3 : new Eid("20150721:101958"); + assert getTestNumber() < 3 : new DefaultEid("20150721:101958"); } private int getTestNumber() { diff --git a/src/test/java/pl/wavesoftware/eid/exceptions/EidIllegalArgumentExceptionTest.java b/src/test/java/pl/wavesoftware/eid/exceptions/EidIllegalArgumentExceptionTest.java new file mode 100644 index 0000000..2e99cb1 --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/exceptions/EidIllegalArgumentExceptionTest.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.exceptions; + +import org.junit.Rule; +import org.junit.Test; +import pl.wavesoftware.eid.ConstantUniqueIdRule; +import pl.wavesoftware.eid.DefaultEid; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; + +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public class EidIllegalArgumentExceptionTest { + + @Rule + public ConstantUniqueIdRule uniqueIdRule = new ConstantUniqueIdRule( + "d3m0" + ); + + @Test + public void constructOfCharSequence() { + // given + String eid = "20181215:000127"; + + // when + EidRuntimeException ex = new EidIllegalArgumentException(eid); + + // then + assertThat(ex).hasNoCause() + .hasMessage("[20181215:000127]"); + } + + @Test + public void constructOfCharSequenceAndMessage() { + // given + String eid = "20181215:000410"; + String message = "This is message"; + + // when + EidRuntimeException ex = new EidIllegalArgumentException(eid, message); + + // then + assertThat(ex).hasNoCause() + .hasMessage("[20181215:000410] => This is message"); + } + + @Test + public void constructOfEidMessage() { + // given + DefaultEid eid = new DefaultEid("20181216:175048"); + EidMessage message = eid.message( + "This is {0} message", new A() + ); + + // when + EidRuntimeException ex = new EidIllegalArgumentException(message); + + // then + assertThat(ex) + .hasNoCause() + .hasMessage("[20181216:175048] => This is a message"); + } + + @Test + public void constructOfCharSequenceAndMessageAndCause() { + // given + String eid = "20181215:001337"; + String message = "This is message"; + Throwable cause = getCause(); + + // when + EidRuntimeException ex = new EidIllegalArgumentException( + eid, message, cause + ); + + // then + assertThat(ex) + .hasCauseInstanceOf(IOException.class) + .hasMessage("[20181215:001337] => This is message"); + } + + @Test + public void constructOfEidMessageAndCause() { + // given + DefaultEid eid = new DefaultEid("20181215:000410"); + EidMessage message = eid.message( + "This is {0} message", new A() + ); + Throwable cause = getCause(); + + // when + EidRuntimeException ex = new EidIllegalArgumentException(message, cause); + + // then + assertThat(ex) + .hasCauseInstanceOf(IOException.class) + .hasMessage("[20181215:000410] => This is a message"); + } + + @Test + public void constructOfCharSequenceAndCause() { + // given + String eid = "20181216:175040"; + Throwable cause = getCause(); + + // when + EidRuntimeException ex = new EidIllegalArgumentException(eid, cause); + + // then + assertThat(ex) + .hasCauseInstanceOf(IOException.class) + .hasMessage("[20181216:175040] => A cause"); + } + + @Test + public void constructOfEid() { + // given + Eid eid = DefaultEid.eid("20181216:180054"); + + // when + EidRuntimeException ex = new EidIllegalArgumentException(eid); + + // then + assertThat(ex) + .hasNoCause() + .hasMessage("[20181216:180054]"); + } + + @Test + public void constructOfEidAndMessage() { + // given + Eid eid = DefaultEid.eid("20181216:180212"); + String message = "A simple message"; + + // when + EidRuntimeException ex = new EidIllegalArgumentException(eid, message); + + // then + assertThat(ex) + .hasNoCause() + .hasMessage("[20181216:180212] => A simple message"); + } + + @Test + public void constructOfEidAndMessageAndCause() { + // given + Eid eid = DefaultEid.eid("20181216:180355"); + String message = "A simple message"; + Throwable cause = getCause(); + + // when + EidRuntimeException ex = new EidIllegalArgumentException( + eid, message, cause + ); + + // then + assertThat(ex) + .hasCauseInstanceOf(IOException.class) + .hasMessage("[20181216:180355] => A simple message"); + } + + @Test + public void constructOfEidAndCause() { + // given + Eid eid = DefaultEid.eid("20181216:191804"); + Throwable cause = getCause(); + + // when + EidRuntimeException ex = new EidIllegalArgumentException( + eid, cause + ); + + // then + assertThat(ex) + .hasCauseInstanceOf(IOException.class) + .hasMessage("[20181216:191804] => A cause"); + } + + private static IOException getCause() { + return new IOException("A cause"); + } + +} diff --git a/src/test/java/pl/wavesoftware/eid/exceptions/EidIllegalStateExceptionTest.java b/src/test/java/pl/wavesoftware/eid/exceptions/EidIllegalStateExceptionTest.java new file mode 100644 index 0000000..c33898a --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/exceptions/EidIllegalStateExceptionTest.java @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.exceptions; + +import org.junit.Rule; +import org.junit.Test; +import pl.wavesoftware.eid.ConstantUniqueIdRule; +import pl.wavesoftware.eid.DefaultEid; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; + +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-16 + */ +public class EidIllegalStateExceptionTest { + @Rule + public ConstantUniqueIdRule uniqueIdRule = new ConstantUniqueIdRule( + "e9b1" + ); + + @Test + public void constructOfCharSequence() { + // given + String eid = "20181216:192816"; + + // when + EidRuntimeException ex = new EidIllegalStateException(eid); + + // then + assertThat(ex).hasNoCause() + .hasMessage("[20181216:192816]"); + } + + @Test + public void constructOfCharSequenceAndMessage() { + // given + String eid = "20181216:192843"; + String message = "This is message"; + + // when + EidRuntimeException ex = new EidIllegalStateException(eid, message); + + // then + assertThat(ex).hasNoCause() + .hasMessage("[20181216:192843] => This is message"); + } + + @Test + public void constructOfEidMessage() { + // given + DefaultEid eid = new DefaultEid("20181216:192906"); + EidMessage message = eid.message( + "This is {0} message", new A() + ); + + // when + EidRuntimeException ex = new EidIllegalStateException(message); + + // then + assertThat(ex) + .hasNoCause() + .hasMessage("[20181216:192906] => This is a message"); + } + + @Test + public void constructOfCharSequenceAndMessageAndCause() { + // given + String eid = "20181216:192917"; + String message = "This is message"; + Throwable cause = getCause(); + + // when + EidRuntimeException ex = new EidIllegalStateException( + eid, message, cause + ); + + // then + assertThat(ex) + .hasCauseInstanceOf(IOException.class) + .hasMessage("[20181216:192917] => This is message"); + } + + @Test + public void constructOfEidMessageAndCause() { + // given + DefaultEid eid = new DefaultEid("20181216:192930"); + EidMessage message = eid.message( + "This is {0} message", new A() + ); + Throwable cause = getCause(); + + // when + EidRuntimeException ex = new EidIllegalStateException(message, cause); + + // then + assertThat(ex) + .hasCauseInstanceOf(IOException.class) + .hasMessage("[20181216:192930] => This is a message"); + } + + @Test + public void constructOfCharSequenceAndCause() { + // given + String eid = "20181216:192938"; + Throwable cause = getCause(); + + // when + EidRuntimeException ex = new EidIllegalStateException(eid, cause); + + // then + assertThat(ex) + .hasCauseInstanceOf(IOException.class) + .hasMessage("[20181216:192938] => A cause"); + } + + @Test + public void constructOfEid() { + // given + Eid eid = DefaultEid.eid("20181216:192947"); + + // when + EidRuntimeException ex = new EidIllegalStateException(eid); + + // then + assertThat(ex) + .hasNoCause() + .hasMessage("[20181216:192947]"); + } + + @Test + public void constructOfEidAndMessage() { + // given + Eid eid = DefaultEid.eid("20181216:192956"); + String message = "A simple message"; + + // when + EidRuntimeException ex = new EidIllegalStateException(eid, message); + + // then + assertThat(ex) + .hasNoCause() + .hasMessage("[20181216:192956] => A simple message"); + } + + @Test + public void constructOfEidAndMessageAndCause() { + // given + Eid eid = DefaultEid.eid("20181216:193003"); + String message = "A simple message"; + Throwable cause = getCause(); + + // when + EidRuntimeException ex = new EidIllegalStateException( + eid, message, cause + ); + + // then + assertThat(ex) + .hasCauseInstanceOf(IOException.class) + .hasMessage("[20181216:193003] => A simple message"); + } + + @Test + public void constructOfEidAndCause() { + // given + Eid eid = DefaultEid.eid("20181216:193015"); + Throwable cause = getCause(); + + // when + EidRuntimeException ex = new EidIllegalStateException( + eid, cause + ); + + // then + assertThat(ex) + .hasCauseInstanceOf(IOException.class) + .hasMessage("[20181216:193015] => A cause"); + } + + private static Throwable getCause() { + return new IOException("A cause"); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/exceptions/EidIndexOutOfBoundsExceptionTest.java b/src/test/java/pl/wavesoftware/eid/exceptions/EidIndexOutOfBoundsExceptionTest.java index 7fd0bd5..d8aded8 100644 --- a/src/test/java/pl/wavesoftware/eid/exceptions/EidIndexOutOfBoundsExceptionTest.java +++ b/src/test/java/pl/wavesoftware/eid/exceptions/EidIndexOutOfBoundsExceptionTest.java @@ -1,61 +1,51 @@ +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.eid.exceptions; import org.hamcrest.CoreMatchers; -import org.junit.After; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import pl.wavesoftware.eid.ConstantUniqueIdRule; +import pl.wavesoftware.eid.DefaultEid; +import pl.wavesoftware.eid.api.Eid; -import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage; /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszynski * @since 2015-11-19 */ public class EidIndexOutOfBoundsExceptionTest { @Rule - public ExpectedException thrown = ExpectedException.none(); - - private String constUniq = "deadfa11"; - private String causeString = "Index seams to be invalid"; - @SuppressWarnings("ThrowableInstanceNeverThrown") - private Throwable cause = new ArrayIndexOutOfBoundsException(causeString); - private Eid.UniqIdGenerator original; - - @Before - public void before() { - original = Eid.setUniqIdGenerator(new Eid.UniqIdGenerator() { - @Override - public String generateUniqId() { - return constUniq; - } - }); - } - - @After - public void after() { - Eid.setUniqIdGenerator(original); - } + public final ExpectedException thrown = ExpectedException.none(); - @Test - public void testGetStandardJdkClass() throws Exception { - // given - @SuppressWarnings("ThrowableInstanceNeverThrown") - EidIndexOutOfBoundsException ex = new EidIndexOutOfBoundsException(new Eid("20151119:103152")); - - // when - Class cls = ex.getStandardJdkClass(); + @Rule + public final ConstantUniqueIdRule uniqueIdRule = new ConstantUniqueIdRule( + "deadfa11" + ); - // then - assertThat(cls).isEqualTo(IndexOutOfBoundsException.class); - } + private final String causeString = "Index seams to be invalid"; @Test - public void testEidIndexOutOfBoundsException_String_String_Throwable() { + public void throwWithEidWithRefAndCause() { // given String eid = "20151119:103158"; String ref = "MS+1233"; @@ -64,14 +54,17 @@ public void testEidIndexOutOfBoundsException_String_String_Throwable() { thrown.expectCause(hasMessage(containsString(causeString))); thrown.expectCause(CoreMatchers.instanceOf(ArrayIndexOutOfBoundsException.class)); thrown.expect(EidIndexOutOfBoundsException.class); - thrown.expectMessage("[20151119:103158|MS+1233] => Index seams to be invalid"); + thrown.expectMessage( + "[20151119:103158|MS+1233] => " + + "Index seams to be invalid" + ); // when - throw new EidIndexOutOfBoundsException(eid, ref, cause); + throw new EidIndexOutOfBoundsException(new DefaultEid(eid, ref), getCause()); } @Test - public void testEidIndexOutOfBoundsException_String_String() { + public void throwWithEidWithRef() { // given String eid = "20151119:103217"; String ref = "MS+1233"; @@ -81,11 +74,11 @@ public void testEidIndexOutOfBoundsException_String_String() { thrown.expectMessage("[20151119:103217|MS+1233]"); // when - throw new EidIndexOutOfBoundsException(eid, ref); + throw new EidIndexOutOfBoundsException(new DefaultEid(eid, ref)); } @Test - public void testEidIndexOutOfBoundsException_String_Throwable() { + public void throwWithStringAndCause() { // given String eid = "20151119:103232"; @@ -93,25 +86,159 @@ public void testEidIndexOutOfBoundsException_String_Throwable() { thrown.expectCause(hasMessage(containsString(causeString))); thrown.expectCause(CoreMatchers.instanceOf(ArrayIndexOutOfBoundsException.class)); thrown.expect(EidIndexOutOfBoundsException.class); - thrown.expectMessage("[20151119:103232] => Index seams to be invalid"); + thrown.expectMessage("[20151119:103232] => " + + "Index seams to be invalid"); // when - throw new EidIndexOutOfBoundsException(eid, cause); + throw new EidIndexOutOfBoundsException(eid, getCause()); } @Test - public void testEidIndexOutOfBoundsException_Eid_Throwable() { + public void throwWithEidAndCause() { // given String eidNum = "20151119:103245"; - Eid eid = new Eid(eidNum); + DefaultEid eid = new DefaultEid(eidNum); // then thrown.expectCause(hasMessage(containsString(causeString))); - thrown.expectCause(CoreMatchers.instanceOf(ArrayIndexOutOfBoundsException.class)); + thrown.expectCause(CoreMatchers.instanceOf( + ArrayIndexOutOfBoundsException.class + )); + thrown.expect(EidIndexOutOfBoundsException.class); + thrown.expectMessage("[20151119:103245] => " + + "Index seams to be invalid"); + + // when + throw new EidIndexOutOfBoundsException(eid, getCause()); + } + + @Test + public void throwWithString() { + // given + String eid = "20181216:233656"; + + // then + thrown.expectCause(nullValue(Throwable.class)); + thrown.expect(EidIndexOutOfBoundsException.class); + thrown.expectMessage("[20181216:233656]"); + + // when + throw new EidIndexOutOfBoundsException(eid); + } + + @Test + public void throwWithStringAndString() { + // given + String eid = "20181216:233958"; + String message = "This is a message"; + + // then + thrown.expectCause(nullValue(Throwable.class)); + thrown.expect(EidIndexOutOfBoundsException.class); + thrown.expectMessage("[20181216:233958] => " + + "This is a message"); + + // when + throw new EidIndexOutOfBoundsException(eid, message); + } + + @Test + public void throwWithEidMessage() { + // given + String eid = "20181216:235124"; + String message = "This is {0} message"; + + // then + thrown.expectCause(nullValue(Throwable.class)); + thrown.expect(EidIndexOutOfBoundsException.class); + thrown.expectMessage("[20181216:235124] => " + + "This is a message"); + + // when + throw new EidIndexOutOfBoundsException( + DefaultEid.eid(eid).message(message, new A()) + ); + } + + @Test + public void throwWithStringStringAndCause() { + // given + String eid = "20181216:235554"; + String message = "This is a message"; + + // then thrown.expect(EidIndexOutOfBoundsException.class); - thrown.expectMessage("[20151119:103245] => Index seams to be invalid"); + thrown.expectMessage("[20181216:235554] => " + + "This is a message"); + thrown.expectCause(CoreMatchers.instanceOf( + ArrayIndexOutOfBoundsException.class + )); // when - throw new EidIndexOutOfBoundsException(eid, cause); + throw new EidIndexOutOfBoundsException( + eid, message, getCause() + ); + } + + @Test + public void throwWithEidMessageAndCause() { + // given + String eid = "20181216:235729"; + String message = "This is {0} message"; + + // then + thrown.expect(EidIndexOutOfBoundsException.class); + thrown.expectMessage("[20181216:235729] => " + + "This is a message"); + thrown.expectCause(CoreMatchers.instanceOf( + ArrayIndexOutOfBoundsException.class + )); + + // when + throw new EidIndexOutOfBoundsException( + DefaultEid.eid(eid).message(message, new A()), getCause() + ); + } + + @Test + public void throwWithEidAndMessage() { + // given + Eid eid = DefaultEid.eid("20181217:001519"); + String message = "This is a message"; + + // then + thrown.expect(EidIndexOutOfBoundsException.class); + thrown.expectMessage("[20181217:001519] => " + + "This is a message"); + thrown.expectCause(nullValue(Throwable.class)); + + // when + throw new EidIndexOutOfBoundsException( + eid, message + ); + } + + @Test + public void throwWithEidAndMessageAndCause() { + // given + Eid eid = DefaultEid.eid("20181217:001727"); + String message = "This is a message"; + + // then + thrown.expect(EidIndexOutOfBoundsException.class); + thrown.expectMessage("[20181217:001727] => " + + "This is a message"); + thrown.expectCause(CoreMatchers.instanceOf( + ArrayIndexOutOfBoundsException.class + )); + + // when + throw new EidIndexOutOfBoundsException( + eid, message, getCause() + ); + } + + private Throwable getCause() { + return new ArrayIndexOutOfBoundsException(causeString); } -} \ No newline at end of file +} diff --git a/src/test/java/pl/wavesoftware/eid/exceptions/EidNullPointerExceptionTest.java b/src/test/java/pl/wavesoftware/eid/exceptions/EidNullPointerExceptionTest.java index 61f0dad..7422350 100644 --- a/src/test/java/pl/wavesoftware/eid/exceptions/EidNullPointerExceptionTest.java +++ b/src/test/java/pl/wavesoftware/eid/exceptions/EidNullPointerExceptionTest.java @@ -1,117 +1,203 @@ +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.eid.exceptions; import org.hamcrest.CoreMatchers; -import org.junit.After; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import pl.wavesoftware.eid.ConstantUniqueIdRule; +import pl.wavesoftware.eid.DefaultEid; +import pl.wavesoftware.eid.api.Eid; +import pl.wavesoftware.eid.api.EidMessage; -import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage; /** - * @author Krzysztof Suszyński + * @author Krzysztof Suszynski * @since 2015-11-19 */ public class EidNullPointerExceptionTest { + private final String constUniq = "deadcafe"; + private final String causeString = "A cause"; + @Rule public ExpectedException thrown = ExpectedException.none(); + @Rule + public ConstantUniqueIdRule uniqueIdRule = + new ConstantUniqueIdRule(constUniq); + + @Test + public void throwWithString() { + // given + String eid = "20181217:220721"; - private String constUniq = "cafedead"; - private String causeString = "A cause"; - @SuppressWarnings("ThrowableInstanceNeverThrown") - private Throwable cause = new UnsupportedOperationException(causeString); - private Eid.UniqIdGenerator original; - - @Before - public void before() { - original = Eid.setUniqIdGenerator(new Eid.UniqIdGenerator() { - @Override - public String generateUniqId() { - return constUniq; - } - }); + // then + thrown.expectCause(nullValue(Throwable.class)); + thrown.expect(EidNullPointerException.class); + thrown.expectMessage("[20181217:220721]"); + + // when + throw new EidNullPointerException(eid); } - @After - public void after() { - Eid.setUniqIdGenerator(original); + @Test + public void throwWithStringAndCause() { + // given + String eid = "20151119:101810"; + + // then + thrown.expectCause(hasMessage(containsString(causeString))); + thrown.expectCause(CoreMatchers.instanceOf( + UnsupportedOperationException.class + )); + thrown.expect(EidNullPointerException.class); + thrown.expectMessage("[20151119:101810] => A cause"); + + // when + throw new EidNullPointerException(eid, getCause()); } @Test - public void testGetStandardJdkClass() throws Exception { + public void throwWithEidAndCause() { // given - @SuppressWarnings("ThrowableInstanceNeverThrown") - EidNullPointerException ex = new EidNullPointerException(new Eid("20151119:102323")); + String eidNum = "20151119:102150"; + DefaultEid eid = new DefaultEid(eidNum); + + // then + thrown.expectCause(hasMessage(containsString(causeString))); + thrown.expectCause(CoreMatchers.instanceOf(UnsupportedOperationException.class)); + thrown.expect(EidNullPointerException.class); + thrown.expectMessage("[20151119:102150] => A cause"); // when - Class cls = ex.getStandardJdkClass(); + throw new EidNullPointerException(eid, getCause()); + } + + @Test + public void throwWithEidAndNullCause() { + // given + String eidNum = "20181217:222651"; + DefaultEid eid = new DefaultEid(eidNum); + Throwable cause = null; // then - assertThat(cls).isEqualTo(NullPointerException.class); + thrown.expectCause(nullValue(Throwable.class)); + thrown.expect(EidNullPointerException.class); + thrown.expectMessage("[20181217:222651]"); + + // when + throw new EidNullPointerException(eid, cause); } @Test - public void testEidNullPointerException_String_String_Throwable() { + public void throwWithEidAndRefAndCause() { // given String eid = "20151119:100854"; String ref = "PL-9584"; // then thrown.expectCause(hasMessage(containsString(causeString))); - thrown.expectCause(CoreMatchers.instanceOf(UnsupportedOperationException.class)); + thrown.expectCause(CoreMatchers.instanceOf( + UnsupportedOperationException.class + )); thrown.expect(EidNullPointerException.class); - thrown.expectMessage("[20151119:100854|PL-9584] => A cause"); + thrown.expectMessage("[20151119:100854|PL-9584] => A cause"); // when - throw new EidNullPointerException(eid, ref, cause); + throw new EidNullPointerException(new DefaultEid(eid, ref), getCause()); } @Test - public void testEidNullPointerException_String_String() { + public void throwWithEid() { // given String eid = "20151119:100854"; String ref = "PL-9584"; // then thrown.expect(EidNullPointerException.class); - thrown.expectMessage("[20151119:100854|PL-9584]"); + thrown.expectMessage("[20151119:100854|PL-9584]"); // when - throw new EidNullPointerException(eid, ref); + throw new EidNullPointerException(new DefaultEid(eid, ref)); } @Test - public void testEidNullPointerException_String_Throwable() { + public void throwWithEidMessageAndCause() { // given - String eid = "20151119:101810"; + String eid = "20181217:220935"; + EidMessage message = DefaultEid.eid(eid) + .message("This is {0} message", new A()); // then thrown.expectCause(hasMessage(containsString(causeString))); - thrown.expectCause(CoreMatchers.instanceOf(UnsupportedOperationException.class)); + thrown.expectCause(CoreMatchers.instanceOf( + UnsupportedOperationException.class + )); thrown.expect(EidNullPointerException.class); - thrown.expectMessage("[20151119:101810] => A cause"); + thrown.expectMessage( + "[20181217:220935] => This is a message" + ); // when - throw new EidNullPointerException(eid, cause); + throw new EidNullPointerException(message, getCause()); } @Test - public void testEidNullPointerException_Eid_Throwable() { + public void throwWithEidAndMessage() { // given - String eidNum = "20151119:102150"; - Eid eid = new Eid(eidNum); + Eid eid = DefaultEid.eid("20181217:221725"); + String message = "This is a message"; + + // then + thrown.expectCause(nullValue(Throwable.class)); + thrown.expect(EidNullPointerException.class); + thrown.expectMessage( + "[20181217:221725] => This is a message" + ); + + // when + throw new EidNullPointerException(eid, message); + } + + @Test + public void throwWithEidAndMessageAndCause() { + // given + DefaultEid eid = new DefaultEid("20181217:221901"); + String message = "This is a message"; // then thrown.expectCause(hasMessage(containsString(causeString))); - thrown.expectCause(CoreMatchers.instanceOf(UnsupportedOperationException.class)); + thrown.expectCause(CoreMatchers.instanceOf( + UnsupportedOperationException.class + )); thrown.expect(EidNullPointerException.class); - thrown.expectMessage("[20151119:102150] => A cause"); + thrown.expectMessage( + "[20181217:221901] => This is a message" + ); // when - throw new EidNullPointerException(eid, cause); + throw new EidNullPointerException(eid, message, getCause()); + } + + private Throwable getCause() { + return new UnsupportedOperationException(causeString); } -} \ No newline at end of file +} diff --git a/src/test/java/pl/wavesoftware/eid/exceptions/EidRuntimeExceptionTest.java b/src/test/java/pl/wavesoftware/eid/exceptions/EidRuntimeExceptionTest.java index a61477c..b54aaa7 100644 --- a/src/test/java/pl/wavesoftware/eid/exceptions/EidRuntimeExceptionTest.java +++ b/src/test/java/pl/wavesoftware/eid/exceptions/EidRuntimeExceptionTest.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.eid.exceptions; import org.hamcrest.CoreMatchers; @@ -5,7 +21,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -import javax.xml.bind.JAXBException; +import javax.naming.NamingException; import java.util.UnknownFormatConversionException; import static org.hamcrest.CoreMatchers.containsString; @@ -16,7 +32,6 @@ * @author Krzysztof Suszyński * @since 2015-10-07 */ -@SuppressWarnings("ConstantConditions") public class EidRuntimeExceptionTest { @Rule @@ -26,18 +41,20 @@ public class EidRuntimeExceptionTest { public void testGetMessage() { // then thrown.expect(EidRuntimeException.class); - thrown.expectCause(CoreMatchers.instanceOf(JAXBException.class)); + thrown.expectCause(CoreMatchers.instanceOf(NamingException.class)); thrown.expectCause(hasMessage(is((String) null))); thrown.expectMessage(containsString("20151007:212217")); - thrown.expectMessage(containsString("javax.xml.bind.JAXBException\n - with linked exception:\n" + - "[java.util.UnknownFormatConversionException: Conversion = 'Invalid for unit test']")); + thrown.expectMessage(containsString( + "javax.naming.NamingException [Root exception is java.util" + + ".UnknownFormatConversionException: Conversion = Invalid for" + + " unit test]" + )); // given - String message = null; Throwable original = new UnknownFormatConversionException("Invalid for unit test"); - JAXBException cause = new JAXBException(message); - cause.setLinkedException(original); + NamingException cause = new NamingException(null); + cause.setRootCause(original); throw new EidRuntimeException("20151007:212217", cause); } -} \ No newline at end of file +} diff --git a/src/test/java/pl/wavesoftware/eid/exceptions/EidTest.java b/src/test/java/pl/wavesoftware/eid/exceptions/EidTest.java deleted file mode 100644 index b8c0055..0000000 --- a/src/test/java/pl/wavesoftware/eid/exceptions/EidTest.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2015 Krzysztof Suszyński . - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package pl.wavesoftware.eid.exceptions; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import pl.wavesoftware.eid.exceptions.Eid.UniqIdGenerator; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -/** - * - * @author Krzysztof Suszyński - */ -@SuppressWarnings({"ConstantConditions", "unused"}) -public class EidTest { - - @Rule - public final ExpectedException thrown = ExpectedException.none(); - - @Test - public void testSetMessageFormat_Null() { - try { - // given - String format = null; - // then - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Format can't be null, but just received one"); - // when - Eid.setMessageFormat(format); - } finally { - Eid.setMessageFormat(Eid.DEFAULT_MESSAGE_FORMAT); - } - } - - @Test - public void testSetMessageFormat_Invalid() { - try { - // given - String format = "%s -> s"; - // then - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Given format contains to little format specifiers, expected 2 but given \"%s -> s\""); - // when - Eid.setMessageFormat(format); - } finally { - Eid.setMessageFormat(Eid.DEFAULT_MESSAGE_FORMAT); - } - } - - @Test - public void testSetUniqIdGenerator() { - try { - // given - UniqIdGenerator generator = new UniqIdGenerator() { - - @Override - public String generateUniqId() { - fail("Generator should not be executed while validating"); - return "constant"; - } - }; - // when - UniqIdGenerator previous = Eid.setUniqIdGenerator(generator); - UniqIdGenerator set = Eid.setUniqIdGenerator(previous); - // then - assertThat(set).isSameAs(generator); - assertThat(previous).isSameAs(Eid.DEFAULT_UNIQ_ID_GENERATOR); - } finally { - Eid.setUniqIdGenerator(Eid.DEFAULT_UNIQ_ID_GENERATOR); - } - } - - @Test - public void testSetUniqIdGenerator_Null() { - try { - // given - UniqIdGenerator generator = null; - // then - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Unique ID generator can't be null, but given one"); - // when - Eid.setUniqIdGenerator(generator); - } finally { - Eid.setUniqIdGenerator(Eid.DEFAULT_UNIQ_ID_GENERATOR); - } - } - - @Test - public void testSetFormat_Null() { - try { - // given - String format = null; - // then - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Format can't be null, but just received one"); - // when - Eid.setFormat(format); - } finally { - Eid.setFormat(Eid.DEFAULT_FORMAT); - } - } - - @Test - public void testSetFormat_Invalid() { - try { - // given - String format = ""; - // then - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Given format contains to little format specifiers, expected 2 but given \"\""); - // when - Eid.setFormat(format); - } finally { - Eid.setFormat(Eid.DEFAULT_FORMAT); - } - } - - @Test - public void testSetFormat() { - try { - // given - String format = "%s %s"; - // when - String old = Eid.setFormat(format); - String set = Eid.setFormat(Eid.DEFAULT_FORMAT); - // then - assertThat(old).isEqualTo(Eid.DEFAULT_FORMAT); - assertThat(set).isEqualTo(format); - } finally { - Eid.setFormat(Eid.DEFAULT_FORMAT); - } - } - - @Test - public void testSetRefFormat() { - try { - // given - String refFormat = "%s - %s - %s"; - // when - String old = Eid.setRefFormat(refFormat); - String set = Eid.setRefFormat(Eid.DEFAULT_REF_FORMAT); - // then - assertThat(old).isEqualTo(Eid.DEFAULT_REF_FORMAT); - assertThat(set).isEqualTo(refFormat); - } finally { - Eid.setRefFormat(Eid.DEFAULT_REF_FORMAT); - } - } - - @Test - public void testSetRefFormat_Null() { - try { - // given - String refFormat = null; - // then - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Format can't be null, but just received one"); - // when - Eid.setRefFormat(refFormat); - } finally { - Eid.setRefFormat(Eid.DEFAULT_REF_FORMAT); - } - } - - @Test - public void testSetRefFormat_Invalid() { - try { - // given - String refFormat = "%s -> s"; - // then - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("Given format contains to little format specifiers, expected 3 but given \"%s -> s\""); - // when - Eid.setRefFormat(refFormat); - } finally { - Eid.setRefFormat(Eid.DEFAULT_REF_FORMAT); - } - } - - @Test - public void testToString() { - // given - Eid instance = new Eid("20150718:012917"); - String expResult = "[20150718:012917]"; - // when - String result = instance.toString(); - // then - assertThat(result).contains(expResult); - assertThat(result).matches("^\\[20150718:012917\\]<[a-zA-Z0-9_-]+>$"); - } - - @Test - public void testToString_Ref() { - // given - Eid instance = new Eid("20150718:013056", "ORA-38101"); - String expResult = "[20150718:013056|ORA-38101]"; - // when - String result = instance.toString(); - // then - assertThat(result).contains(expResult); - } - - @Test - public void testGetId() { - // given - Eid instance = new Eid("20150718:013209"); - String expResult = "20150718:013209"; - // when - String result = instance.getId(); - // then - assertThat(result).isEqualTo(expResult); - } - - @Test - public void testGetRef() { - // given - Eid instance = new Eid("20150718:013314", "ORA-38105"); - String expResult = "ORA-38105"; - // when - String result = instance.getRef(); - // then - assertThat(result).isEqualTo(expResult); - } - - @Test - public void testGetRef_Null() { - // given - Eid instance = new Eid("20150718:013236"); - String expResult = ""; - // when - String result = instance.getRef(); - // then - assertThat(result).isEqualTo(expResult); - } - - @Test - public void testGetUniq() { - String id = "20150718:013443"; - Eid instance = new Eid(id); - Eid instance2 = new Eid(id); - String result = instance.getUniq(); - String result2 = instance2.getUniq(); - assertThat(result).isNotEmpty(); - assertThat(result).isNotEqualTo(result2); - } - - @Test - public void testMakeLogMessage() { - // given - String code = "20151117:192211"; - Eid eid = new Eid(code); - int filesNumber = 18; - - // when - String message = eid.makeLogMessage("Files: %d", filesNumber); - - // then - assertThat(message).contains("[20151117:192211]<", "> => Files: 18"); - } - -} diff --git a/src/test/java/pl/wavesoftware/eid/exceptions/ExceptionsTest.java b/src/test/java/pl/wavesoftware/eid/exceptions/ExceptionsTest.java index 54ed1fa..ad77fc7 100644 --- a/src/test/java/pl/wavesoftware/eid/exceptions/ExceptionsTest.java +++ b/src/test/java/pl/wavesoftware/eid/exceptions/ExceptionsTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2015 Krzysztof Suszyński . + * Copyright (c) 2015 Wave Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,16 +16,17 @@ package pl.wavesoftware.eid.exceptions; import org.assertj.core.util.Lists; -import org.assertj.core.util.Maps; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; +import pl.wavesoftware.eid.DefaultEid; +import pl.wavesoftware.eid.api.Eid; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; import java.util.List; -import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; @@ -37,26 +38,27 @@ @RunWith(Parameterized.class) public class ExceptionsTest { - private static Map, Class> getClassesMapping() { - Map, Class> map = Maps.newHashMap(); - map.put(EidRuntimeException.class, RuntimeException.class); - map.put(EidIllegalArgumentException.class, IllegalArgumentException.class); - map.put(EidIllegalStateException.class, IllegalStateException.class); - map.put(EidIndexOutOfBoundsException.class, IndexOutOfBoundsException.class); - map.put(EidNullPointerException.class, NullPointerException.class); - - return map; + @Parameters(name = "{index}: {0}({1})") + public static Iterable data() { + List argsList = getArguments(); + List parameters = Lists.newArrayList(); + for (Class exception : getExceptions()) { + for (Object[] args : argsList) { + addParameters(exception, parameters, args); + } + } + return parameters; } private static List getArguments() { - Throwable cause = new InterruptedException("A testing message"); - String eid = "20150718:112954"; - String ref = "PL-981"; - Eid id = new Eid(eid); + String message = "A testing message"; + Throwable cause = new InterruptedException(message); + CharSequence eid = "20150718:112954"; + Eid id = new DefaultEid(eid); List arguments = Lists.newArrayList(); - arguments.add(new Object[]{eid, ref, cause}); + arguments.add(new Object[]{eid, message, cause}); arguments.add(new Object[]{eid, cause}); - arguments.add(new Object[]{eid, ref}); + arguments.add(new Object[]{eid, message}); arguments.add(new Object[]{id, cause}); arguments.add(new Object[]{id}); return arguments; @@ -73,37 +75,47 @@ private static String argumentsTypesToString(Object[] args) { private static Class[] getArgumentsTypes(Object[] args) { List> classes = Lists.newArrayList(); for (Object arg : args) { - classes.add(Throwable.class.isAssignableFrom(arg.getClass()) ? Throwable.class : arg.getClass()); + classes.add(guessType(arg)); } Class[] empty = new Class[0]; return classes.toArray(empty); } - @Parameters(name = "{index}: {0}({1})") - public static Iterable data() { - List argsList = getArguments(); - Map, Class> mapping = getClassesMapping(); - List parameters = Lists.newArrayList(); - for (Map.Entry, Class> entrySet : mapping.entrySet()) { - for (Object[] args : argsList) { - addParameters(entrySet, parameters, args); - } - } - return parameters; + private static Class guessType(Object arg) { + return Throwable.class.isAssignableFrom(arg.getClass()) + ? Throwable.class + : Eid.class.isAssignableFrom(arg.getClass()) + ? Eid.class + : arg.getClass(); } - private static void addParameters(Map.Entry, Class> entrySet, - List parameters, Object[] args) { - try { - Class eidClass = entrySet.getKey(); - Class jdkClass = entrySet.getValue(); + @SuppressWarnings("unchecked") + private static Iterable> getExceptions() { + return Arrays.asList( + EidRuntimeException.class, + EidIllegalArgumentException.class, + EidIllegalStateException.class, + EidIndexOutOfBoundsException.class, + EidNullPointerException.class + ); + } - Constructor constructor = eidClass.getDeclaredConstructor(getArgumentsTypes(args)); + private static void addParameters( + Class eidClass, + List parameters, + Object[] args + ) { + try { + Class[] types = getArgumentsTypes(args); + if (types[0] == String.class) { + types[0] = CharSequence.class; + } + Constructor constructor = + eidClass.getDeclaredConstructor(types); parameters.add(new Object[]{ eidClass.getSimpleName(), argumentsTypesToString(args), eidClass, - jdkClass, constructor, args }); @@ -116,40 +128,27 @@ private static void addParameters(Map.Entry private final Class eidClass; - private final Class jdkClass; private final Constructor constructor; private final Object[] arguments; @SuppressWarnings("unchecked") - public ExceptionsTest(String classSimpleName, String argsClasses, Class eidClass, - Class jdkClass, Constructor constructor, Object... arguments) { + public ExceptionsTest( + String classSimpleName, + String argsClasses, + Class eidClass, + Constructor constructor, + Object... arguments + ) { assertThat(classSimpleName).isNotEmpty(); assertThat(argsClasses).isNotEmpty(); this.eidClass = eidClass; - this.jdkClass = jdkClass; this.constructor = (Constructor) constructor; this.arguments = arguments; } - @Test - public void testGetStandardJdkClass() { - // given - EidRuntimeException exception = construct(); - - // when - Eid eid = exception.getEid(); - Class jdkCls = exception.getStandardJdkClass(); - - // then - assertThat(exception).isNotNull(); - assertThat(eid).isNotNull(); - assertThat(jdkCls).isNotNull(); - assertThat(jdkCls).isEqualTo(jdkClass); - } - @Test public void testMessage() { // given diff --git a/src/test/java/pl/wavesoftware/eid/impl/BindingImplTest.java b/src/test/java/pl/wavesoftware/eid/impl/BindingImplTest.java new file mode 100644 index 0000000..41c4c5c --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/impl/BindingImplTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import org.junit.Test; +import pl.wavesoftware.eid.api.Binding; +import pl.wavesoftware.eid.api.SerializableSupplier; +import pl.wavesoftware.eid.api.Supplier; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszynski + * @since 2018-11-30 + */ +public class BindingImplTest { + + @Test + public void testLazy() { + // given + Binding binding = new BindingImpl(); + + // when + SerializableSupplier lazy = + binding.getFactories().getLazyFactory().lazy(new Supplier() { + @Override + public String get() { + return "Alice"; + } + }); + String result = lazy.get(); + + // then + assertThat(result).isEqualTo("Alice"); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/impl/DefaultEidMessageTest.java b/src/test/java/pl/wavesoftware/eid/impl/DefaultEidMessageTest.java new file mode 100644 index 0000000..d87874c --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/impl/DefaultEidMessageTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import org.junit.Test; +import pl.wavesoftware.eid.DefaultEid; +import pl.wavesoftware.eid.api.EidMessage; + +import java.util.Date; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public class DefaultEidMessageTest { + + @Test + public void testToString() { + // given + DefaultEid eid = new DefaultEid("20181114:225421"); + EidMessage message = eid.message( + "An example message with {0,date} {0,time}", + new Date(1024000L) + ); + + // when + String repr = message.toString(); + CharSequence fomatted = message.getFormattedMessage(); + char forthChar = message.charAt(32); + int len = message.length(); + CharSequence sub = message.subSequence(35, 38); + + // then + assertThat(fomatted).isEqualTo("An example message with Jan 1, 1970 12:17:04 AM"); + assertThat(repr).contains( + "[20181114:225421]<", + "> => An example message with Jan 1, 1970 12:17:04 AM" + ); + assertThat(forthChar).isEqualTo('e'); + assertThat(len).isEqualTo(76); + assertThat(sub).isEqualTo("mpl"); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/impl/DefaultFormatterTest.java b/src/test/java/pl/wavesoftware/eid/impl/DefaultFormatterTest.java new file mode 100644 index 0000000..64a83b6 --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/impl/DefaultFormatterTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import org.junit.Rule; +import org.junit.Test; +import pl.wavesoftware.eid.ConstantUniqueIdRule; +import pl.wavesoftware.eid.DefaultEid; +import pl.wavesoftware.eid.api.Configuration; +import pl.wavesoftware.eid.api.Formatter; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-03 + */ +public class DefaultFormatterTest { + + @Rule + public ConstantUniqueIdRule uniqueIdRule = new ConstantUniqueIdRule( + "deadcafe" + ); + + @Test + public void format() { + // given + Configuration configuration = new ConfigurationImpl(); + Formatter formatter = new DefaultFormatter(configuration); + + // when + String formatted = formatter.format(new DefaultEid("20181203:224055")); + + // then + assertThat(formatted).isEqualTo("[20181203:224055]"); + } + + @Test + public void formatWithMessage() { + // given + Configuration configuration = new ConfigurationImpl(); + Formatter formatter = new DefaultFormatter(configuration); + + // when + String formatted = formatter.format( + new DefaultEid("20181203:224137"), + "a message" + ); + + // then + assertThat(formatted).isEqualTo("[20181203:224137] => a message"); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/impl/DefaultUniqueIdGeneratorTest.java b/src/test/java/pl/wavesoftware/eid/impl/DefaultUniqueIdGeneratorTest.java new file mode 100644 index 0000000..b6ae44a --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/impl/DefaultUniqueIdGeneratorTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import org.junit.Test; +import pl.wavesoftware.eid.api.UniqueIdGenerator; + +import static org.assertj.core.api.Assertions.*; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public class DefaultUniqueIdGeneratorTest { + + @Test + public void testGenerateUniqId() { + // given + UniqueIdGenerator generator = new DefaultUniqueIdGenerator(); + String id; + + for (int i = 0; i < 1000000; i++) { + // when + id = generator.generateUniqId(); + + // then + assertThat(id).hasSize(6); + } + } +} diff --git a/src/test/java/pl/wavesoftware/eid/impl/EidTextRepresentationTest.java b/src/test/java/pl/wavesoftware/eid/impl/EidTextRepresentationTest.java new file mode 100644 index 0000000..cfbfd65 --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/impl/EidTextRepresentationTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import org.junit.Test; +import pl.wavesoftware.eid.DefaultEid; +import pl.wavesoftware.eid.api.Configuration; +import pl.wavesoftware.eid.system.EidModule; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Date; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszynski + * @since 2018-11-14 + */ +public class EidTextRepresentationTest { + + @Test + public void passivation() throws IOException, ClassNotFoundException { + // given + final DefaultEid eid = new DefaultEid("20181114:231205"); + Configuration configuration = EidModule.MODULE + .getBinding() + .getConfigurationSystem() + .getConfiguration(); + TextMessage textMessage = new TextMessage( + configuration, + "Other {0}", + new Object[]{new Date(3095000L)} + ); + final EidTextRepresentation representation = new EidTextRepresentation( + eid, + textMessage, + configuration + ); + ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArray); + + // when + objectOutputStream.writeObject(representation); + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( + byteArray.toByteArray() + ); + ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); + EidTextRepresentation repr2 = (EidTextRepresentation) objectInputStream.readObject(); + + // then + assertThat(repr2.get()).isEqualTo(representation.get()); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/impl/InternalChecksTest.java b/src/test/java/pl/wavesoftware/eid/impl/InternalChecksTest.java new file mode 100644 index 0000000..4ef633d --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/impl/InternalChecksTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-03 + */ +public class InternalChecksTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void instantinate() throws NoSuchMethodException, + IllegalAccessException, InvocationTargetException, + InstantiationException { + // when + Constructor constr = + InternalChecks.class.getDeclaredConstructor(); + constr.setAccessible(true); + InternalChecks checks = constr.newInstance(); + + // then + assertThat(checks).isNotNull(); + } + + @Test + public void testCheckNotNull() { + // given + String eid = "20181203:223812"; + String val = System.getProperty("non-existing-key-in-system"); + + // then + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage(eid); + + // when + InternalChecks.checkNotNull(val, eid); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/impl/MessageSupplierTest.java b/src/test/java/pl/wavesoftware/eid/impl/MessageSupplierTest.java new file mode 100644 index 0000000..dbd02a3 --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/impl/MessageSupplierTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import org.junit.Test; +import pl.wavesoftware.eid.api.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-03 + */ +public class MessageSupplierTest { + + @Test + public void testGet() { + // given + Configuration configuration = new ConfigurationImpl(); + MessageSupplier supplier = new MessageSupplier( + configuration, "{0} -> 11", new Object[] { ".5" } + ); + + // when + String message = supplier.get(); + + // then + assertThat(message).isEqualTo(".5 -> 11"); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/impl/TestBinding.java b/src/test/java/pl/wavesoftware/eid/impl/TestBinding.java new file mode 100644 index 0000000..a3347ba --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/impl/TestBinding.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.impl; + +import pl.wavesoftware.eid.api.Binding; +import pl.wavesoftware.eid.api.ConfigurationSystem; +import pl.wavesoftware.eid.api.EidFactories; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public final class TestBinding implements Binding { + + private final Binding impl = new BindingImpl(); + + @Override + public ConfigurationSystem getConfigurationSystem() { + return impl.getConfigurationSystem(); + } + + @Override + public EidFactories getFactories() { + return impl.getFactories(); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/system/BindingChooserTest.java b/src/test/java/pl/wavesoftware/eid/system/BindingChooserTest.java new file mode 100644 index 0000000..8a81351 --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/system/BindingChooserTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.system; + +import org.junit.Test; +import pl.wavesoftware.eid.api.Binding; +import pl.wavesoftware.eid.impl.BindingImpl; +import pl.wavesoftware.eid.impl.TestBinding; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.Assertions.*; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-18 + */ +public class BindingChooserTest { + + @Test + public void testChooseImplementation() { + // given + BindingChooser chooser = new BindingChooser(); + Binding testBinding = new TestBinding(); + Binding binding = new BindingImpl(); + List bindings = Arrays.asList( + testBinding, + binding + ); + Collections.shuffle(bindings); + + // when + + Binding chosen = chooser.chooseImplementation(bindings); + + // then + assertThat(chosen).isSameAs(testBinding); + } + + @Test + public void testChooseImplementationOnSingle() { + // given + BindingChooser chooser = new BindingChooser(); + + // when + Binding binding = new BindingImpl(); + Binding chosen = chooser.chooseImplementation(Collections.singletonList( + binding + )); + + // then + assertThat(chosen).isSameAs(binding); + } + + @Test(expected = AssertionError.class) + public void testChooseImplementationOnEmpty() { + // given + BindingChooser chooser = new BindingChooser(); + + // when + Binding chosen = chooser.chooseImplementation(new ArrayList()); + + // then + assertThat(chosen).isNull(); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/utils/EidExecutionsTest.java b/src/test/java/pl/wavesoftware/eid/utils/EidExecutionsTest.java new file mode 100644 index 0000000..85810f8 --- /dev/null +++ b/src/test/java/pl/wavesoftware/eid/utils/EidExecutionsTest.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.eid.utils; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import pl.wavesoftware.eid.DefaultEid; +import pl.wavesoftware.eid.exceptions.EidRuntimeException; + +import java.text.ParseException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.isA; +import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage; + +/** + * @author Krzysztof Suszynski + * @since 2.0.0 + */ +public class EidExecutionsTest { + + @Rule + public final ExpectedException thrown = ExpectedException.none(); + + private final String eid = "20181029:230523"; + + @Test + public void testTryToExecute_UnsafeProcedure_String() { + // given + final String causeMessage = "An error occured while parsing JSON document at char 178"; + UnsafeProcedure procedure = new UnsafeProcedure() { + @Override + public void execute() throws ParseException { + throw new ParseException(causeMessage, 178); + } + }; + // then + thrown.expect(EidRuntimeException.class); + thrown.expectCause(isA(ParseException.class)); + thrown.expectCause(hasMessage(equalTo(causeMessage))); + // when + EidExecutions.tryToExecute(procedure, eid); + } + + @Test + public void testTryToExecute_UnsafeProcedure_String_Ok() { + // given + UnsafeProcedure procedure = new UnsafeProcedure() { + @Override + public void execute() { + // nothing special here, for unit test + } + }; + // when + EidExecutions.tryToExecute(procedure, eid); + // then + assertThat(procedure).isNotNull(); + } + + @Test + public void testTryToExecute_UnsafeProcedure_Eid() { + // given + final String causeMessage = "An error occured while parsing JSON document at char 178"; + UnsafeProcedure procedure = new UnsafeProcedure() { + @Override + public void execute() throws ParseException { + throw new ParseException(causeMessage, 178); + } + }; + // then + thrown.expect(EidRuntimeException.class); + thrown.expectCause(isA(ParseException.class)); + thrown.expectCause(hasMessage(equalTo(causeMessage))); + // when + EidExecutions.tryToExecute(procedure, new DefaultEid(eid)); + } + + @Test + public void testTryToExecute_UnsafeProcedure_Eid_Ok() { + // given + UnsafeProcedure procedure = new UnsafeProcedure() { + @Override + public void execute() { + // nothing special here, for unit test + } + }; + // when + EidExecutions.tryToExecute(procedure, new DefaultEid(eid)); + // then + assertThat(procedure).isNotNull(); + } + + @Test + public void testTryToExecute_UnsafeSupplier_String() { + // given + final String causeMessage = "An error occured while parsing JSON document at char 178"; + UnsafeSupplier supplier = new UnsafeSupplier() { + + @Override + public String get() throws ParseException { + throw new ParseException(causeMessage, 178); + } + }; + // then + thrown.expect(EidRuntimeException.class); + thrown.expectCause(isA(ParseException.class)); + thrown.expectCause(hasMessage(equalTo(causeMessage))); + // when + EidExecutions.tryToExecute(supplier, eid); + } + + @Test + public void testTryToExecute_UnsafeSupplier_String_Ok() { + // given + final String returning = "An answer to universe and everything"; + UnsafeSupplier supplier = new UnsafeSupplier() { + @Override + public String get() throws ParseException { + return returning; + } + }; + // when + String answer = EidExecutions.tryToExecute(supplier, eid); + // then + assertThat(supplier).isNotNull(); + assertThat(answer).isNotNull().isNotEmpty().isEqualTo(returning); + } + + @Test + public void testTryToExecute_UnsafeSupplier_Eid() { + // given + final String causeMessage = "An error occured while parsing JSON document at char 178"; + UnsafeSupplier supplier = new UnsafeSupplier() { + + @Override + public String get() throws ParseException { + throw new ParseException(causeMessage, 178); + } + }; + // then + thrown.expect(EidRuntimeException.class); + thrown.expectCause(isA(ParseException.class)); + thrown.expectCause(hasMessage(equalTo(causeMessage))); + // when + EidExecutions.tryToExecute(supplier, new DefaultEid(eid)); + } + + @Test + public void testTryToExecute_UnsafeSupplier_Eid_Ok() { + // given + final String returning = "An answer to universe and everything"; + UnsafeSupplier supplier = new UnsafeSupplier() { + @Override + public String get() throws ParseException { + return returning; + } + }; + // when + String answer = EidExecutions.tryToExecute(supplier, new DefaultEid(eid)); + // then + assertThat(supplier).isNotNull(); + assertThat(answer).isNotNull().isNotEmpty().isEqualTo(returning); + } +} diff --git a/src/test/java/pl/wavesoftware/eid/utils/EidPreconditionsIT.java b/src/test/java/pl/wavesoftware/eid/utils/EidPreconditionsIT.java index aa268f0..637a3ba 100644 --- a/src/test/java/pl/wavesoftware/eid/utils/EidPreconditionsIT.java +++ b/src/test/java/pl/wavesoftware/eid/utils/EidPreconditionsIT.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.eid.utils; import com.google.common.base.Preconditions; @@ -18,9 +34,11 @@ import org.openjdk.jmh.runner.options.TimeValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pl.wavesoftware.eid.DisableValidatorState; import pl.wavesoftware.eid.exceptions.EidRuntimeException; import pl.wavesoftware.testing.JavaAgentSkip; import pl.wavesoftware.testing.JmhCleaner; +import pl.wavesoftware.testing.JvmArgs; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -52,7 +70,7 @@ public void doBenchmarking() throws RunnerException { Options opt = new OptionsBuilder() .include(this.getClass().getName() + ".*") .mode(Mode.Throughput) - .timeUnit(TimeUnit.MICROSECONDS) + .timeUnit(TimeUnit.MILLISECONDS) .operationsPerInvocation(OPERATIONS) .warmupTime(TimeValue.seconds(1)) .warmupIterations(1) @@ -62,7 +80,7 @@ public void doBenchmarking() throws RunnerException { .forks(1) .shouldFailOnError(true) .shouldDoGC(true) - .jvmArgs("-server", "-Xms256m", "-Xmx256m", "-XX:PermSize=128m", "-XX:MaxPermSize=128m", "-XX:+UseParallelGC") + .jvmArgs(JvmArgs.get()) .build(); Runner runner = new Runner(opt); @@ -76,7 +94,7 @@ public void doBenchmarking() throws RunnerException { @Benchmark @BenchmarkConfig(test = TestCase.CHECK_ARGUMENT, framework = Framework.GUAVA) - public void testCheckArgument(Blackhole bh) { + public void testCheckArgument(Blackhole bh, DisableValidatorState state) { for (int i = 0; i < OPERATIONS; i++) { Preconditions.checkArgument(i >= 0, "20160325:123449"); bh.consume(i); @@ -85,7 +103,7 @@ public void testCheckArgument(Blackhole bh) { @Benchmark @BenchmarkConfig(test = TestCase.CHECK_STATE, framework = Framework.GUAVA) - public void testCheckState(Blackhole bh) { + public void testCheckState(Blackhole bh, DisableValidatorState state) { for (int i = 0; i < OPERATIONS; i++) { Preconditions.checkState(i >= 0, "20160325:123534"); bh.consume(i); @@ -128,12 +146,12 @@ public void testCheckNotNullEid(Blackhole bh) { @State(Scope.Benchmark) public static class SupplierOfUnsafes { - private EidPreconditions.UnsafeSupplier supplier; - private EidPreconditions.UnsafeProcedure procedure; + private UnsafeSupplier supplier; + private UnsafeProcedure procedure; @Setup public void setup() { - this.supplier = new EidPreconditions.UnsafeSupplier() { + this.supplier = new UnsafeSupplier() { @Override public String get() throws Exception { @@ -147,7 +165,7 @@ public String get() throws Exception { @BenchmarkConfig(test = TestCase.TRY_TO_EXECUTE, framework = Framework.EID) public void testTryToExecuteSupplier(SupplierOfUnsafes supplierOfUnsafes, Blackhole bh) { for (int i = 0; i < OPERATIONS; i++) { - bh.consume(EidPreconditions.tryToExecute(supplierOfUnsafes.supplier, "20160326:223854")); + bh.consume(EidExecutions.tryToExecute(supplierOfUnsafes.supplier, "20160326:223854")); } } @@ -163,9 +181,13 @@ private void verifySpeedFor(TestCase testCase, Collection results) { double ratio = eid / guava; - LOG.info(String.format("%s: Guava score = %.2f vs Eid score = %.2f ==> ratio: %.2f%%, " + - "minimum threshold: %.2f%%", - testCase, guava, eid, ratio * PERCENT, SPEED_THRESHOLD * PERCENT)); + LOG.info(String.format( + "%s: Guava score = %.2f vs Eid score = %.2f " + + "==> ratio: %.2f%%, " + + "minimum threshold: %.2f%%", + testCase, guava, eid, + ratio * PERCENT, SPEED_THRESHOLD * PERCENT + )); assertThat(ratio).isGreaterThanOrEqualTo(SPEED_THRESHOLD); } @@ -202,6 +224,7 @@ private Method findMethod(TestCase testCase, Framework framework) { @Retention(RetentionPolicy.RUNTIME) private @interface BenchmarkConfig { TestCase test(); + Framework framework(); } diff --git a/src/test/java/pl/wavesoftware/eid/utils/EidPreconditionsTest.java b/src/test/java/pl/wavesoftware/eid/utils/EidPreconditionsTest.java index 5eb083a..944d4c3 100644 --- a/src/test/java/pl/wavesoftware/eid/utils/EidPreconditionsTest.java +++ b/src/test/java/pl/wavesoftware/eid/utils/EidPreconditionsTest.java @@ -1,11 +1,11 @@ /* - * Copyright 2015 Krzysztof Suszyński . + * Copyright (c) 2015 Wave Software * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,7 +21,11 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import pl.wavesoftware.eid.exceptions.Eid; +import pl.wavesoftware.eid.ConfiguratorRule; +import pl.wavesoftware.eid.DefaultEid; +import pl.wavesoftware.eid.api.ConfigurationBuilder; +import pl.wavesoftware.eid.api.Configurator; +import pl.wavesoftware.eid.api.Eid; import pl.wavesoftware.eid.exceptions.EidIllegalArgumentException; import pl.wavesoftware.eid.exceptions.EidIllegalStateException; import pl.wavesoftware.eid.exceptions.EidIndexOutOfBoundsException; @@ -30,20 +34,27 @@ import javax.annotation.Nonnull; import java.lang.reflect.Constructor; -import java.text.ParseException; +import java.lang.reflect.Modifier; +import java.util.Locale; import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage; +import static org.hamcrest.CoreMatchers.containsString; /** * - * @author Krzysztof Suszyński + * @author Krzysztof Suszynski */ public class EidPreconditionsTest { @Rule public final ExpectedException thrown = ExpectedException.none(); + @Rule + public final ConfiguratorRule configurator = new ConfiguratorRule(new Configurator() { + @Override + public void configure(ConfigurationBuilder configuration) { + configuration.locale(Locale.ENGLISH); + } + }); private final String eid = "20150718:075046"; @@ -67,7 +78,10 @@ public void testCheckArgument_WithMessage() { thrown.expectMessage(containsString(eid)); thrown.expectMessage(containsString("PI value is 3.14")); // when - EidPreconditions.checkArgument(expression, eid, "PI value is %.2f", Math.PI); + EidPreconditions.checkArgument( + expression, eid, + "PI value is {0,number,#.##}", Math.PI + ); } @Test @@ -75,7 +89,10 @@ public void testCheckArgument_Ok_WithMessage() { // given boolean expression = truthyValue(); // when - EidPreconditions.checkArgument(expression, eid, "PI value is %.2f", Math.PI); + EidPreconditions.checkArgument( + expression, eid, + "PI value is {0,number,#.##}", Math.PI + ); // then assertThat(thrown).isNotNull(); } @@ -89,7 +106,10 @@ public void testCheckArgument_Eid_WithMessage() { thrown.expectMessage(containsString(eid)); thrown.expectMessage(containsString("PI value is 3.14")); // when - EidPreconditions.checkArgument(expression, new Eid(eid), "PI value is %.2f", Math.PI); + EidPreconditions.checkArgument( + expression, new DefaultEid(eid), + "PI value is {0,number,#.##}", Math.PI + ); } @Test @@ -97,7 +117,10 @@ public void testCheckArgument_Eid_Ok_WithMessage() { // given boolean expression = truthyValue(); // when - EidPreconditions.checkArgument(expression, new Eid(eid), "PI value is %.2f", Math.PI); + EidPreconditions.checkArgument( + expression, new DefaultEid(eid), + "PI value is {0,number,#.##}", Math.PI + ); // then assertThat(thrown).isNotNull(); } @@ -132,7 +155,10 @@ public void testCheckState_WithMessage() { thrown.expectMessage(containsString(eid)); thrown.expectMessage(containsString("PI is 3.1416")); // when - EidPreconditions.checkState(expression, eid, "PI is %.4f", Math.PI); + EidPreconditions.checkState( + expression, eid, + "PI is {0,number,#.####}", Math.PI + ); } @Test @@ -140,7 +166,10 @@ public void testCheckState_Ok_WithMessage() { // given boolean expression = truthyValue(); // when - EidPreconditions.checkState(expression, eid, "PI is %.4f", Math.PI); + EidPreconditions.checkState( + expression, eid, + "PI is {0,number,#.##}", Math.PI + ); // then assertThat(thrown).isNotNull(); } @@ -154,7 +183,10 @@ public void testCheckState_Eid_WithMessage() { thrown.expectMessage(containsString(eid)); thrown.expectMessage(containsString("PI is 3.1416")); // when - EidPreconditions.checkState(expression, new Eid(eid), "PI is %.4f", Math.PI); + EidPreconditions.checkState( + expression, new DefaultEid(eid), + "PI is {0,number,#.####}", Math.PI + ); } @Test @@ -162,7 +194,10 @@ public void testCheckState_Ok_Eid_WithMessage() { // given boolean expression = truthyValue(); // when - EidPreconditions.checkState(expression, new Eid(eid), "PI is %.4f", Math.PI); + EidPreconditions.checkState( + expression, new DefaultEid(eid), + "PI is {0,number,#.##}", Math.PI + ); // then assertThat(thrown).isNotNull(); } @@ -208,7 +243,10 @@ public void testCheckNotNull_WithMessage() { thrown.expectMessage(containsString(eid)); thrown.expectMessage(containsString("π <=> 3.142")); // when - EidPreconditions.checkNotNull(reference, eid, "π <=> %.3f", Math.PI); + EidPreconditions.checkNotNull( + reference, eid, + "π <=> {0,number,#.###}", Math.PI + ); } @Test @@ -216,7 +254,10 @@ public void testCheckNotNull_Ok_WithMessage() { // given Object reference = "A test"; // when - Object checked = EidPreconditions.checkNotNull(reference, eid, "π <=> %.3f", Math.PI); + Object checked = EidPreconditions.checkNotNull( + reference, eid, + "π <=> {0,number,#.###}", Math.PI + ); // then assertThat(checked).isSameAs(reference); } @@ -230,7 +271,10 @@ public void testCheckNotNull_Eid_WithMessage() { thrown.expectMessage(containsString(eid)); thrown.expectMessage(containsString("π <=> 3.142")); // when - EidPreconditions.checkNotNull(reference, new Eid(eid), "π <=> %.3f", Math.PI); + EidPreconditions.checkNotNull( + reference, new DefaultEid(eid), + "π <=> {0,number,#.###}", Math.PI + ); } @Test @@ -238,7 +282,10 @@ public void testCheckNotNull_Ok_Eid_WithMessage() { // given Object reference = "A test"; // when - Object checked = EidPreconditions.checkNotNull(reference, new Eid(eid), "π <=> %.3f", Math.PI); + Object checked = EidPreconditions.checkNotNull( + reference, new DefaultEid(eid), + "π <=> {0,number,#.###}", Math.PI + ); // then assertThat(checked).isSameAs(reference); } @@ -280,6 +327,18 @@ public void testCheckElementIndex() { EidPreconditions.checkElementIndex(index, size, eid); } + @Test + public void testCheckElementIndexOnGithubIssue15() { + // given + int index = 4; + int size = 4; + // then + thrown.expect(EidIndexOutOfBoundsException.class); + thrown.expectMessage(containsString(eid)); + // when + EidPreconditions.checkElementIndex(index, size, eid); + } + @Test public void testCheckElementIndex_WithMessage() { // given @@ -290,7 +349,10 @@ public void testCheckElementIndex_WithMessage() { thrown.expectMessage(containsString(eid)); thrown.expectMessage(containsString("Pi (π): 3.14")); // when - EidPreconditions.checkElementIndex(index, size, eid, "Pi (π): %.2f", Math.PI); + EidPreconditions.checkElementIndex( + index, size, eid, + "Pi (π): {0,number,#.##}", Math.PI + ); } @Test @@ -303,7 +365,10 @@ public void testCheckElementIndex_Eid_WithMessage() { thrown.expectMessage(containsString(eid)); thrown.expectMessage(containsString("Pi (π): 3.14")); // when - EidPreconditions.checkElementIndex(index, size, new Eid(eid), "Pi (π): %.2f", Math.PI); + EidPreconditions.checkElementIndex( + index, size, new DefaultEid(eid), + "Pi (π): {0,number,#.##}", Math.PI + ); } @Test @@ -314,9 +379,12 @@ public void testCheckElementIndex_SizeIllegal_WithMessage() { // then thrown.expect(EidIllegalArgumentException.class); thrown.expectMessage(containsString(eid)); - thrown.expectMessage(containsString("Pi (π): 3.142")); + thrown.expectMessage(containsString("Pi (π): 3.14")); // when - EidPreconditions.checkElementIndex(index, size, eid, "Pi (π): %.3f", Math.PI); + EidPreconditions.checkElementIndex( + index, size, eid, + "Pi (π): {0,number,#.##}", Math.PI + ); } @Test @@ -327,9 +395,12 @@ public void testCheckElementIndex_SizeIllegal_Eid_WithMessage() { // then thrown.expect(EidIllegalArgumentException.class); thrown.expectMessage(containsString(eid)); - thrown.expectMessage(containsString("Pi (π): 3.142")); + thrown.expectMessage(containsString("Pi (π): 3.14")); // when - EidPreconditions.checkElementIndex(index, size, new Eid(eid), "Pi (π): %.3f", Math.PI); + EidPreconditions.checkElementIndex( + index, size, new DefaultEid(eid), + "Pi (π): {0,number,#.##}", Math.PI + ); } @Test @@ -338,7 +409,10 @@ public void testCheckElementIndex_Ok_WithMessage() { int index = 234; int size = 450; // when - int checked = EidPreconditions.checkElementIndex(index, size, eid, "Pi (π): %.1f", Math.PI); + int checked = EidPreconditions.checkElementIndex( + index, size, eid, + "Pi (π): {0,number,#.#}", Math.PI + ); // then assertThat(checked).isEqualTo(index); } @@ -349,7 +423,10 @@ public void testCheckElementIndex_Ok_Eid_WithMessage() { int index = 234; int size = 450; // when - int checked = EidPreconditions.checkElementIndex(index, size, new Eid(eid), "Pi (π): %.1f", Math.PI); + int checked = EidPreconditions.checkElementIndex( + index, size, new DefaultEid(eid), + "Pi (π): {0,number,#.#}", Math.PI + ); // then assertThat(checked).isEqualTo(index); } @@ -375,7 +452,7 @@ public void testCheckElementIndex_Eid_SizeInvalid() { thrown.expect(EidIllegalArgumentException.class); thrown.expectMessage(containsString(eid)); // when - EidPreconditions.checkElementIndex(index, size, new Eid(eid)); + EidPreconditions.checkElementIndex(index, size, new DefaultEid(eid)); } @Test @@ -395,7 +472,7 @@ public void testCreate() throws NoSuchMethodException { // given Class cls = EidPreconditions.class; Constructor constructor = cls.getDeclaredConstructor(); - boolean access = constructor.isAccessible(); + boolean access = Modifier.isPublic(constructor.getModifiers()); // then assertThat(access).isFalse(); @@ -405,13 +482,14 @@ public void testCreate() throws NoSuchMethodException { @Override public boolean matches(Object item) { @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - Eid eidObject = EidRuntimeException.class.cast(item).getEid(); + Eid eidObject = ((EidRuntimeException) item).getEid(); return eidObject.getId().equals("20150718:083450") - && !eidObject.getRef().isEmpty() - && !eidObject.getUniq().isEmpty(); + && !eidObject.hasRef() + && !eidObject.getUnique().isEmpty(); } }); - thrown.expectMessage(containsString("[20150718:083450|This should not be accessed]")); + thrown.expectMessage(containsString("[20150718:083450]")); + thrown.expectMessage(containsString("This should not be accessed")); // when assertThat(new EidPreconditions()).isNull(); } @@ -420,7 +498,7 @@ public boolean matches(Object item) { public void testCheckArgument_boolean_Eid_Null() { // given boolean expression = falsyValue(); - Eid eidObject = nullyValue(); + DefaultEid eidObject = nullyValue(); // then thrown.expect(EidIllegalArgumentException.class); thrown.expectMessage(containsString("20160329:132823|EID-NULL")); @@ -443,7 +521,7 @@ public void testCheckArgument_boolean_String_Null() { @Test public void testCheckArgument_boolean_Eid() { // given - Eid eidObject = getEid(); + DefaultEid eidObject = getEid(); boolean expression = falsyValue(); // then thrown.expect(EidIllegalArgumentException.class); @@ -455,7 +533,7 @@ public void testCheckArgument_boolean_Eid() { @Test public void testCheckArgument_boolean_Eid_Ok() { // given - Eid eidObject = getEid(); + DefaultEid eidObject = getEid(); boolean expression = truthyValue(); // when EidPreconditions.checkArgument(expression, eidObject); @@ -467,7 +545,7 @@ public void testCheckArgument_boolean_Eid_Ok() { public void testCheckState_boolean_Eid() { // given boolean expression = falsyValue(); - Eid eidObject = getEid(); + DefaultEid eidObject = getEid(); // then thrown.expect(EidIllegalStateException.class); thrown.expectMessage(containsString(eid)); @@ -479,7 +557,7 @@ public void testCheckState_boolean_Eid() { public void testCheckState_boolean_Eid_Ok() { // given boolean expression = truthyValue(); - Eid eidObject = getEid(); + DefaultEid eidObject = getEid(); // when EidPreconditions.checkState(expression, eidObject); // then @@ -490,7 +568,7 @@ public void testCheckState_boolean_Eid_Ok() { public void testCheckNotNull_GenericType_Eid() { // given Object reference = nullyValue(); - Eid eidObject = getEid(); + DefaultEid eidObject = getEid(); // then thrown.expect(EidNullPointerException.class); thrown.expectMessage(containsString(eid)); @@ -502,7 +580,7 @@ public void testCheckNotNull_GenericType_Eid() { public void testCheckNotNull_GenericType_Eid_Ok() { // given String reference = "ok"; - Eid eidObject = getEid(); + DefaultEid eidObject = getEid(); // when String result = EidPreconditions.checkNotNull(reference, eidObject); // then @@ -515,7 +593,7 @@ public void testCheckElementIndex_3args_2() { // given int index = 5; int size = 0; - Eid eidObject = getEid(); + DefaultEid eidObject = getEid(); // then thrown.expect(EidIndexOutOfBoundsException.class); thrown.expectMessage(containsString(eid)); @@ -528,7 +606,7 @@ public void testCheckElementIndex_3args_2_Negative() { // given int index = -5; int size = 10; - Eid eidObject = getEid(); + DefaultEid eidObject = getEid(); // then thrown.expect(EidIndexOutOfBoundsException.class); thrown.expectMessage(containsString(eid)); @@ -541,154 +619,16 @@ public void testCheckElementIndex_3args_2_Ok() { // given int index = 1; int size = 120; - Eid eidObject = getEid(); + DefaultEid eidObject = getEid(); // when int result = EidPreconditions.checkElementIndex(index, size, eidObject); // then assertThat(result).isEqualTo(index); } - @Test - public void testTryToExecute_UnsafeProcedure_String() { - // given - final String causeMessage = "An error occured while parsing JSON document at char 178"; - EidPreconditions.UnsafeProcedure procedure = new EidPreconditions.UnsafeProcedure() { - @Override - public void execute() throws ParseException { - throw new ParseException(causeMessage, 178); - } - }; - // then - thrown.expect(EidRuntimeException.class); - thrown.expectCause(isA(ParseException.class)); - thrown.expectCause(hasMessage(equalTo(causeMessage))); - // when - EidPreconditions.tryToExecute(procedure, eid); - } - - @Test - public void testTryToExecute_UnsafeProcedure_String_Ok() { - // given - EidPreconditions.UnsafeProcedure procedure = new EidPreconditions.UnsafeProcedure() { - @Override - public void execute() { - // nothing special here, for unit test - } - }; - // when - EidPreconditions.tryToExecute(procedure, eid); - // then - assertThat(procedure).isNotNull(); - } - - @Test - public void testTryToExecute_UnsafeProcedure_Eid() { - // given - final String causeMessage = "An error occured while parsing JSON document at char 178"; - EidPreconditions.UnsafeProcedure procedure = new EidPreconditions.UnsafeProcedure() { - @Override - public void execute() throws ParseException { - throw new ParseException(causeMessage, 178); - } - }; - // then - thrown.expect(EidRuntimeException.class); - thrown.expectCause(isA(ParseException.class)); - thrown.expectCause(hasMessage(equalTo(causeMessage))); - // when - EidPreconditions.tryToExecute(procedure, new Eid(eid)); - } - - @Test - public void testTryToExecute_UnsafeProcedure_Eid_Ok() { - // given - EidPreconditions.UnsafeProcedure procedure = new EidPreconditions.UnsafeProcedure() { - @Override - public void execute() { - // nothing special here, for unit test - } - }; - // when - EidPreconditions.tryToExecute(procedure, new Eid(eid)); - // then - assertThat(procedure).isNotNull(); - } - - @Test - public void testTryToExecute_UnsafeSupplier_String() { - // given - final String causeMessage = "An error occured while parsing JSON document at char 178"; - EidPreconditions.UnsafeSupplier supplier = new EidPreconditions.UnsafeSupplier() { - - @Override - public String get() throws ParseException { - throw new ParseException(causeMessage, 178); - } - }; - // then - thrown.expect(EidRuntimeException.class); - thrown.expectCause(isA(ParseException.class)); - thrown.expectCause(hasMessage(equalTo(causeMessage))); - // when - EidPreconditions.tryToExecute(supplier, eid); - } - - @Test - public void testTryToExecute_UnsafeSupplier_String_Ok() { - // given - final String returning = "An answer to universe and everything"; - EidPreconditions.UnsafeSupplier supplier = new EidPreconditions.UnsafeSupplier() { - @Override - public String get() throws ParseException { - return returning; - } - }; - // when - String answer = EidPreconditions.tryToExecute(supplier, eid); - // then - assertThat(supplier).isNotNull(); - assertThat(answer).isNotNull().isNotEmpty().isEqualTo(returning); - } - - @Test - public void testTryToExecute_UnsafeSupplier_Eid() { - // given - final String causeMessage = "An error occured while parsing JSON document at char 178"; - EidPreconditions.UnsafeSupplier supplier = new EidPreconditions.UnsafeSupplier() { - - @Override - public String get() throws ParseException { - throw new ParseException(causeMessage, 178); - } - }; - // then - thrown.expect(EidRuntimeException.class); - thrown.expectCause(isA(ParseException.class)); - thrown.expectCause(hasMessage(equalTo(causeMessage))); - // when - EidPreconditions.tryToExecute(supplier, new Eid(eid)); - } - - @Test - public void testTryToExecute_UnsafeSupplier_Eid_Ok() { - // given - final String returning = "An answer to universe and everything"; - EidPreconditions.UnsafeSupplier supplier = new EidPreconditions.UnsafeSupplier() { - @Override - public String get() throws ParseException { - return returning; - } - }; - // when - String answer = EidPreconditions.tryToExecute(supplier, new Eid(eid)); - // then - assertThat(supplier).isNotNull(); - assertThat(answer).isNotNull().isNotEmpty().isEqualTo(returning); - } - @Nonnull - private Eid getEid() { - return new Eid(eid); + private DefaultEid getEid() { + return new DefaultEid(eid); } private static Boolean truthyValue() { diff --git a/src/test/java/pl/wavesoftware/testing/JavaAgentSkip.java b/src/test/java/pl/wavesoftware/testing/JavaAgentSkip.java index 5c55eb9..60e20f6 100644 --- a/src/test/java/pl/wavesoftware/testing/JavaAgentSkip.java +++ b/src/test/java/pl/wavesoftware/testing/JavaAgentSkip.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.testing; import org.junit.Assume; diff --git a/src/test/java/pl/wavesoftware/testing/JavaVersion.java b/src/test/java/pl/wavesoftware/testing/JavaVersion.java new file mode 100644 index 0000000..8ea9683 --- /dev/null +++ b/src/test/java/pl/wavesoftware/testing/JavaVersion.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.testing; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-29 + */ +public final class JavaVersion implements Comparable { + private final int major; + + private JavaVersion(int major) { + this.major = major; + } + + public static JavaVersion get() { + return new JavaVersion(getMajor()); + } + + public static JavaVersion of(int major) { + return new JavaVersion(major); + } + + private static int getMajor() { + String version = System.getProperty("java.version"); + if (version.startsWith("1.")) { + version = version.substring(2); + } + // Allow these formats: + // 1.8.0_72-ea + // 9-ea + // 9 + // 9.0.1 + int dotPos = version.indexOf('.'); + int dashPos = version.indexOf('-'); + return Integer.parseInt(version.substring( + 0, + dotPos > -1 + ? dotPos + : dashPos > -1 + ? dashPos : 1 + )); + } + + public boolean greaterOrEqual(JavaVersion other) { + return compareTo(other) >= 0; + } + + @Override + public int compareTo(JavaVersion other) { + return this.major - other.major; + } +} diff --git a/src/test/java/pl/wavesoftware/testing/JmhCleaner.java b/src/test/java/pl/wavesoftware/testing/JmhCleaner.java index b818dc7..ad1b8a4 100644 --- a/src/test/java/pl/wavesoftware/testing/JmhCleaner.java +++ b/src/test/java/pl/wavesoftware/testing/JmhCleaner.java @@ -1,3 +1,19 @@ +/* + * Copyright (c) 2015 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package pl.wavesoftware.testing; import org.apache.commons.io.FileUtils; diff --git a/src/test/java/pl/wavesoftware/testing/JvmArgs.java b/src/test/java/pl/wavesoftware/testing/JvmArgs.java new file mode 100644 index 0000000..a325380 --- /dev/null +++ b/src/test/java/pl/wavesoftware/testing/JvmArgs.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pl.wavesoftware.testing; + +/** + * @author Krzysztof Suszynski + * @since 2018-12-29 + */ +public final class JvmArgs { + + private static final String[] PRE_RELEASE_8 = new String[] { + "-server", "-Xms256m", "-Xmx256m", + "-XX:PermSize=128m", "-XX:MaxPermSize=128m", + "-XX:+UseParNewGC" + }; + + private static final String[] RELEASE_8_PLUS = new String[] { + "-server", "-Xms256m", "-Xmx256m", + "-XX:+UseParallelGC" + }; + + private JvmArgs() { + // nothing here + } + + public static String[] get() { + JavaVersion version = JavaVersion.get(); + return version.greaterOrEqual(JavaVersion.of(8)) + ? RELEASE_8_PLUS : PRE_RELEASE_8; + } +} diff --git a/src/test/resources/META-INF/services/pl.wavesoftware.eid.api.Binding b/src/test/resources/META-INF/services/pl.wavesoftware.eid.api.Binding new file mode 100644 index 0000000..dd8e76f --- /dev/null +++ b/src/test/resources/META-INF/services/pl.wavesoftware.eid.api.Binding @@ -0,0 +1 @@ +pl.wavesoftware.eid.impl.TestBinding diff --git a/src/test/resources/META-INF/services/pl.wavesoftware.eid.api.Configurator b/src/test/resources/META-INF/services/pl.wavesoftware.eid.api.Configurator new file mode 100644 index 0000000..90bbca2 --- /dev/null +++ b/src/test/resources/META-INF/services/pl.wavesoftware.eid.api.Configurator @@ -0,0 +1 @@ +pl.wavesoftware.eid.api.TestConfigurator diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml new file mode 100644 index 0000000..fe834c9 --- /dev/null +++ b/src/test/resources/logback-test.xml @@ -0,0 +1,32 @@ + + + + + + + %highlight(%-5level) %magenta(%d{HH:mm:ss.SSS}) %cyan(%logger{36}) - %msg%n + + + + + + + diff --git a/src/test/resources/simplelogger.properties b/src/test/resources/simplelogger.properties deleted file mode 100644 index 821be00..0000000 --- a/src/test/resources/simplelogger.properties +++ /dev/null @@ -1,5 +0,0 @@ -# SLF4J's SimpleLogger configuration file -org.slf4j.simpleLogger.defaultLogLevel=info -org.slf4j.simpleLogger.showThreadName=false -org.slf4j.simpleLogger.showLogName=false -org.slf4j.simpleLogger.showShortLogName=false