11 | * module Legacy {
12 | * sql Town 'SELECT id, name FROM town' {
13 | * int id;
14 | * String name;
15 | * }
16 | * }
17 | *
18 | */
19 | public interface Searchable {}
20 |
--------------------------------------------------------------------------------
/interface/src/main/java/com/dslplatform/patterns/Identifiable.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.patterns;
2 |
3 | /**
4 | * A domain object is uniquely represented by its URI.
5 | * Entity and snowflake are example of domain objects which are
6 | * identified by their identity, instead of their attributes.
7 | * While entity does not implement {@link Identifiable}, an aggregate root does.
8 | */
9 | public interface Identifiable extends Searchable {
10 | /**
11 | * Domain object identity.
12 | * This identity can be used to lookup a domain object.
13 | *
14 | * @return domain object identity
15 | */
16 | public String getURI();
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/test/java-generated/com/dslplatform/ocd/test/Utils.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.ocd.test;
2 |
3 | import org.w3c.dom.Element;
4 |
5 | public abstract class Utils {
6 | public static Element stringToElement(final String element) {
7 | try {
8 | return XMLConverter.INSTANCE.stringToDocument(element).getDocumentElement();
9 | } catch (final Exception e) {
10 | throw new RuntimeException(e);
11 | }
12 | }
13 |
14 | public static String elementToString(final Element element) {
15 | try {
16 | return XMLConverter.INSTANCE.nodeToString(element);
17 | } catch (final Exception e) {
18 | throw new RuntimeException(e);
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/source/purchaseOrderInstance.json:
--------------------------------------------------------------------------------
1 | {"purchaseOrder":{"@xmlns":"http://tempuri.org/po.xsd","@orderDate":"1999-10-20","shipTo":{"@country":"US","name":"Alice Smith","street":"123 Maple Street","city":"Mill Valley","state":"CA","zip":"90952"},"billTo":{"@country":"US","name":"Robert Smith","street":"8 Oak Avenue","city":"Old Town","state":"PA","zip":"95819"},"comment":"Hurry, my lawn is going wild!","items":{"item":[{"@partNum":"872-AA","productName":"Lawnmower","quantity":"1","USPrice":"148.95","comment":"Confirm this is electric"},{"@partNum":"926-AA","productName":"Baby Monitor","quantity":"1","USPrice":"39.98","shipDate":"1999-05-21"}]}}}
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/xml/reference/purchaseOrderInstance.xml.json:
--------------------------------------------------------------------------------
1 | {"purchaseOrder":{"@xmlns":"http://tempuri.org/po.xsd","@orderDate":"1999-10-20","shipTo":{"@country":"US","name":"Alice Smith","street":"123 Maple Street","city":"Mill Valley","state":"CA","zip":"90952"},"billTo":{"@country":"US","name":"Robert Smith","street":"8 Oak Avenue","city":"Old Town","state":"PA","zip":"95819"},"comment":"Hurry, my lawn is going wild!","items":{"item":[{"@partNum":"872-AA","productName":"Lawnmower","quantity":"1","USPrice":"148.95","comment":"Confirm this is electric"},{"@partNum":"926-AA","productName":"Baby Monitor","quantity":"1","USPrice":"39.98","shipDate":"1999-05-21"}]}}}
--------------------------------------------------------------------------------
/core/src/main/java/com/dslplatform/client/exceptions/HttpSecurityException.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client.exceptions;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 |
6 | public class HttpSecurityException extends HttpException {
7 | private final int receivedCode;
8 |
9 | public HttpSecurityException(final String response, final int receivedCode, final Map> headers) {
10 | super(response, receivedCode, headers);
11 |
12 | this.receivedCode = receivedCode;
13 | }
14 |
15 | @Override
16 | public int getReceivedCode() {
17 | return receivedCode;
18 | }
19 |
20 | private static final long serialVersionUID = 0x0097000a;
21 | }
22 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/reference/purchaseOrderInstance.json.xml.json:
--------------------------------------------------------------------------------
1 | {"purchaseOrder":{"@xmlns":"http://tempuri.org/po.xsd","@orderDate":"1999-10-20","shipTo":{"@country":"US","name":"Alice Smith","street":"123 Maple Street","city":"Mill Valley","state":"CA","zip":"90952"},"billTo":{"@country":"US","name":"Robert Smith","street":"8 Oak Avenue","city":"Old Town","state":"PA","zip":"95819"},"comment":"Hurry, my lawn is going wild!","items":{"item":[{"@partNum":"872-AA","productName":"Lawnmower","quantity":"1","USPrice":"148.95","comment":"Confirm this is electric"},{"@partNum":"926-AA","productName":"Baby Monitor","quantity":"1","USPrice":"39.98","shipDate":"1999-05-21"}]}}}
--------------------------------------------------------------------------------
/core/src/test/java/com/dslplatform/client/DomainProxyTest.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client;
2 |
3 | import org.junit.Test;
4 |
5 | import com.dslplatform.patterns.AggregateRoot;
6 | import com.dslplatform.patterns.ServiceLocator;
7 | import com.dslplatform.patterns.Specification;
8 |
9 | public class DomainProxyTest {
10 | @Test(expected = java.lang.IllegalArgumentException.class)
11 | public void withNullSpecification() throws Exception {
12 | final ServiceLocator locator = Bootstrap.init(getClass().getResourceAsStream("/projectprops/mockproject.properties"));
13 | final DomainProxy dp = locator.resolve(DomainProxy.class);
14 | dp.search((Specification) null);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/test/java-generated/com/dslplatform/ocd/test/TypeFactory.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.ocd.test;
2 |
3 | import java.net.InetAddress;
4 | import java.net.URI;
5 | import java.net.URISyntaxException;
6 | import java.net.UnknownHostException;
7 |
8 | public abstract class TypeFactory {
9 | public static URI buildURI(final String uri) {
10 | try {
11 | return new URI(uri);
12 | } catch (final URISyntaxException e) {
13 | throw new RuntimeException(e);
14 | }
15 | }
16 |
17 | public static InetAddress buildIP(final String ip) {
18 | try {
19 | return InetAddress.getByName(ip);
20 | } catch (final UnknownHostException e) {
21 | throw new RuntimeException(e);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/interface/src/main/java/com/dslplatform/patterns/ServiceLocator.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.patterns;
2 |
3 | /**
4 | * Service for resolving other services.
5 | * One locator per project should be used.
6 | *
7 | * When multiple projects are used, locator must be passed around
8 | * to resolve appropriate service.
9 | *
10 | * Custom classes can be resolved if their dependencies can be satisfied.
11 | */
12 | public interface ServiceLocator {
13 | /**
14 | * Resolve a service registered in the locator.
15 | *
16 | * @param type to be located
17 | * @param clazz class or interface
18 | * @return registered implementation
19 | */
20 | public T resolve(Class clazz);
21 | }
22 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/reference/mixed.json.xml:
--------------------------------------------------------------------------------
1 | abcdsome textsome text1some text2a0some text3a1a2
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/xml/unsupported_use_cases/source/mixed.xml:
--------------------------------------------------------------------------------
1 | abcdsome textsome text1some text2a0some text3a1a2abcdabcdabc#textabcdabcdabc#textsome textsome textsome textsome textsome textsome text
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/unsupported_use_cases/reference/mixed.json.xml:
--------------------------------------------------------------------------------
1 | abcdsome textsome text1some text2a0some text3a1a2abcdabcdabc#textabcdabcdabc#textsome textsome textsome textsome textsome textsome text
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/xml/unsupported_use_cases/reference/reference/mixed.xml.json.xml:
--------------------------------------------------------------------------------
1 | abcdsome textsome text1some text2some text3a0a1a2abcdabcdabc#textabcdabcdabc#textsome textsome textsome textsome textsome textsome text
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/reference/purchaseOrderInstance.json.xml:
--------------------------------------------------------------------------------
1 | Alice Smith123 Maple StreetMill ValleyCA90952Robert Smith8 Oak AvenueOld TownPA95819Hurry, my lawn is going wild!Lawnmower1148.95Confirm this is electricBaby Monitor139.981999-05-21
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/xml/reference/purchaseOrderInstance.xml.json.xml:
--------------------------------------------------------------------------------
1 | Alice Smith123 Maple StreetMill ValleyCA90952Robert Smith8 Oak AvenueOld TownPA95819Hurry, my lawn is going wild!Lawnmower1148.95Confirm this is electricBaby Monitor139.981999-05-21
--------------------------------------------------------------------------------
/core/src/main/java/com/dslplatform/client/exceptions/HttpException.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client.exceptions;
2 |
3 | import java.io.IOException;
4 | import java.util.List;
5 | import java.util.Map;
6 |
7 | public class HttpException extends IOException {
8 | private final int receivedCode;
9 | private final Map> headers;
10 |
11 | public HttpException(final String response, final int receivedCode, final Map> headers) {
12 | super(response);
13 |
14 | this.receivedCode = receivedCode;
15 | this.headers = headers;
16 | }
17 |
18 | public int getReceivedCode() {
19 | return receivedCode;
20 | }
21 | public Map> getHeaders() {
22 | return headers;
23 | }
24 |
25 | private static final long serialVersionUID = 0x0097000a;
26 | }
27 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/unsupported_use_cases/source/mixed.json:
--------------------------------------------------------------------------------
1 | {
2 | "root":{
3 | "array":["a","b","c","d"]
4 | , "#text":"some text"
5 | , "#cdata-section":"some CDATA"
6 | , "#text":"some text1"
7 | , "#text":"some text2"
8 | , "a":"a0"
9 | , "#cdata-section":"some CDATA"
10 | , "#text":"some text3"
11 | , "a":"a1"
12 | , "a":"a2"
13 | , "object":{
14 | "array":["a","b","c","d"]
15 | ,"array":["a","b","c","d"]
16 | ,"array":["a","b","c","#text"]
17 | , "object":{
18 | "array":["a","b","c","d"]
19 | ,"array":["a","b","c","d"]
20 | ,"array":["a","b","c","#text"]
21 | , "#text":"some text"
22 | , "#cdata-section":"some CDATA"
23 | , "#text":"some text"
24 | , "#text":"some text"
25 | } , "#text":"some text"
26 | , "#cdata-section":"some CDATA"
27 | , "#text":"some text"
28 | , "#text":"some text"
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/core/src/main/java/com/dslplatform/client/exceptions/HttpUnexpectedCodeException.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client.exceptions;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Map;
6 |
7 | public class HttpUnexpectedCodeException extends HttpException {
8 | private final List expectedCode = new ArrayList(2);
9 |
10 | public HttpUnexpectedCodeException(
11 | final String response,
12 | final int[] expectedCode,
13 | final int receivedCode,
14 | final Map> headers) {
15 | super(response, receivedCode, headers);
16 |
17 | if (expectedCode != null) {
18 | for (final int ec : expectedCode) {
19 | this.expectedCode.add(ec);
20 | }
21 | }
22 | }
23 |
24 | public List getExpectedCode() {
25 | return expectedCode;
26 | }
27 |
28 | private static final long serialVersionUID = 0x0097000a;
29 | }
30 |
--------------------------------------------------------------------------------
/interface/src/main/java/com/dslplatform/patterns/Either.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.patterns;
2 |
3 | public class Either {
4 | private final T value;
5 | private final Throwable error;
6 |
7 | private Either(final T value, final Throwable error) {
8 | this.value = value;
9 | this.error = error;
10 | }
11 |
12 | public boolean isSuccess() { return error == null; }
13 | public T get() { return value; }
14 | public Throwable whyNot() { return error; }
15 | public String explainError() { return error.getMessage(); }
16 |
17 | public static Either success(final T value) {
18 | return new Either(value, null);
19 | }
20 |
21 | public static Either fail(final Throwable error) {
22 | return new Either(null, error != null ? error : new Throwable());
23 | }
24 |
25 | public static Either fail(final String error) {
26 | return new Either(null, new Throwable(error != null ? error : ""));
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/interface/src/main/java/com/dslplatform/patterns/AggregateRoot.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.patterns;
2 |
3 | /**
4 | * Aggregate root is a meaningful object in the domain.
5 | * It can be viewed as a write boundary for entities and value objects
6 | * that will maintain write consistency.
7 | *
8 | * Usually it represents a single table, but can span several tables
9 | * and can be used like a document or a similar data structure.
10 | * Since every aggregate is also an entity, it has a unique identification
11 | * represented by its URI.
12 | *
28 | */
29 | public interface AggregateRoot extends Identifiable {}
30 |
--------------------------------------------------------------------------------
/project/J2SEVersionCheck.scala:
--------------------------------------------------------------------------------
1 | case class J2SEVersion(majorVersion: Int, minorVersion: Int)
2 |
3 | object J2SEVersion {
4 | val `5` = J2SEVersion(49, 0)
5 | val `6` = J2SEVersion(50, 0)
6 | val `7` = J2SEVersion(51, 0)
7 | val `8` = J2SEVersion(52, 0)
8 | }
9 |
10 | object J2SEVersionCheck {
11 | def apply(bytecode: Array[Byte], versionCheck: J2SEVersion => Boolean) =
12 | new J2SEVersionCheck(bytecode).checkVersion(versionCheck)
13 | }
14 |
15 | private class J2SEVersionCheck(bytecode: Array[Byte])
16 | extends BytecodePickler(bytecode) {
17 |
18 | def checkVersion(versionCheck: J2SEVersion => Boolean): Unit = {
19 | reset()
20 | require(u4() == 0xcafebabe, "Invalid header encountered!")
21 |
22 | val minorVersion = u2()
23 | val majorVersion = u2()
24 |
25 | val j2seVersion = new J2SEVersion(majorVersion, minorVersion)
26 |
27 | if (!versionCheck(j2seVersion)) {
28 | sys.error(s"""J2SE version check failed (got ${j2seVersion.majorVersion}.${j2seVersion.minorVersion})""")
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/interface/src/main/java/com/dslplatform/patterns/Specification.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.patterns;
2 |
3 | /**
4 | * Search predicate which can be used to filter domain objects from the remote
5 | * server using {@link SearchableRepository searchable repository}.
6 | *
7 | * Specification is defined in DSL with keyword {@code specification}
8 | * and a predicate.
9 | * Server can convert specification to SQL query on the fly or call
10 | * database function created at compile time. Other optimization techniques
11 | * can be used too.
12 | *
25 | *
26 | * @param domain object on which search will be performed
27 | */
28 | public interface Specification {}
29 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/source/samlRequest.json:
--------------------------------------------------------------------------------
1 | {"samlp:AuthnRequest":{"@xmlns:samlp":"urn:oasis:names:tc:SAML:2.0:protocol","@ID":"_bec424fa5103428909a30ff1e31168327f79474984","@Version":"2.0","@IssueInstant":"2007-12-10T11:39:34Z","@ForceAuthn":"false","@IsPassive":"false","@ProtocolBinding":"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST","@AssertionConsumerServiceURL":"http://moodle.bridge.feide.no/simplesaml/saml2/sp/AssertionConsumerService.php","saml:Issuer":{"@xmlns:saml":"urn:oasis:names:tc:SAML:2.0:assertion","#text":"\n urn:mace:feide.no:services:no.feide.moodle\n "},"samlp:NameIDPolicy":{"@xmlns:samlp":"urn:oasis:names:tc:SAML:2.0:protocol","@Format":"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent","@SPNameQualifier":"moodle.bridge.feide.no","@AllowCreate":"true"},"samlp:RequestedAuthnContext":{"@xmlns:samlp":"urn:oasis:names:tc:SAML:2.0:protocol","@Comparison":"exact","saml:AuthnContextClassRef":{"@xmlns:saml":"urn:oasis:names:tc:SAML:2.0:assertion","#text":"\n urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport\n "}}}}
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/xml/reference/samlRequest.xml.json:
--------------------------------------------------------------------------------
1 | {"samlp:AuthnRequest":{"@xmlns:samlp":"urn:oasis:names:tc:SAML:2.0:protocol","@ID":"_bec424fa5103428909a30ff1e31168327f79474984","@Version":"2.0","@IssueInstant":"2007-12-10T11:39:34Z","@ForceAuthn":"false","@IsPassive":"false","@ProtocolBinding":"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST","@AssertionConsumerServiceURL":"http://moodle.bridge.feide.no/simplesaml/saml2/sp/AssertionConsumerService.php","saml:Issuer":{"@xmlns:saml":"urn:oasis:names:tc:SAML:2.0:assertion","#text":"\n urn:mace:feide.no:services:no.feide.moodle\n "},"samlp:NameIDPolicy":{"@xmlns:samlp":"urn:oasis:names:tc:SAML:2.0:protocol","@Format":"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent","@SPNameQualifier":"moodle.bridge.feide.no","@AllowCreate":"true"},"samlp:RequestedAuthnContext":{"@xmlns:samlp":"urn:oasis:names:tc:SAML:2.0:protocol","@Comparison":"exact","saml:AuthnContextClassRef":{"@xmlns:saml":"urn:oasis:names:tc:SAML:2.0:assertion","#text":"\n urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport\n "}}}}
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/reference/samlRequest.json.xml.json:
--------------------------------------------------------------------------------
1 | {"samlp:AuthnRequest":{"@xmlns:samlp":"urn:oasis:names:tc:SAML:2.0:protocol","@ID":"_bec424fa5103428909a30ff1e31168327f79474984","@Version":"2.0","@IssueInstant":"2007-12-10T11:39:34Z","@ForceAuthn":"false","@IsPassive":"false","@ProtocolBinding":"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST","@AssertionConsumerServiceURL":"http://moodle.bridge.feide.no/simplesaml/saml2/sp/AssertionConsumerService.php","saml:Issuer":{"@xmlns:saml":"urn:oasis:names:tc:SAML:2.0:assertion","#text":"\n urn:mace:feide.no:services:no.feide.moodle\n "},"samlp:NameIDPolicy":{"@xmlns:samlp":"urn:oasis:names:tc:SAML:2.0:protocol","@Format":"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent","@SPNameQualifier":"moodle.bridge.feide.no","@AllowCreate":"true"},"samlp:RequestedAuthnContext":{"@xmlns:samlp":"urn:oasis:names:tc:SAML:2.0:protocol","@Comparison":"exact","saml:AuthnContextClassRef":{"@xmlns:saml":"urn:oasis:names:tc:SAML:2.0:assertion","#text":"\n urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport\n "}}}}
--------------------------------------------------------------------------------
/project/config/eclipse/sort-settings.bat:
--------------------------------------------------------------------------------
1 | ::#!
2 | @echo off
3 |
4 | for %%a in (*.xml, *.ini, *.txt) do (
5 | call scala -nocompdaemon -savecompiled "%~f0" "%%~fa" > "%%~fa.sorted"
6 | )
7 |
8 | goto :EOF
9 | ::!#
10 |
11 | val filename = args.head
12 | val lines = scala.io.Source.fromFile(filename).getLines.toIndexedSeq
13 |
14 | val sorted =
15 | if (filename endsWith ".xml") {
16 | val marker = (_: String) startsWith " !marker(ev)
18 |
19 | val head = lines takeWhile marker_!
20 | val (body, tail) = (lines dropWhile marker_!) partition marker
21 |
22 | head ++ body.sortBy(identity) ++ tail
23 | }
24 | else if (filename endsWith ".ini") {
25 | val marker = (_: String) startsWith "#"
26 |
27 | val (head, body) = lines partition marker
28 |
29 | head ++ body.sortBy(identity)
30 | }
31 | else if (filename endsWith ".txt") {
32 | lines.sortBy(identity)
33 | }
34 | else {
35 | IndexedSeq.empty
36 | }
37 |
38 | print(sorted mkString("", "\n", "\n"))
39 |
--------------------------------------------------------------------------------
/core/src/test/java/com/dslplatform/client/JacksonTest.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client;
2 |
3 | import org.joda.time.DateTime;
4 | import org.junit.Test;
5 |
6 | import java.io.IOException;
7 |
8 | import static org.junit.Assert.assertEquals;
9 | import static org.junit.Assert.assertTrue;
10 |
11 | public class JacksonTest {
12 | @Test
13 | public void customType() throws IOException {
14 | final JsonSerialization json = new JacksonJsonSerialization(null);
15 | DateTime now1 = DateTime.now();
16 | byte[] res = json.serialize(now1).toByteArray();
17 | DateTime now2 = json.deserialize(DateTime.class, res, res.length);
18 | assertEquals(now1.toDate().getTime(), now2.toDate().getTime());
19 | }
20 |
21 | static class NoEmpty {
22 | public final int i;
23 | public NoEmpty(int i) {
24 | this.i = i;
25 | }
26 | }
27 |
28 | @Test
29 | public void nonDefaultCtor() throws IOException {
30 | final JsonSerialization json = new JacksonJsonSerialization(null);
31 | String res = json.serialize(new NoEmpty(556)).toUtf8();
32 | assertTrue(res.contains("556"));
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DSL client - Java
2 |
3 | ## Introduction
4 |
5 | DSL client is a set of core Java files used as compile target for [DSL Platform] [1].
6 |
7 | If you are new to the DSL Platform, take a look at [introduction] [3] and check out [the tutorials] [4].
8 | You can even [try it online] [5] (but not in Java).
9 |
10 | ## Why?
11 |
12 | DSL client is compatible with [Revenj] [6] REST API. This means it can be used as Java/Android library for interaction with Revenj.
13 |
14 | DSL client can also be used as fastest [JSON serializer] [7] for JVM.
15 |
16 | ## Documentation
17 |
18 | List of documentation resources:
19 |
20 | - [Learn DSL online][5]
21 | - [Domain-Driven Design introduction][2]
22 | - [Java introduction][3]
23 | - [Tutorial][4]
24 |
25 | [1]: https://dsl-platform.com
26 | [2]: https://docs.dsl-platform.com/ddd-foundations
27 | [3]: https://docs.dsl-platform.com/java-introduction
28 | [4]: https://docs.dsl-platform.com/java-beginners-tutorial
29 | [5]: https://learn.dsl-platform.com
30 | [6]: https://github.com/ngs-doo/revenj
31 | [7]: https://github.com/ngs-doo/json-benchmark
32 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/reference/samlRequest.json.xml:
--------------------------------------------------------------------------------
1 |
2 | urn:mace:feide.no:services:no.feide.moodle
3 |
4 | urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
5 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/xml/reference/samlRequest.xml.json.xml:
--------------------------------------------------------------------------------
1 |
2 | urn:mace:feide.no:services:no.feide.moodle
3 |
4 | urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
5 |
--------------------------------------------------------------------------------
/core/src/main/java/com/dslplatform/client/HttpApplicationProxy.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client;
2 |
3 | import java.util.concurrent.Future;
4 |
5 | class HttpApplicationProxy implements ApplicationProxy {
6 | private final static String APPLICATION_URI = "RestApplication.svc/";
7 |
8 | private final HttpClient client;
9 |
10 | public HttpApplicationProxy(final HttpClient client) {
11 | this.client = client;
12 | }
13 |
14 | @Override
15 | public Future get(
16 | final Class manifest,
17 | final String command,
18 | final int[] expectedStatus) {
19 | return client.sendRequest(
20 | manifest,
21 | APPLICATION_URI + command,
22 | "GET",
23 | null,
24 | expectedStatus);
25 | }
26 |
27 | @Override
28 | public Future post(
29 | final Class manifest,
30 | final String command,
31 | final TArgument argument,
32 | final int[] expectedStatus) {
33 | return client.sendRequest(
34 | manifest,
35 | APPLICATION_URI + command,
36 | "POST",
37 | argument,
38 | expectedStatus);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/interface/src/main/java/com/dslplatform/patterns/AggregateDomainEvent.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.patterns;
2 |
3 | /**
4 | * {@link DomainEvent Domain event} which should be used when there is an action
5 | * to be applied on a single {@link AggregateRoot aggregate root}.
6 | *
7 | * When a {@link DomainEvent domain event} affects only a single aggregate,
8 | * a specialized aggregate domain event can be used.
9 | * This event can't have side effects outside the aggregate, which allows it to
10 | * be replayed when it's asynchronous.
11 | * This is useful in write-intensive scenarios to minimize write load in the
12 | * database, but will increase read load, because reading an aggregate will have
13 | * to read all its unapplied events and apply them during reconstruction.
14 | *
15 | * AggregateDomainEvent is defined in DSL with keyword {@code event}.
16 | *
22 | * @param aggregate root type
23 | */
24 | public interface AggregateDomainEvent extends Identifiable {}
25 |
--------------------------------------------------------------------------------
/interface/src/main/java/com/dslplatform/patterns/Report.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.patterns;
2 |
3 | /**
4 | * Report object should be used for reducing round-trips from server.
5 | * When request from server should return multiple data sources
6 | * report concept with it's arguments and results is appropriate.
7 | *
34 | */
35 | public interface Report {}
36 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/xml/source/samlRequest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | urn:mace:feide.no:services:no.feide.moodle
4 |
5 |
6 |
7 |
8 | urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/core/src/test/java/com/dslplatform/client/MapServiceLocatorTest.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client;
2 |
3 | import static org.junit.Assert.assertSame;
4 |
5 | import java.util.HashMap;
6 | import java.util.Map;
7 | import java.util.concurrent.ExecutorService;
8 | import java.util.concurrent.Executors;
9 |
10 | import org.junit.Test;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 |
14 | public class MapServiceLocatorTest {
15 | @Test
16 | public void withDefaultLoggerAndEC() throws Exception {
17 | final Map, Object> initialComponents = new HashMap, Object>();
18 | final ExecutorService executorService = Executors.newSingleThreadExecutor();
19 | initialComponents.put(ExecutorService.class, executorService);
20 | final Logger logger = LoggerFactory.getLogger("test-logger");
21 | initialComponents.put(Logger.class, logger);
22 |
23 | final MapServiceLocator mapServiceLocator = new MapServiceLocator(initialComponents);
24 | assertSame("Executor matches", executorService, mapServiceLocator.resolve(ExecutorService.class));
25 | assertSame("Logger matches", logger, mapServiceLocator.resolve(Logger.class));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/project/BytecodePickler.scala:
--------------------------------------------------------------------------------
1 |
2 | class BytecodePickler(bytecode: Array[Byte]) {
3 | private var index = -1
4 |
5 | protected def reset(): Unit = {
6 | index = 0
7 | }
8 |
9 | protected def u1() = {
10 | val res = bytecode(index) & 0xff
11 | index = index + 1
12 | res
13 | }
14 |
15 | protected def u2() = {
16 | (u1() << 8) | u1()
17 | }
18 |
19 | protected def u4() = {
20 | (u2() << 16) | u2()
21 | }
22 |
23 | protected def u8() = {
24 | (u4().toLong << 16) | u4()
25 | }
26 |
27 | /** Returns number of tag indexes to skip */
28 | protected def skipTag() =
29 | u1 match {
30 | case 1 => index += u2() + 2; 1
31 |
32 | case 3
33 | | 4
34 | | 9
35 | | 10
36 | | 11
37 | | 12 => index += 4; 1
38 |
39 | case 5
40 | | 6 => index += 8; 2
41 |
42 | case 7
43 | | 8 => index += 2; 1
44 |
45 | case tag =>
46 | sys.error("Encountered unknown tag: " + tag)
47 | }
48 |
49 | protected def overwrite(value: Short): Unit = {
50 | bytecode(index -2) = (value >> 8).toByte
51 | bytecode(index -1) = value.toByte
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/core/src/test/java/com/dslplatform/client/TestLogging.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client;
2 |
3 | import com.dslplatform.client.xml.XMLHelpers;
4 | import org.w3c.dom.Document;
5 |
6 | public abstract class TestLogging {
7 | // private final Logger logger = LoggerFactory.getLogger(getClass().getSimpleName());
8 |
9 | protected long now() {
10 | return System.currentTimeMillis();
11 | }
12 |
13 | private void debugInner(final String message) {
14 | // logger.debug(message);
15 | // System.out.println(message);
16 | }
17 |
18 | private void infoInner(final String message) {
19 | // logger.info(message);
20 | System.out.println(message);
21 | }
22 |
23 | protected void debug(final String format, final Object... parts) {
24 | // if (logger.isDebugEnabled()) {
25 | debugInner(String.format(format, parts));
26 | // }
27 | }
28 |
29 | protected void debug(final Document doc) {
30 | // if (logger.isInfoEnabled()) {
31 | debug(XMLHelpers.xmlDocumentToString(doc));
32 | // }
33 | }
34 |
35 | protected void info(final String format, final Object... parts) {
36 | // if (logger.isInfoEnabled()) {
37 | infoInner(String.format(format, parts));
38 | // }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/xml/source/purchaseOrderInstance.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Alice Smith
4 | 123 Maple Street
5 | Mill Valley
6 | CA
7 | 90952
8 |
9 |
10 | Robert Smith
11 | 8 Oak Avenue
12 | Old Town
13 | PA
14 | 95819
15 |
16 | Hurry, my lawn is going wild!
17 |
18 |
19 | Lawnmower
20 | 1
21 | 148.95
22 | Confirm this is electric
23 |
24 |
25 | Baby Monitor
26 | 1
27 | 39.98
28 | 1999-05-21
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/interface/src/main/java/com/dslplatform/patterns/DomainEvent.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.patterns;
2 |
3 | /**
4 | * Domain event represents an meaningful business event that occurred in the system.
5 | * It is a message that back-end system knows how to process and that will
6 | * change the state of the system.
7 | *
8 | * They are the preferred way of manipulating data instead of simple CUD
9 | * operations (create, update, delete).
10 | * Unlike the {@link AggregateDomainEvent aggregate domain event} which is tied
11 | * to a change in a single {@link AggregateRoot aggregate root}, domain event
12 | * should be used when an action will result in modifications to multiple
13 | * aggregates, an external call (like sending an email) or some other action.
14 | *
15 | * By default, events will be applied immediately.
16 | * If {@code async} is used, event will be stored immediately, but applied later.
17 | *
18 | * DomainEvent is defined in DSL with keyword {@code event}.
19 | *
20 | *
19 | *
20 | * @param aggregate root type
21 | */
22 | public final class History implements Identifiable {
23 | private final List> snapshots;
24 |
25 | @SuppressWarnings("unused")
26 | private History() {
27 | this.snapshots = null;
28 | }
29 |
30 | public History(final List> snapshots) {
31 | this.snapshots = snapshots;
32 | }
33 |
34 | /**
35 | * {@link AggregateRoot aggregate root} identity
36 | *
37 | * @return URI found in first snapshot
38 | */
39 | @Override
40 | public String getURI() {
41 | return snapshots.get(0).getValue().getURI();
42 | }
43 |
44 | /**
45 | * Sequence of persisted snapshots.
46 | *
47 | * @return list of snapshots captured for the provided {@link AggregateRoot aggregate root}
48 | */
49 | public List> getSnapshots() {
50 | return snapshots;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/reference/hello.json.xml:
--------------------------------------------------------------------------------
1 | text node in the middleWSDL File for HelloService
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/source/hello.json:
--------------------------------------------------------------------------------
1 | {"definitions":{"@name":"HelloService","@targetNamespace":"http://www.examples.com/wsdl/HelloService.wsdl","@xmlns":"http://schemas.xmlsoap.org/wsdl/","@xmlns:soap":"http://schemas.xmlsoap.org/wsdl/soap/","@xmlns:tns":"http://www.examples.com/wsdl/HelloService.wsdl","@xmlns:xsd":"http://www.w3.org/2001/XMLSchema","message":[{"@name":"SayHelloRequest","part":{"@name":"firstName","@type":"xsd:string"}},{"@name":"SayHelloResponse","part":{"@name":"greeting","@type":"xsd:string"}}],"portType":{"@name":"Hello_PortType","operation":{"@name":"sayHello","input":{"@message":"tns:SayHelloRequest"},"output":{"@message":"tns:SayHelloResponse"}}},"binding":{"@name":"Hello_Binding","@type":"tns:Hello_PortType","soap:binding":{"@style":"rpc","@transport":"http://schemas.xmlsoap.org/soap/http"},"operation":{"@name":"sayHello","soap:operation":{"@soapAction":"sayHello"},"input":{"soap:body":{"@encodingStyle":"http://schemas.xmlsoap.org/soap/encoding/","@namespace":"urn:examples:helloservice","@use":"encoded"}},"#text":"text node in the middle", "#cdata-section":"cdata after text node","output":{"soap:body":{"@encodingStyle":"http://schemas.xmlsoap.org/soap/encoding/","@namespace":"urn:examples:helloservice","@use":"encoded"}}}},"service":{"@name":"Hello_Service","#cdata-section":"cdata in the middle","documentation":"WSDL File for HelloService","port":{"@binding":"tns:Hello_Binding","@name":"Hello_Port","soap:address":{"@location":"http://www.examples.com/SayHello/", "#cdata-section":"cdata somewha at the end"}}}}}
2 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/reference/hello.json.xml.json:
--------------------------------------------------------------------------------
1 | {"definitions":{"@name":"HelloService","@targetNamespace":"http://www.examples.com/wsdl/HelloService.wsdl","@xmlns":"http://schemas.xmlsoap.org/wsdl/","@xmlns:soap":"http://schemas.xmlsoap.org/wsdl/soap/","@xmlns:tns":"http://www.examples.com/wsdl/HelloService.wsdl","@xmlns:xsd":"http://www.w3.org/2001/XMLSchema","message":[{"@name":"SayHelloRequest","part":{"@name":"firstName","@type":"xsd:string"}},{"@name":"SayHelloResponse","part":{"@name":"greeting","@type":"xsd:string"}}],"portType":{"@name":"Hello_PortType","operation":{"@name":"sayHello","input":{"@message":"tns:SayHelloRequest"},"output":{"@message":"tns:SayHelloResponse"}}},"binding":{"@name":"Hello_Binding","@type":"tns:Hello_PortType","soap:binding":{"@style":"rpc","@transport":"http://schemas.xmlsoap.org/soap/http"},"operation":{"@name":"sayHello","soap:operation":{"@soapAction":"sayHello"},"input":{"soap:body":{"@encodingStyle":"http://schemas.xmlsoap.org/soap/encoding/","@namespace":"urn:examples:helloservice","@use":"encoded"}},"#text":"text node in the middle","#cdata-section":"cdata after text node","output":{"soap:body":{"@encodingStyle":"http://schemas.xmlsoap.org/soap/encoding/","@namespace":"urn:examples:helloservice","@use":"encoded"}}}},"service":{"@name":"Hello_Service","#cdata-section":"cdata in the middle","documentation":"WSDL File for HelloService","port":{"@binding":"tns:Hello_Binding","@name":"Hello_Port","soap:address":{"@location":"http://www.examples.com/SayHello/","#cdata-section":"cdata somewha at the end"}}}}}
--------------------------------------------------------------------------------
/interface/src/main/java/com/dslplatform/storage/S3Repository.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.storage;
2 |
3 | import java.io.InputStream;
4 | import java.util.Map;
5 | import java.util.concurrent.Future;
6 |
7 | /**
8 | * S3 can be used to offload large binaries from the application server.
9 | * Bucket and key are saved in the application server.
10 | *
11 | * This service is used by S3 data type
12 | */
13 | public interface S3Repository {
14 | /**
15 | * Load remote stream using bucket and key
16 | *
17 | * @param bucket bucket where stream is stored
18 | * @param key key in bucket for stream
19 | * @return future to stream
20 | */
21 | Future get(String bucket, String key);
22 |
23 | /**
24 | * Upload stream defined by bucket and key.
25 | * Provide length of the stream and additional metadata.
26 | *
27 | * @param bucket bucket where stream will be stored
28 | * @param key key inside a bucket for stream
29 | * @param stream provided stream
30 | * @param length size of stream
31 | * @param metadata additional metadata
32 | * @return future for error checking
33 | */
34 | Future> upload(
35 | String bucket,
36 | String key,
37 | InputStream stream,
38 | long length,
39 | Map metadata);
40 |
41 | /**
42 | * Delete remote stream using bucket and key
43 | *
44 | * @param bucket bucket where stream is stored
45 | * @param key key in bucket for stream
46 | * @return future for error checking
47 | */
48 | Future> delete(String bucket, String key);
49 | }
50 |
--------------------------------------------------------------------------------
/core/src/test/java-generated/com/dslplatform/client/json/Boolean/OneBooleanDefaultValueTurtle.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client.json.Boolean;
2 |
3 | import com.dslplatform.client.JsonSerialization;
4 | import com.dslplatform.patterns.Bytes;
5 | import java.io.IOException;
6 |
7 | public class OneBooleanDefaultValueTurtle {
8 | private static JsonSerialization jsonSerialization;
9 |
10 | @org.junit.BeforeClass
11 | public static void initializeJsonSerialization() throws IOException {
12 | jsonSerialization = com.dslplatform.client.StaticJson.getSerialization();
13 | }
14 |
15 | @org.junit.Test
16 | public void testDefaultValueEquality() throws IOException {
17 | final boolean defaultValue = false;
18 | final Bytes defaultValueJsonSerialized = jsonSerialization.serialize(defaultValue);
19 | final boolean defaultValueJsonDeserialized = jsonSerialization.deserialize(boolean.class, defaultValueJsonSerialized.content, defaultValueJsonSerialized.length);
20 | com.dslplatform.ocd.javaasserts.BooleanAsserts.assertOneEquals(defaultValue, defaultValueJsonDeserialized);
21 | }
22 |
23 | @org.junit.Test
24 | public void testBorderValue1Equality() throws IOException {
25 | final boolean borderValue1 = true;
26 | final Bytes borderValue1JsonSerialized = jsonSerialization.serialize(borderValue1);
27 | final boolean borderValue1JsonDeserialized = jsonSerialization.deserialize(boolean.class, borderValue1JsonSerialized.content, borderValue1JsonSerialized.length);
28 | com.dslplatform.ocd.javaasserts.BooleanAsserts.assertOneEquals(borderValue1, borderValue1JsonDeserialized);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013, Nova Generacija Softvera d.o.o.
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice,
8 | this list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * Neither the name of Nova Generacija Softvera d.o.o. nor the names of its
15 | contributors may be used to endorse or promote products derived from this
16 | software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/interface/src/main/java/com/dslplatform/client/ApplicationProxy.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client;
2 |
3 | import java.util.concurrent.Future;
4 |
5 | /**
6 | * Proxy service to remote RPC-like API.
7 | *
8 | * Remote services can be called using their name.
9 | */
10 | public interface ApplicationProxy {
11 | /**
12 | * When the remote service doesn't require any arguments it can be called
13 | * using the {@code get} method. The class needs to be provided for
14 | * deserialization.
15 | *
16 | * @param result type
17 | * @param manifest result class for deserialization
18 | * @param command remote service name
19 | * @param expectedStatus expected status from remote call
20 | * @return future with the deserialized result
21 | */
22 | public Future get(
23 | Class manifest,
24 | String command,
25 | int[] expectedStatus);
26 |
27 | /**
28 | * When the remote service requires arguments a message with the serialized
29 | * payload will be sent. The class needs to be provided for deserialization.
30 | *
31 | * @param argument type
32 | * @param result type
33 | * @param manifest result class for deserialization
34 | * @param command remote service name
35 | * @param argument remote service argument
36 | * @param expectedStatus expected status from remote call
37 | * @return future with the deserialized result
38 | */
39 | public Future post(
40 | Class manifest,
41 | String command,
42 | TArgument argument,
43 | int[] expectedStatus);
44 | }
45 |
--------------------------------------------------------------------------------
/core/src/main/java/com/dslplatform/client/SettingsHeaderProvider.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client;
2 |
3 | import java.nio.charset.Charset;
4 | import java.util.AbstractMap;
5 | import java.util.ArrayList;
6 | import java.util.List;
7 | import java.util.Map;
8 | import java.util.Properties;
9 |
10 | public class SettingsHeaderProvider implements HttpHeaderProvider {
11 |
12 | private final List> headers = new ArrayList>();
13 |
14 | public SettingsHeaderProvider(final Properties properties) {
15 | final String basicAuth = properties.getProperty("basic-auth");
16 | final String hashAuth = properties.getProperty("hash-auth");
17 | final String authorization = properties.getProperty("authorization");
18 | if (basicAuth != null) {
19 | headers.add(new AbstractMap.SimpleEntry("Authorization", "Basic " + basicAuth));
20 | } else if (hashAuth != null) {
21 | headers.add(new AbstractMap.SimpleEntry("Authorization", "Hash " + hashAuth));
22 | } else if (authorization != null) {
23 | headers.add(new AbstractMap.SimpleEntry("Authorization", authorization));
24 | } else {
25 | final String username = properties.getProperty("username");
26 | //TODO: remove this legacy
27 | final String password = properties.getProperty("project-id");
28 | if (username != null && password != null) {
29 | final String authToken = Utils.base64Encode((username + ':' + password).getBytes(Charset.forName("UTF-8")));
30 | headers.add(new AbstractMap.SimpleEntry("Authorization", "Basic " + authToken));
31 | }
32 | }
33 | }
34 |
35 | @Override
36 | public List> getHeaders() {
37 | return headers;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/core/src/test/java/com/dslplatform/client/BootstrapTest.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.assertSame;
5 |
6 | import java.util.*;
7 | import java.util.concurrent.ExecutorService;
8 | import java.util.concurrent.Executors;
9 |
10 | import org.junit.Test;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 |
14 | import com.dslplatform.patterns.ServiceLocator;
15 |
16 | public class BootstrapTest {
17 |
18 | @Test
19 | public void withDefaultLoggerAndEC() throws Exception {
20 | final ServiceLocator locator = Bootstrap.init(getClass().getResourceAsStream("/projectprops/mockproject.properties"));
21 | final Properties ps = locator.resolve(Properties.class);
22 | assertEquals("Project id matches", ps.getProperty("project-id"), "0e13d168-1e2d-6ced-82f0-b9e693acde3e");
23 | }
24 |
25 | @Test
26 | public void withCustomLoggerAndEC() throws Exception {
27 | final String loggerName = "testLogger";
28 | final Logger logger = LoggerFactory.getLogger(loggerName);
29 | final Map, Object> initialComponents = new HashMap, Object>();
30 | final ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
31 | initialComponents.put(ExecutorService.class, newSingleThreadExecutor);
32 | initialComponents.put(Logger.class, logger);
33 |
34 | final Properties p = new Properties();
35 | p.load(getClass().getResourceAsStream("/projectprops/mockproject.properties"));
36 | final ServiceLocator locator = Bootstrap.init(p, initialComponents);
37 |
38 | assertSame("Logger instance matches.", locator.resolve(Logger.class), logger);
39 | assertSame("ExecutionService matches.", locator.resolve(ExecutorService.class), newSingleThreadExecutor);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/xml/source/hello.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
28 |
32 |
33 |
39 |
40 |
41 |
42 |
43 | WSDL File for HelloService
44 |
45 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/interface/src/main/java/com/dslplatform/patterns/Bytes.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.patterns;
2 |
3 | import java.io.IOException;
4 | import java.io.OutputStream;
5 | import java.nio.charset.Charset;
6 | import java.util.Arrays;
7 |
8 | /**
9 | * Allow reuse of same byte[] by specifying custom length
10 | * Array is valid only up until specified length.
11 | */
12 | public class Bytes {
13 | /**
14 | * Byte array which can be reused
15 | */
16 | public final byte[] content;
17 | /**
18 | * Length which specifies valid data in array
19 | */
20 | public final int length;
21 |
22 | /**
23 | * Create a new instance of Bytes object by providing used array and length which indicates end of valid data.
24 | *
25 | * @param content data
26 | * @param length actual length of array
27 | */
28 | public Bytes(final byte[] content, final int length) {
29 | this.content = content;
30 | this.length = length;
31 | }
32 |
33 | /**
34 | * Helper object for providing zero length object (instead of null object)
35 | */
36 | public static final Bytes EMPTY = new Bytes(new byte[0], 0);
37 |
38 | /**
39 | * Copy bytes to output stream.
40 | *
41 | * @param stream output stream
42 | * @throws IOException
43 | */
44 | public void copyTo(final OutputStream stream) throws IOException {
45 | stream.write(content, 0, length);
46 | }
47 |
48 | private static final Charset utf8 = Charset.forName("UTF-8");
49 |
50 | /**
51 | * Utility method for displaying byte[] as UTF-8 string.
52 | *
53 | * @return string value from UTF-8 charset
54 | */
55 | public String toUtf8() {
56 | return new String(content, 0, length, utf8);
57 | }
58 |
59 | /**
60 | * Utility method for returning byte[] of the actual size.
61 | *
62 | * @return copy of original byte[] with expected length
63 | */
64 | public byte[] toByteArray() {
65 | return Arrays.copyOf(content, length);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/source/purchaseOrder.json:
--------------------------------------------------------------------------------
1 | {"xs:schema":{"@xmlns:xs":"http://www.w3.org/2001/XMLSchema","@targetNamespace":"http://tempuri.org/po.xsd","@xmlns":"http://tempuri.org/po.xsd","@elementFormDefault":"qualified","xs:annotation":{"xs:documentation":{"@xml:lang":"en","#text":"\n Purchase order schema for Example.com.\n Copyright 2000 Example.com. All rights reserved.\n "}},"xs:element":[{"@name":"purchaseOrder","@type":"PurchaseOrderType"},{"@name":"comment","@type":"xs:string"}],"xs:complexType":[{"@name":"PurchaseOrderType","xs:sequence":{"xs:element":[{"@name":"shipTo","@type":"USAddress"},{"@name":"billTo","@type":"USAddress"},{"@ref":"comment","@minOccurs":"0"},{"@name":"items","@type":"Items"}]},"xs:attribute":{"@name":"orderDate","@type":"xs:date"}},{"@name":"USAddress","xs:annotation":{"xs:documentation":"\n Purchase order schema for Example.Microsoft.com.\n Copyright 2001 Example.Microsoft.com. All rights reserved.\n ","xs:appinfo":"\n Application info.\n "},"xs:sequence":{"xs:element":[{"@name":"name","@type":"xs:string"},{"@name":"street","@type":"xs:string"},{"@name":"city","@type":"xs:string"},{"@name":"state","@type":"xs:string"},{"@name":"zip","@type":"xs:decimal"}]},"xs:attribute":{"@name":"country","@type":"xs:NMTOKEN","@fixed":"US"}},{"@name":"Items","xs:sequence":{"xs:element":{"@name":"item","@minOccurs":"0","@maxOccurs":"unbounded","xs:complexType":{"xs:sequence":{"xs:element":[{"@name":"productName","@type":"xs:string"},{"@name":"quantity","xs:simpleType":{"xs:restriction":{"@base":"xs:positiveInteger","xs:maxExclusive":{"@value":"100"}}}},{"@name":"USPrice","@type":"xs:decimal"},{"@ref":"comment","@minOccurs":"0"},{"@name":"shipDate","@type":"xs:date","@minOccurs":"0"}]},"xs:attribute":{"@name":"partNum","@type":"SKU","@use":"required"}}}}}],"xs:simpleType":{"@name":"SKU","xs:restriction":{"@base":"xs:string","xs:pattern":{"@value":"\\d{3}-[A-Z]{2}"}}}}}
2 |
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/xml/reference/purchaseOrder.xml.json:
--------------------------------------------------------------------------------
1 | {"xs:schema":{"@xmlns:xs":"http://www.w3.org/2001/XMLSchema","@targetNamespace":"http://tempuri.org/po.xsd","@xmlns":"http://tempuri.org/po.xsd","@elementFormDefault":"qualified","xs:annotation":{"xs:documentation":{"@xml:lang":"en","#text":"\n Purchase order schema for Example.com.\n Copyright 2000 Example.com. All rights reserved.\n "}},"xs:element":[{"@name":"purchaseOrder","@type":"PurchaseOrderType"},{"@name":"comment","@type":"xs:string"}],"xs:complexType":[{"@name":"PurchaseOrderType","xs:sequence":{"xs:element":[{"@name":"shipTo","@type":"USAddress"},{"@name":"billTo","@type":"USAddress"},{"@ref":"comment","@minOccurs":"0"},{"@name":"items","@type":"Items"}]},"xs:attribute":{"@name":"orderDate","@type":"xs:date"}},{"@name":"USAddress","xs:annotation":{"xs:documentation":"\n Purchase order schema for Example.Microsoft.com.\n Copyright 2001 Example.Microsoft.com. All rights reserved.\n ","xs:appinfo":"\n Application info.\n "},"xs:sequence":{"xs:element":[{"@name":"name","@type":"xs:string"},{"@name":"street","@type":"xs:string"},{"@name":"city","@type":"xs:string"},{"@name":"state","@type":"xs:string"},{"@name":"zip","@type":"xs:decimal"}]},"xs:attribute":{"@name":"country","@type":"xs:NMTOKEN","@fixed":"US"}},{"@name":"Items","xs:sequence":{"xs:element":{"@name":"item","@minOccurs":"0","@maxOccurs":"unbounded","xs:complexType":{"xs:sequence":{"xs:element":[{"@name":"productName","@type":"xs:string"},{"@name":"quantity","xs:simpleType":{"xs:restriction":{"@base":"xs:positiveInteger","xs:maxExclusive":{"@value":"100"}}}},{"@name":"USPrice","@type":"xs:decimal"},{"@ref":"comment","@minOccurs":"0"},{"@name":"shipDate","@type":"xs:date","@minOccurs":"0"}]},"xs:attribute":{"@name":"partNum","@type":"SKU","@use":"required"}}}}}],"xs:simpleType":{"@name":"SKU","xs:restriction":{"@base":"xs:string","xs:pattern":{"@value":"\\d{3}-[A-Z]{2}"}}}}}
--------------------------------------------------------------------------------
/core/src/test/resources/roundtripTests/json/reference/purchaseOrder.json.xml.json:
--------------------------------------------------------------------------------
1 | {"xs:schema":{"@xmlns:xs":"http://www.w3.org/2001/XMLSchema","@targetNamespace":"http://tempuri.org/po.xsd","@xmlns":"http://tempuri.org/po.xsd","@elementFormDefault":"qualified","xs:annotation":{"xs:documentation":{"@xml:lang":"en","#text":"\n Purchase order schema for Example.com.\n Copyright 2000 Example.com. All rights reserved.\n "}},"xs:element":[{"@name":"purchaseOrder","@type":"PurchaseOrderType"},{"@name":"comment","@type":"xs:string"}],"xs:complexType":[{"@name":"PurchaseOrderType","xs:sequence":{"xs:element":[{"@name":"shipTo","@type":"USAddress"},{"@name":"billTo","@type":"USAddress"},{"@ref":"comment","@minOccurs":"0"},{"@name":"items","@type":"Items"}]},"xs:attribute":{"@name":"orderDate","@type":"xs:date"}},{"@name":"USAddress","xs:annotation":{"xs:documentation":"\n Purchase order schema for Example.Microsoft.com.\n Copyright 2001 Example.Microsoft.com. All rights reserved.\n ","xs:appinfo":"\n Application info.\n "},"xs:sequence":{"xs:element":[{"@name":"name","@type":"xs:string"},{"@name":"street","@type":"xs:string"},{"@name":"city","@type":"xs:string"},{"@name":"state","@type":"xs:string"},{"@name":"zip","@type":"xs:decimal"}]},"xs:attribute":{"@name":"country","@type":"xs:NMTOKEN","@fixed":"US"}},{"@name":"Items","xs:sequence":{"xs:element":{"@name":"item","@minOccurs":"0","@maxOccurs":"unbounded","xs:complexType":{"xs:sequence":{"xs:element":[{"@name":"productName","@type":"xs:string"},{"@name":"quantity","xs:simpleType":{"xs:restriction":{"@base":"xs:positiveInteger","xs:maxExclusive":{"@value":"100"}}}},{"@name":"USPrice","@type":"xs:decimal"},{"@ref":"comment","@minOccurs":"0"},{"@name":"shipDate","@type":"xs:date","@minOccurs":"0"}]},"xs:attribute":{"@name":"partNum","@type":"SKU","@use":"required"}}}}}],"xs:simpleType":{"@name":"SKU","xs:restriction":{"@base":"xs:string","xs:pattern":{"@value":"\\d{3}-[A-Z]{2}"}}}}}
--------------------------------------------------------------------------------
/core/src/main/java/com/dslplatform/client/ClientRepository.java:
--------------------------------------------------------------------------------
1 | package com.dslplatform.client;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 | import java.util.concurrent.Future;
6 |
7 | import com.dslplatform.patterns.Identifiable;
8 | import com.dslplatform.patterns.Repository;
9 | import com.dslplatform.patterns.ServiceLocator;
10 |
11 | /**
12 | * Common base implementation for {@link Repository repository}.
13 | * It redirects calls to proxy services.
14 | * It shouldn't be used or resolved.
15 | * Instead domain model repositories should be resolved.
16 | *