├── .buildscript
├── deploy_snapshot.sh
└── settings.xml
├── .codecov.yml
├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── assets
└── feature_graphic.png
├── compiler
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── contentful
│ │ │ └── vault
│ │ │ └── compiler
│ │ │ ├── FieldsInjection.java
│ │ │ ├── Injection.java
│ │ │ ├── ModelInjection.java
│ │ │ ├── Processor.java
│ │ │ ├── SpaceInjection.java
│ │ │ └── SqliteUtils.java
│ └── resources
│ │ └── META-INF
│ │ └── services
│ │ └── javax.annotation.processing.Processor
│ └── test
│ ├── java
│ └── com
│ │ └── contentful
│ │ └── vault
│ │ └── compiler
│ │ ├── ContentTypeTest.java
│ │ ├── FieldTest.java
│ │ ├── SpaceTest.java
│ │ └── lib
│ │ └── TestUtils.java
│ └── resources
│ ├── FieldsInjection.java
│ ├── ModelInjection.java
│ ├── SpaceInjection.java
│ ├── SpaceInjectionCopyPath.java
│ └── SpaceInjectionVersion.java
├── core
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── contentful
│ │ │ └── vault
│ │ │ ├── AbsQuery.java
│ │ │ ├── Asset.java
│ │ │ ├── AutoEscapeValues.java
│ │ │ ├── BaseFields.java
│ │ │ ├── BlobUtils.java
│ │ │ ├── Constants.java
│ │ │ ├── ContentType.java
│ │ │ ├── FetchQuery.java
│ │ │ ├── Field.java
│ │ │ ├── FieldMeta.java
│ │ │ ├── Link.java
│ │ │ ├── LinkResolver.java
│ │ │ ├── ModelHelper.java
│ │ │ ├── ObserveQuery.java
│ │ │ ├── QueryResolver.java
│ │ │ ├── Resource.java
│ │ │ ├── Space.java
│ │ │ ├── SpaceHelper.java
│ │ │ ├── Sql.java
│ │ │ ├── SqliteHelper.java
│ │ │ ├── SyncCallback.java
│ │ │ ├── SyncConfig.java
│ │ │ ├── SyncException.java
│ │ │ ├── SyncResult.java
│ │ │ ├── SyncRunnable.java
│ │ │ ├── Vault.java
│ │ │ ├── VaultDatabaseExporter.java
│ │ │ └── VaultThreadFactory.java
│ └── templates
│ │ └── com
│ │ └── contentful
│ │ └── vault
│ │ └── build
│ │ └── GeneratedBuildParameters.java
│ └── test
│ └── resources
│ └── AndroidManifest.xml
├── jitpack.yml
├── last-module
└── pom.xml
├── mvnw
├── mvnw.cmd
├── pom.xml
├── proguard-vault.cfg
└── tests-integration
├── pom.xml
└── src
├── main
├── AndroidManifest.xml
└── assets
│ └── cfexampleapi.db
└── test
├── java
└── com
│ └── contentful
│ └── vaultintegration
│ ├── AllTheThingsTest.java
│ ├── ArrayLinks.java
│ ├── ArrayTest.java
│ ├── BaseTest.java
│ ├── BlobTest.java
│ ├── DatabaseCopyTest.java
│ ├── LinksTest.java
│ ├── LocaleTest.java
│ ├── LocalizedLinksTest.java
│ ├── ObserveTest.java
│ ├── ParcelableTest.java
│ ├── SqliteEscapeTest.java
│ ├── SyncBase.java
│ ├── SyncPreviewTest.java
│ ├── SyncTest.java
│ ├── UpgradeTest.java
│ ├── VaultTest.java
│ └── lib
│ ├── allthethings
│ ├── AllTheThingsResource.java
│ └── AllTheThingsSpace.java
│ ├── arraylinks
│ ├── MultiLinksSpace.java
│ ├── Product.java
│ └── Shop.java
│ ├── demo
│ ├── Cat.java
│ └── DemoSpace.java
│ ├── escape
│ ├── SqliteEscapeModel.java
│ └── SqliteEscapeSpace.java
│ ├── links
│ ├── AssetsContainer.java
│ └── LinksSpace.java
│ ├── localizedlinks
│ ├── Container.java
│ └── LocalizedLinksSpace.java
│ └── vault
│ ├── ArraysResource.java
│ ├── BlobResource.java
│ └── VaultSpace.java
└── resources
├── AndroidManifest.xml
├── allthethings
├── initial.json
├── locales.json
└── types.json
├── arraylinks
├── initial.json
├── locales.json
└── types.json
├── assets
├── empty.json
├── initial.json
├── locales.json
└── types.json
├── demo
├── initial.json
├── locales.json
├── types.json
└── update.json
├── escape
├── initial.json
├── locales.json
└── types.json
├── links
├── initial.json
├── locales.json
├── types.json
└── update.json
├── localizedlinks
├── initial.json
├── locales.json
└── types.json
└── vault
├── initial.json
├── locales.json
└── types.json
/.buildscript/deploy_snapshot.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Deploy a jar, source jar, and javadoc jar to Sonatype's snapshot repo.
4 | #
5 | # Adapted from https://coderwall.com/p/9b_lfq and
6 | # http://benlimmer.com/2013/12/26/automatically-publish-javadoc-to-gh-pages-with-travis-ci/
7 |
8 | SLUG="contentful/vault"
9 | JDK="oraclejdk8"
10 | BRANCH="master"
11 |
12 | set -e
13 |
14 | if [ "$TRAVIS_REPO_SLUG" != "$SLUG" ]; then
15 | echo "Skipping snapshot deployment: wrong repository. Expected '$SLUG' but was '$TRAVIS_REPO_SLUG'."
16 | elif [ "$TRAVIS_JDK_VERSION" != "$JDK" ]; then
17 | echo "Skipping snapshot deployment: wrong JDK. Expected '$JDK' but was '$TRAVIS_JDK_VERSION'."
18 | elif [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
19 | echo "Skipping snapshot deployment: was pull request."
20 | elif [ "$TRAVIS_BRANCH" != "$BRANCH" ]; then
21 | echo "Skipping snapshot deployment: wrong branch. Expected '$BRANCH' but was '$TRAVIS_BRANCH'."
22 | else
23 | echo "Deploying snapshot to maven ..."
24 | mvn clean source:jar javadoc:jar deploy --settings=".buildscript/settings.xml" -Dmaven.test.skip=true
25 | echo "Snapshot deployed to maven!"
26 | fi
27 |
28 | echo "Deploying snapshot to jitpack ..."
29 | curl https://jitpack.io/com/github/contentful/vault/${TRAVIS_BRANCH}-SNAPSHOT
30 | echo "Snapshot deployed to jitpack!"
31 |
--------------------------------------------------------------------------------
/.buildscript/settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | sonatype-nexus-snapshots
5 | ${env.CI_DEPLOY_USERNAME}
6 | ${env.CI_DEPLOY_PASSWORD}
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.codecov.yml:
--------------------------------------------------------------------------------
1 | coverage:
2 | precision: 1
3 | range: 70...100
4 |
5 | status:
6 | project:
7 | default:
8 | enabled: yes
9 | threshold: 1
10 | if_not_found: success
11 | if_no_updates: success
12 |
13 | comment:
14 | behavior: new
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | target/
3 | *.iml
4 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/contentful/vault/4f6a5ed4f6c592f4ee68a4fac23c876b173b9291/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 |
3 | jdk:
4 | - openjdk8
5 | - oraclejdk8
6 |
7 | after_success:
8 | - .buildscript/deploy_snapshot.sh
9 |
10 | env:
11 | global:
12 | - secure: hRICT/jbg/nUqpf3z1bA0/W5B18gG4tXcS1PknosyCJlDqTzqAoAxY8txwCDaIODXlRTr0Ttmo+JhzR2nvoP0ojMu++FJRtsB7Zk7sC9QPTJJBgVcMiV6GpzMEK/KCBN4Z/bVFnVCUWleEkysKpctYGCpUZodsjicA7CLU2bRSY3wvVF93HugPA00qZjY2o85F/pKH5m1liazo/bO3R1GWZ0qFnisqpFcaGWp0RFeh4GHG2n+h7vZmytE/wHuEg5iXrbb4lq6I4aDVeYOffpUcHp/u6fs2U1wzdNqN0krNcNQcHZI+NaRQzc0nJ3ntWdxJx+FkptBW5p1run1ynvY3y1qhT3F80qEwoLoM8z6jimvD5yJjhzFRDYyykZqNu7XqqYn88PpjUFHtghLBvJQ1WSMb7OmbMdExt/l1W/23FGWRKEcJHD8dw91pv6efZcVqT+JlweVtUiMz0XDEKdZDBjWZqhK4/wiNsIjsNeIocyKESKyzz6jg9p2qu8b8MTTR2hmVtOCJQmbhKl9uC4UVExqsK0w52LQfmtQ82BfsUU7OPMCULOCmnG195v9q0FmgGi7+IQpIm6HmL3iinNTNKFeN3atWz/EgAdmUo4cnjS5KIsf+Ko/IcbsuRLCufT3nnmKKN/JiuBPQ5RM4Eu4LnVils7G+78xbUtUa9q98c=
13 | - secure: LbWygLMrmjUdwuwgPYf8P2RGuzWC+eRgH4DsmZtsy1SvaE26EX4tlPxbrSJFD8qrDTcfrzpJjrIuQzMHC2vN7K592t7XXHFb6iIUocm3wEbjvQSoaHHpX6lLXFNhJSNabhEyhE10DiBfRn9tkXE7NbQjRgyzhb0tD8iNZY/q/xB++NU6ghAICZP/Bx8xuT8ioIIA9RmEgGZRq9Ym9sqpvlZ8Lx8vKXjQlBS8GXKgZcIwwlQRXh6ciRRim29Lsyp9pBrp2rOoTBEbm1vaozuzFuqUuhA/9mdaKGu2/H75vH3iQL3yKcm4Jgb8rAvfSpfaxTxAV3mfG4jYZA6NSyz7WIn9GppPrxnbHZhIMK+g8BbrWyHdRR3IG8LV4j/Ln05LA+0bbJee2stqOLQvRbuHCBqXN1JmsABC8VHJIN2PjLOblvcpV2cf++hq2xzTCSIjXaNt7MhOP/caFC5LnOUFv4JNt4J5KyKa78rl6O6W8IYcBdZtjHdwOPRcIkIHDcqi4kvcLQMt1cz3ZHMoQgc6Izpo3b3hMMuTSdKBbBSbY3towFtg/7XwDW4FXERVaPhs8Z5AYSUnusGlhq2wY0H0oV14HrliQO9i2Tuk2p8hlIRjQQZDzq15YGehWrI/tDpvurgNa9SYGcqxvBn+XPeS3OnTyvEypuG653Wxi/Mb/nQ=
14 |
15 | android:
16 | components:
17 | - tools
18 | - platform-tools
19 | - tools
20 | - build-tools-25.0.3
21 | - android-19
22 | licenses:
23 | - android-.+
24 | - google-.+
25 |
26 | sudo: required
27 |
28 | branches:
29 | except:
30 | - gh-pages
31 |
32 | notifications:
33 | slack:
34 | - secure: KTrEbtoFwNCHe3Xa+WVpyVMENu35Y+rml9Xs7XNtcjk6Ke//DvjGZTIUwuG9GWXmT+aDkLL4CaBUUhRapZdg7CUsBjIU5rusBSsOJEuAWUu0QcLDVRC1lxhSo8Ebcf8KxMtrFAW4h7psjGvDg3eBCj6vH5/+wUMS4lzgeDYoouhZUKETshKd7rrYCQy5qH4nmkoHFKQ5qJNFh/uVCyvQerEZnLOK6EHFfV5ZG9f74gt+3yNYJkQRBEvCccj7cpLUYQze42ZHyvQmqBg8AEad8stJQa4G6wVd186BXTkz03vVdtzivdLgHwcDS0NNkbd4OOiVBR0jX0EyiTAD83GYxX2tSMuumpqEDNGzZuCLdHPR+X2ZpWgHY7XB8ipafpSMMAaB0sxe+YTfjJduFiGcnPr1PcVOIY/sOWZZ4AM7jOR5ymFozQ5XlKcCZQJqrtm4cgQezmJzsTYqRZjmfp4H5VxpFN07qejOcTjKTN/n7nFpbH8LKsEflwhfN/MPHyA4iL9E00X2m3wp+jZLdj9lwjPyPhxRXynmGickvDHbLk7yYb+blO0b2fMYhnKHg1vJMxaB53iChzFv70IWW05O3n+eFH7FwVsboZBWofEmxPmat73HG2x3ViUbAwPEa/LZVAQ8Cw89mxiBZXVd1/3vyIQXWF3iaKdZrDGXIvtx6qY=
35 |
36 | cache:
37 | directories:
38 | - $HOME/.m2
39 |
--------------------------------------------------------------------------------
/assets/feature_graphic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/contentful/vault/4f6a5ed4f6c592f4ee68a4fac23c876b173b9291/assets/feature_graphic.png
--------------------------------------------------------------------------------
/compiler/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | com.contentful.vault
7 | vault-parent
8 | 3.2.7-SNAPSHOT
9 |
10 |
11 | compiler
12 |
13 |
14 |
15 | commons-codec
16 | commons-codec
17 |
18 |
19 |
20 | com.google.guava
21 | guava
22 |
23 |
24 |
25 | com.squareup
26 | javapoet
27 |
28 |
29 |
30 | com.contentful.java
31 | java-sdk
32 |
33 |
34 |
35 | com.google.android
36 | android
37 | provided
38 |
39 |
40 |
41 | com.contentful.vault
42 | core
43 | ${project.version}
44 | provided
45 |
46 |
47 |
48 | sun.jdk
49 | tools
50 | 1.8.0
51 | system
52 | ${java.home}/../lib/tools.jar
53 |
54 |
55 |
56 |
57 | junit
58 | junit
59 | test
60 |
61 |
62 |
63 | com.google.testing.compile
64 | compile-testing
65 | test
66 |
67 |
68 |
69 | com.google.truth
70 | truth
71 | test
72 |
73 |
74 |
75 | commons-io
76 | commons-io
77 | test
78 |
79 |
80 |
81 |
82 |
83 |
84 | src/test/resources
85 |
86 |
87 |
88 |
89 | org.apache.maven.plugins
90 | maven-compiler-plugin
91 |
92 | -proc:none
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/compiler/src/main/java/com/contentful/vault/compiler/FieldsInjection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault.compiler;
18 |
19 | import com.contentful.vault.BaseFields;
20 | import com.contentful.vault.FieldMeta;
21 | import com.google.common.base.CaseFormat;
22 | import com.squareup.javapoet.ClassName;
23 | import com.squareup.javapoet.FieldSpec;
24 | import com.squareup.javapoet.TypeSpec;
25 | import java.util.Set;
26 | import javax.lang.model.element.Modifier;
27 | import javax.lang.model.element.TypeElement;
28 |
29 | final class FieldsInjection extends Injection {
30 | private final Set fields;
31 |
32 | public FieldsInjection(String remoteId, ClassName className, TypeElement originatingElement,
33 | Set fields) {
34 | super(remoteId, className, originatingElement);
35 | this.fields = fields;
36 | }
37 |
38 | @Override TypeSpec.Builder getTypeSpecBuilder() {
39 | TypeSpec.Builder builder = TypeSpec.classBuilder(className.simpleName())
40 | .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
41 | .superclass(BaseFields.class);
42 |
43 | for (FieldMeta field : fields) {
44 | builder.addField(createFieldSpec(field));
45 | }
46 |
47 | return builder;
48 | }
49 |
50 | private FieldSpec createFieldSpec(FieldMeta field) {
51 | String name = CaseFormat.LOWER_CAMEL
52 | .converterTo(CaseFormat.UPPER_UNDERSCORE)
53 | .convert(field.name());
54 | if (name == null) {
55 | throw new IllegalArgumentException(
56 | "Invalid field with ID '" + field.id() + "' for generated class '" +
57 | className.simpleName() + "', has no name.");
58 | }
59 | return FieldSpec.builder(String.class, name, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
60 | .initializer("$S", field.name())
61 | .build();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/compiler/src/main/java/com/contentful/vault/compiler/Injection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault.compiler;
18 |
19 | import com.squareup.javapoet.ClassName;
20 | import com.squareup.javapoet.FieldSpec;
21 | import com.squareup.javapoet.JavaFile;
22 | import com.squareup.javapoet.MethodSpec;
23 | import com.squareup.javapoet.ParameterizedTypeName;
24 | import com.squareup.javapoet.TypeName;
25 | import com.squareup.javapoet.TypeSpec;
26 | import java.util.List;
27 | import java.util.Map;
28 | import javax.lang.model.element.Modifier;
29 | import javax.lang.model.element.TypeElement;
30 |
31 | abstract class Injection {
32 | final String remoteId;
33 |
34 | final ClassName className;
35 |
36 | final TypeElement originatingElement;
37 |
38 | public Injection(String remoteId, ClassName className, TypeElement originatingElement) {
39 | this.remoteId = remoteId;
40 | this.className = className;
41 | this.originatingElement = originatingElement;
42 | }
43 |
44 | JavaFile brewJava() {
45 | TypeSpec.Builder typeSpecBuilder = getTypeSpecBuilder()
46 | .addOriginatingElement(originatingElement);
47 |
48 | return JavaFile.builder(className.packageName(), typeSpecBuilder.build())
49 | .skipJavaLangImports(true)
50 | .build();
51 | }
52 |
53 | abstract TypeSpec.Builder getTypeSpecBuilder();
54 |
55 | protected MethodSpec.Builder createGetterImpl(FieldSpec field, String name) {
56 | return MethodSpec.methodBuilder(name)
57 | .returns(field.type)
58 | .addAnnotation(Override.class)
59 | .addModifiers(Modifier.PUBLIC)
60 | .addStatement("return $N", field.name);
61 | }
62 |
63 | protected FieldSpec.Builder createListWithInitializer(String name,
64 | Class extends List> listClass, TypeName typeName) {
65 | TypeName listTypeName = ParameterizedTypeName.get(ClassName.get(List.class), typeName);
66 |
67 | TypeName initializerTypeName =
68 | ParameterizedTypeName.get(ClassName.get(listClass), typeName);
69 |
70 | return FieldSpec.builder(listTypeName, name).initializer("new $T()", initializerTypeName);
71 | }
72 |
73 | protected FieldSpec.Builder createMapWithInitializer(String name, Class extends Map> mapClass,
74 | TypeName keyTypeName, TypeName valueTypeName) {
75 | TypeName mapTypeName = ParameterizedTypeName.get(
76 | ClassName.get(Map.class), keyTypeName, valueTypeName);
77 |
78 | TypeName linkedMapTypeName = ParameterizedTypeName.get(
79 | ClassName.get(mapClass), keyTypeName, valueTypeName);
80 |
81 | return FieldSpec.builder(mapTypeName, name)
82 | .initializer("new $T()", linkedMapTypeName);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/compiler/src/main/java/com/contentful/vault/compiler/SqliteUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault.compiler;
18 |
19 | import java.util.List;
20 | import java.util.Map;
21 | import org.apache.commons.codec.binary.Base64;
22 |
23 | final class SqliteUtils {
24 | private SqliteUtils() {
25 | throw new AssertionError();
26 | }
27 |
28 | static String typeForClass(String className) {
29 | if (String.class.getName().equals(className)) {
30 | return "TEXT";
31 | } else if (Boolean.class.getName().equals(className)) {
32 | return "BOOL";
33 | } else if (Integer.class.getName().equals(className)) {
34 | return "INT";
35 | } else if (Double.class.getName().equals(className)) {
36 | return "DOUBLE";
37 | } else if (Map.class.getName().equals(className)) {
38 | return "BLOB";
39 | } else if (List.class.getName().equals(className)) {
40 | return "BLOB";
41 | }
42 | return null;
43 | }
44 |
45 | static String hashForId(String id) {
46 | return Base64.encodeBase64String(id.getBytes()).replaceAll("=", "").toLowerCase();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/compiler/src/main/resources/META-INF/services/javax.annotation.processing.Processor:
--------------------------------------------------------------------------------
1 | com.contentful.vault.compiler.Processor
--------------------------------------------------------------------------------
/compiler/src/test/java/com/contentful/vault/compiler/ContentTypeTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault.compiler;
18 |
19 | import com.google.common.base.Joiner;
20 | import com.google.testing.compile.JavaFileObjects;
21 |
22 | import org.junit.Test;
23 |
24 | import javax.tools.JavaFileObject;
25 |
26 | import static com.contentful.vault.compiler.lib.TestUtils.processors;
27 | import static com.contentful.vault.compiler.lib.TestUtils.readTestResource;
28 | import static com.google.common.truth.Truth.assert_;
29 | import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
30 |
31 | public class ContentTypeTest {
32 | @Test public void testInjection() throws Exception {
33 | JavaFileObject source = JavaFileObjects.forSourceString("Test", Joiner.on('\n').join(
34 | "import com.contentful.vault.Asset;",
35 | "import com.contentful.vault.ContentType;",
36 | "import com.contentful.vault.Field;",
37 | "import com.contentful.vault.Resource;",
38 | "import com.contentful.vault.SpaceHelper;",
39 | "import java.util.List;",
40 | "import java.util.Map;",
41 | "class Test {",
42 | " @ContentType(\"cid\")",
43 | " static class AwesomeModel extends Resource {",
44 | " @Field String textField;",
45 | " @Field Boolean booleanField;",
46 | " @Field Integer integerField;",
47 | " @Field Double doubleField;",
48 | " @Field Map mapField;",
49 | " @Field Asset assetLink;",
50 | " @Field AwesomeModel entryLink;",
51 | " @Field List arrayOfAssets;",
52 | " @Field List arrayOfModels;",
53 | " @Field List arrayOfSymbols;",
54 | " }",
55 | "}"
56 | ));
57 |
58 | JavaFileObject expectedSource = JavaFileObjects.forSourceString(
59 | "Test$AwesomeModel$$ModelHelper",
60 | readTestResource("ModelInjection.java"));
61 |
62 | assert_().about(javaSource()).that(source)
63 | .processedWith(processors())
64 | .compilesWithoutError()
65 | .and()
66 | .generatesSources(expectedSource);
67 | }
68 |
69 | @Test public void failsEmptyId() throws Exception {
70 | JavaFileObject source = JavaFileObjects.forSourceString("Test",
71 | Joiner.on('\n').join(
72 | "import com.contentful.vault.ContentType;",
73 | "import com.contentful.vault.Resource;",
74 | "@ContentType(\"\")",
75 | "class Test extends Resource {",
76 | "}"
77 | ));
78 |
79 | assert_().about(javaSource()).that(source)
80 | .processedWith(processors())
81 | .failsToCompile()
82 | .withErrorContaining("@ContentType id may not be empty. (Test)");
83 | }
84 |
85 | @Test public void failsInvalidType() throws Exception {
86 | JavaFileObject source = JavaFileObjects.forSourceString("Test", Joiner.on('\n').join(
87 | "import com.contentful.vault.ContentType;",
88 | "import java.util.Date;",
89 | "@ContentType(\"cid\")",
90 | "class Test {",
91 | "}"));
92 |
93 | assert_().about(javaSource()).that(source)
94 | .processedWith(processors())
95 | .failsToCompile()
96 | .withErrorContaining(
97 | "Classes annotated with @ContentType must extend \"com.contentful.vault.Resource\". "
98 | + "(Test)");
99 | }
100 |
101 | @Test public void failsNoFields() throws Exception {
102 | JavaFileObject source = JavaFileObjects.forSourceString("Test", Joiner.on('\n').join(
103 | "import com.contentful.vault.ContentType;",
104 | "import com.contentful.vault.Resource;",
105 | "@ContentType(\"foo\")",
106 | "class Test extends Resource {",
107 | "}"));
108 |
109 | assert_().about(javaSource()).that(source)
110 | .processedWith(processors())
111 | .failsToCompile()
112 | .withErrorContaining("Model must contain at least one @Field element. (Test)");
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/compiler/src/test/java/com/contentful/vault/compiler/lib/TestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault.compiler.lib;
18 |
19 | import com.contentful.vault.compiler.Processor;
20 |
21 | import org.apache.commons.io.FileUtils;
22 |
23 | import java.io.File;
24 | import java.io.IOException;
25 | import java.net.URL;
26 | import java.nio.charset.Charset;
27 | import java.util.Arrays;
28 |
29 | public class TestUtils {
30 | public static Iterable extends Processor> processors() {
31 | return Arrays.asList(new Processor());
32 | }
33 |
34 | public static String readTestResource(String fileName) throws IOException {
35 | URL resource = TestUtils.class.getClassLoader().getResource(fileName);
36 | return FileUtils.readFileToString(new File(resource.getPath()), Charset.defaultCharset());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/compiler/src/test/resources/FieldsInjection.java:
--------------------------------------------------------------------------------
1 | import com.contentful.vault.BaseFields;
2 |
3 | public final class Test$Model$Fields extends BaseFields {
4 | public static final String FOO = "foo";
5 |
6 | public static final String BAR = "bar";
7 |
8 | public static final String BAZ = "baz";
9 |
10 | public static final String BAZ2 = "baz2";
11 |
12 | public static final String B_A_Z_123 = "b_a_z_123";
13 | }
--------------------------------------------------------------------------------
/compiler/src/test/resources/ModelInjection.java:
--------------------------------------------------------------------------------
1 | import android.database.Cursor;
2 | import com.contentful.vault.Asset;
3 | import com.contentful.vault.FieldMeta;
4 | import com.contentful.vault.ModelHelper;
5 | import com.contentful.vault.SpaceHelper;
6 | import java.util.ArrayList;
7 | import java.util.HashMap;
8 | import java.util.List;
9 | import java.util.Map;
10 |
11 | public final class Test$AwesomeModel$$ModelHelper extends ModelHelper {
12 | final List fields = new ArrayList();
13 |
14 | public Test$AwesomeModel$$ModelHelper() {
15 | fields.add(FieldMeta.builder().setId("textField").setName("textField").setSqliteType("TEXT").build());
16 | fields.add(FieldMeta.builder().setId("booleanField").setName("booleanField").setSqliteType("BOOL").build());
17 | fields.add(FieldMeta.builder().setId("integerField").setName("integerField").setSqliteType("INT").build());
18 | fields.add(FieldMeta.builder().setId("doubleField").setName("doubleField").setSqliteType("DOUBLE").build());
19 | fields.add(FieldMeta.builder().setId("mapField").setName("mapField").setSqliteType("BLOB").build());
20 | fields.add(FieldMeta.builder().setId("assetLink").setName("assetLink").setLinkType("ASSET").build());
21 | fields.add(FieldMeta.builder().setId("entryLink").setName("entryLink").setLinkType("ENTRY").build());
22 | fields.add(FieldMeta.builder().setId("arrayOfAssets").setName("arrayOfAssets").setArrayType(
23 | "com.contentful.vault.Asset").build());
24 | fields.add(FieldMeta.builder().setId("arrayOfModels").setName("arrayOfModels").setArrayType("Test.AwesomeModel").build());
25 | fields.add(FieldMeta.builder().setId("arrayOfSymbols").setName("arrayOfSymbols").setSqliteType(
26 | "BLOB").setArrayType("java.lang.String").build());
27 | }
28 |
29 | @Override
30 | public List getFields() {
31 | return fields;
32 | }
33 |
34 | @Override
35 | public String getTableName() {
36 | return "entry_y2lk";
37 | }
38 |
39 | @Override
40 | public List getCreateStatements(SpaceHelper spaceHelper) {
41 | List list = new ArrayList();
42 | for (String code : spaceHelper.getLocales()) {
43 | list.add("CREATE TABLE `entry_y2lk$" + code + "` (`remote_id` STRING NOT NULL UNIQUE, `created_at` STRING NOT NULL, `updated_at` STRING, `textField` TEXT, `booleanField` BOOL, `integerField` INT, `doubleField` DOUBLE, `mapField` BLOB, `arrayOfSymbols` BLOB);");
44 | }
45 | return list;
46 | }
47 |
48 | @Override
49 | @SuppressWarnings("unchecked")
50 | public Test.AwesomeModel fromCursor(Cursor cursor) {
51 | Test.AwesomeModel result = new Test.AwesomeModel();
52 | setContentType(result, "cid");
53 | result.textField = cursor.getString(3);
54 | result.booleanField = Integer.valueOf(1).equals(cursor.getInt(4));
55 | result.integerField = cursor.getInt(5);
56 | result.doubleField = cursor.getDouble(6);
57 | result.mapField = fieldFromBlob(HashMap.class, cursor, 7);
58 | result.arrayOfSymbols = fieldFromBlob(ArrayList.class, cursor, 8);
59 | return result;
60 | }
61 |
62 | @Override
63 | @SuppressWarnings("unchecked")
64 | public boolean setField(Test.AwesomeModel resource, String name, Object value) {
65 | if ("textField".equals(name)) {
66 | resource.textField = (String) value;
67 | }
68 | else if ("booleanField".equals(name)) {
69 | resource.booleanField = (Boolean) value;
70 | }
71 | else if ("integerField".equals(name)) {
72 | resource.integerField = (Integer) value;
73 | }
74 | else if ("doubleField".equals(name)) {
75 | resource.doubleField = (Double) value;
76 | }
77 | else if ("mapField".equals(name)) {
78 | resource.mapField = (Map) value;
79 | }
80 | else if ("assetLink".equals(name)) {
81 | resource.assetLink = (Asset) value;
82 | }
83 | else if ("entryLink".equals(name)) {
84 | resource.entryLink = (Test.AwesomeModel) value;
85 | }
86 | else if ("arrayOfAssets".equals(name)) {
87 | resource.arrayOfAssets = (List) value;
88 | }
89 | else if ("arrayOfModels".equals(name)) {
90 | resource.arrayOfModels = (List) value;
91 | }
92 | else if ("arrayOfSymbols".equals(name)) {
93 | resource.arrayOfSymbols = (List) value;
94 | }
95 | else {
96 | return false;
97 | }
98 | return true;
99 | }
100 | }
--------------------------------------------------------------------------------
/compiler/src/test/resources/SpaceInjection.java:
--------------------------------------------------------------------------------
1 | import com.contentful.vault.ModelHelper;
2 | import com.contentful.vault.Resource;
3 | import com.contentful.vault.SpaceHelper;
4 | import java.util.Arrays;
5 | import java.util.LinkedHashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | public final class Test$AwesomeSpace$$SpaceHelper extends SpaceHelper {
10 | final Map, ModelHelper>> models = new LinkedHashMap, ModelHelper>>();
11 |
12 | final Map> types = new LinkedHashMap>();
13 |
14 | final List locales = Arrays.asList("foo", "bar");
15 |
16 | public Test$AwesomeSpace$$SpaceHelper() {
17 | models.put(Test.Model.class, new Test$Model$$ModelHelper());
18 | types.put("cid", Test.Model.class);
19 | }
20 |
21 | @Override
22 | public String getDatabaseName() {
23 | return "space_c2lk";
24 | }
25 |
26 | @Override
27 | public int getDatabaseVersion() {
28 | return 1;
29 | }
30 |
31 | @Override
32 | public Map, ModelHelper>> getModels() {
33 | return models;
34 | }
35 |
36 | @Override
37 | public Map> getTypes() {
38 | return types;
39 | }
40 |
41 | @Override
42 | public String getCopyPath() {
43 | return null;
44 | }
45 |
46 | @Override
47 | public String getSpaceId() {
48 | return "sid";
49 | }
50 |
51 | @Override
52 | public List getLocales() {
53 | return locales;
54 | }
55 | }
--------------------------------------------------------------------------------
/compiler/src/test/resources/SpaceInjectionCopyPath.java:
--------------------------------------------------------------------------------
1 | import com.contentful.vault.ModelHelper;
2 | import com.contentful.vault.Resource;
3 | import com.contentful.vault.SpaceHelper;
4 | import java.util.Arrays;
5 | import java.util.LinkedHashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | public final class Test$AwesomeSpace$$SpaceHelper extends SpaceHelper {
10 | final Map, ModelHelper>> models = new LinkedHashMap, ModelHelper>>();
11 |
12 | final Map> types = new LinkedHashMap>();
13 |
14 | final List locales = Arrays.asList("foo");
15 |
16 | public Test$AwesomeSpace$$SpaceHelper() {
17 | models.put(Test.Model.class, new Test$Model$$ModelHelper());
18 | types.put("cid", Test.Model.class);
19 | }
20 |
21 | @Override
22 | public String getDatabaseName() {
23 | return "space_c2lk";
24 | }
25 |
26 | @Override
27 | public int getDatabaseVersion() {
28 | return 1;
29 | }
30 |
31 | @Override
32 | public Map, ModelHelper>> getModels() {
33 | return models;
34 | }
35 |
36 | @Override
37 | public Map> getTypes() {
38 | return types;
39 | }
40 |
41 | @Override
42 | public String getCopyPath() {
43 | return "foo.db";
44 | }
45 |
46 | @Override
47 | public String getSpaceId() {
48 | return "sid";
49 | }
50 |
51 | @Override
52 | public List getLocales() {
53 | return locales;
54 | }
55 | }
--------------------------------------------------------------------------------
/compiler/src/test/resources/SpaceInjectionVersion.java:
--------------------------------------------------------------------------------
1 | import com.contentful.vault.ModelHelper;
2 | import com.contentful.vault.Resource;
3 | import com.contentful.vault.SpaceHelper;
4 | import java.util.Arrays;
5 | import java.util.LinkedHashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | public final class Test$AwesomeSpace$$SpaceHelper extends SpaceHelper {
10 | final Map, ModelHelper>> models = new LinkedHashMap, ModelHelper>>();
11 |
12 | final Map> types = new LinkedHashMap>();
13 |
14 | final List locales = Arrays.asList("foo");
15 |
16 | public Test$AwesomeSpace$$SpaceHelper() {
17 | models.put(Test.Model.class, new Test$Model$$ModelHelper());
18 | types.put("cid", Test.Model.class);
19 | }
20 |
21 | @Override
22 | public String getDatabaseName() {
23 | return "space_c2lk";
24 | }
25 |
26 | @Override
27 | public int getDatabaseVersion() {
28 | return 9;
29 | }
30 |
31 | @Override
32 | public Map, ModelHelper>> getModels() {
33 | return models;
34 | }
35 |
36 | @Override
37 | public Map> getTypes() {
38 | return types;
39 | }
40 |
41 | @Override
42 | public String getCopyPath() {
43 | return null;
44 | }
45 |
46 | @Override
47 | public String getSpaceId() {
48 | return "sid";
49 | }
50 |
51 |
52 | @Override
53 | public List getLocales() {
54 | return locales;
55 | }
56 | }
--------------------------------------------------------------------------------
/core/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | com.contentful.vault
7 | vault-parent
8 | 3.2.7-SNAPSHOT
9 |
10 |
11 | core
12 |
13 |
14 |
15 | org.apache.commons
16 | commons-lang3
17 |
18 |
19 |
20 | commons-io
21 | commons-io
22 |
23 |
24 |
25 | com.contentful.java
26 | java-sdk
27 |
28 |
29 |
30 | com.google.android
31 | android
32 | provided
33 |
34 |
35 |
36 | io.reactivex.rxjava3
37 | rxjava
38 | 3.0.0
39 | provided
40 |
41 |
42 |
43 |
44 | junit
45 | junit
46 | test
47 |
48 |
49 |
50 | org.mockito
51 | mockito-core
52 | test
53 |
54 |
55 |
56 | org.robolectric
57 | robolectric
58 | test
59 |
60 |
61 |
62 |
63 |
64 |
65 | src/main/resources
66 | true
67 |
68 |
69 | src/main/templates
70 | true
71 |
72 | ${project.build.directory}/generated-sources/
73 |
74 |
75 |
76 |
77 |
78 |
79 | org.codehaus.mojo
80 | build-helper-maven-plugin
81 | ${build-helper.version}
82 |
83 |
84 | generate-sources
85 |
86 | add-source
87 |
88 |
89 |
90 | ${project.build.directory}/generated-sources/
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/AbsQuery.java:
--------------------------------------------------------------------------------
1 | package com.contentful.vault;
2 |
3 | abstract class AbsQuery> {
4 | private final Class type;
5 |
6 | private final Vault vault;
7 |
8 | private Params params = new Params();
9 |
10 | AbsQuery(Class type, Vault vault) {
11 | this.type = type;
12 | this.vault = vault;
13 | }
14 |
15 | @SuppressWarnings("unchecked")
16 | public E where(String selection, String... args) {
17 | params.setSelection(selection);
18 | params.setSelectionArgs(args);
19 | return (E) this;
20 | }
21 |
22 | @SuppressWarnings("unchecked")
23 | public E limit(Integer limit) {
24 | String value = null;
25 | if (limit != null) {
26 | value = limit.toString();
27 | }
28 | params.setLimit(value);
29 | return (E) this;
30 | }
31 |
32 | @SuppressWarnings("unchecked")
33 | public E order(String... order) {
34 | params.setOrder(order);
35 | return (E) this;
36 | }
37 |
38 | Class type() {
39 | return type;
40 | }
41 |
42 | Vault vault() {
43 | return vault;
44 | }
45 |
46 | Params params() {
47 | return params;
48 | }
49 |
50 | void setParams(Params params) {
51 | this.params = params;
52 | }
53 |
54 | static final class Params {
55 | private String selection;
56 | private String[] selectionArgs;
57 | private String limit;
58 | private String[] order;
59 |
60 | public String selection() {
61 | return selection;
62 | }
63 |
64 | public void setSelection(String selection) {
65 | this.selection = selection;
66 | }
67 |
68 | public String[] selectionArgs() {
69 | return selectionArgs;
70 | }
71 |
72 | public void setSelectionArgs(String[] selectionArgs) {
73 | this.selectionArgs = selectionArgs;
74 | }
75 |
76 | public String limit() {
77 | return limit;
78 | }
79 |
80 | public void setLimit(String limit) {
81 | this.limit = limit;
82 | }
83 |
84 | public String[] order() {
85 | return order;
86 | }
87 |
88 | public void setOrder(String[] order) {
89 | this.order = order;
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/Asset.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import android.os.Parcel;
20 | import android.os.Parcelable;
21 | import java.util.HashMap;
22 | import java.util.Map;
23 |
24 | import static com.contentful.java.cda.CDAType.ASSET;
25 |
26 | public final class Asset extends Resource implements Parcelable {
27 | private final String url;
28 |
29 | private final String mimeType;
30 |
31 | private final String title;
32 |
33 | private final String description;
34 |
35 | private final HashMap file;
36 |
37 | Asset(Builder builder) {
38 | this.url = builder.url;
39 | this.mimeType = builder.mimeType;
40 | this.title = builder.title;
41 | this.description = builder.description;
42 | this.file = builder.file;
43 | }
44 |
45 | public String url() {
46 | return url;
47 | }
48 |
49 | public String mimeType() {
50 | return mimeType;
51 | }
52 |
53 | public String title() {
54 | return title;
55 | }
56 |
57 | public String description() {
58 | return description;
59 | }
60 |
61 | public Map file() {
62 | return file;
63 | }
64 |
65 | @Override String getIdPrefix() {
66 | return ASSET.toString();
67 | }
68 |
69 | static Builder builder() {
70 | return new Builder();
71 | }
72 |
73 | static class Builder {
74 | String url;
75 | String mimeType;
76 | String title;
77 | String description;
78 | HashMap file;
79 |
80 | public Builder setUrl(String url) {
81 | this.url = url;
82 | return this;
83 | }
84 |
85 | public Builder setMimeType(String mimeType) {
86 | this.mimeType = mimeType;
87 | return this;
88 | }
89 |
90 | public Builder setTitle(String title) {
91 | this.title = title;
92 | return this;
93 | }
94 |
95 | public Builder setDescription(String description) {
96 | this.description = description;
97 | return this;
98 | }
99 |
100 | public Builder setFile(HashMap file) {
101 | this.file = file;
102 | return this;
103 | }
104 |
105 | public Asset build() {
106 | return new Asset(this);
107 | }
108 | }
109 |
110 | // Parcelable
111 | public int describeContents() {
112 | return 0;
113 | }
114 |
115 | public void writeToParcel(Parcel out, int flags) {
116 | out.writeString(remoteId());
117 |
118 | out.writeString(createdAt());
119 |
120 | writeOptionalString(out, updatedAt());
121 |
122 | out.writeString(url);
123 |
124 | out.writeString(mimeType);
125 |
126 | writeOptionalString(out, title());
127 |
128 | writeOptionalString(out, description());
129 |
130 | if (file == null) {
131 | out.writeInt(-1);
132 | } else {
133 | out.writeInt(1);
134 | out.writeSerializable(file);
135 | }
136 | }
137 |
138 | private void writeOptionalString(Parcel out, String s) {
139 | if (s == null) {
140 | out.writeInt(-1);
141 | } else {
142 | out.writeInt(1);
143 | out.writeString(s);
144 | }
145 | }
146 |
147 | public static final Parcelable.Creator CREATOR
148 | = new Parcelable.Creator() {
149 | public Asset createFromParcel(Parcel in) {
150 | return new Asset(in);
151 | }
152 |
153 | public Asset[] newArray(int size) {
154 | return new Asset[size];
155 | }
156 | };
157 |
158 | @SuppressWarnings("unchecked")
159 | Asset(Parcel in) {
160 | setRemoteId(in.readString());
161 |
162 | setCreatedAt(in.readString());
163 |
164 | if (in.readInt() != -1) {
165 | setUpdatedAt(in.readString());
166 | }
167 |
168 | this.url = in.readString();
169 |
170 | this.mimeType = in.readString();
171 |
172 | if (in.readInt() == -1) {
173 | this.title = null;
174 | } else {
175 | this.title = in.readString();
176 | }
177 |
178 | if (in.readInt() == -1) {
179 | this.description = null;
180 | } else {
181 | this.description = in.readString();
182 | }
183 |
184 | if (in.readInt() == -1) {
185 | this.file = null;
186 | } else {
187 | this.file = (HashMap) in.readSerializable();
188 | }
189 | }
190 |
191 | public static final class Fields extends BaseFields {
192 | public static final String URL = "url";
193 |
194 | public static final String MIME_TYPE = "mime_type";
195 |
196 | public static final String TITLE = "title";
197 |
198 | public static final String DESCRIPTION = "description";
199 |
200 | public static final String FILE = "file";
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/AutoEscapeValues.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import android.content.ContentValues;
20 | import java.util.Map;
21 | import java.util.Set;
22 |
23 | import static com.contentful.vault.Sql.escape;
24 |
25 | final class AutoEscapeValues {
26 | private final ContentValues values = new ContentValues();
27 |
28 | public void put(String key, String value) {
29 | values.put(escape(key), value);
30 | }
31 |
32 | public void put(String key, Byte value) {
33 | values.put(escape(key), value);
34 | }
35 |
36 | public void put(String key, Short value) {
37 | values.put(escape(key), value);
38 | }
39 |
40 | public void put(String key, Integer value) {
41 | values.put(escape(key), value);
42 | }
43 |
44 | public void put(String key, Long value) {
45 | values.put(escape(key), value);
46 | }
47 |
48 | public void put(String key, Float value) {
49 | values.put(escape(key), value);
50 | }
51 |
52 | public void put(String key, Double value) {
53 | values.put(escape(key), value);
54 | }
55 |
56 | public void put(String key, Boolean value) {
57 | values.put(escape(key), value);
58 | }
59 |
60 | public void put(String key, byte[] value) {
61 | values.put(escape(key), value);
62 | }
63 |
64 | public void putNull(String key) {
65 | values.putNull(escape(key));
66 | }
67 |
68 | public int size() {
69 | return values.size();
70 | }
71 |
72 | public void remove(String key) {
73 | values.remove(escape(key));
74 | }
75 |
76 | public void clear() {
77 | values.clear();
78 | }
79 |
80 | public boolean containsKey(String key) {
81 | return values.containsKey(escape(key));
82 | }
83 |
84 | public Object get(String key) {
85 | return values.get(escape(key));
86 | }
87 |
88 | public String getAsString(String key) {
89 | return values.getAsString(escape(key));
90 | }
91 |
92 | public Long getAsLong(String key) {
93 | return values.getAsLong(escape(key));
94 | }
95 |
96 | public Integer getAsInteger(String key) {
97 | return values.getAsInteger(escape(key));
98 | }
99 |
100 | public Short getAsShort(String key) {
101 | return values.getAsShort(escape(key));
102 | }
103 |
104 | public Byte getAsByte(String key) {
105 | return values.getAsByte(escape(key));
106 | }
107 |
108 | public Double getAsDouble(String key) {
109 | return values.getAsDouble(escape(key));
110 | }
111 |
112 | public Float getAsFloat(String key) {
113 | return values.getAsFloat(escape(key));
114 | }
115 |
116 | public Boolean getAsBoolean(String key) {
117 | return values.getAsBoolean(escape(key));
118 | }
119 |
120 | public byte[] getAsByteArray(String key) {
121 | return values.getAsByteArray(escape(key));
122 | }
123 |
124 | public Set> valueSet() {
125 | return values.valueSet();
126 | }
127 |
128 | public Set keySet() {
129 | return values.keySet();
130 | }
131 |
132 | public ContentValues get() {
133 | return values;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/BaseFields.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | public abstract class BaseFields {
20 | public static final String REMOTE_ID = "remote_id";
21 |
22 | public static final String CREATED_AT = "created_at";
23 |
24 | public static final String UPDATED_AT = "updated_at";
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/BlobUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import java.io.ByteArrayInputStream;
20 | import java.io.ByteArrayOutputStream;
21 | import java.io.IOException;
22 | import java.io.ObjectInputStream;
23 | import java.io.ObjectOutputStream;
24 | import java.io.Serializable;
25 |
26 | final class BlobUtils {
27 | @SuppressWarnings("unchecked")
28 | static T fromBlob(Class clazz, byte[] blob)
29 | throws IOException, ClassNotFoundException {
30 | T result = null;
31 | ObjectInputStream ois = null;
32 | try {
33 | ByteArrayInputStream bos = new ByteArrayInputStream(blob);
34 | ois = new ObjectInputStream(bos);
35 | result = (T) ois.readObject();
36 | } finally {
37 | if (ois != null) {
38 | try {
39 | ois.close();
40 | } catch (IOException e) {
41 | e.printStackTrace();
42 | }
43 | }
44 | }
45 | return result;
46 | }
47 |
48 | static byte[] toBlob(Serializable object) throws IOException {
49 | ObjectOutputStream oos = null;
50 | ByteArrayOutputStream bos;
51 | byte[] result = null;
52 | try {
53 | bos = new ByteArrayOutputStream();
54 | oos = new ObjectOutputStream(bos);
55 | oos.writeObject(object);
56 | result = bos.toByteArray();
57 | } finally {
58 | if (oos != null) {
59 | try {
60 | oos.close();
61 | } catch (IOException e) {
62 | e.printStackTrace();
63 | }
64 | }
65 | }
66 | return result;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/Constants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | public final class Constants {
20 | private Constants() {
21 | throw new AssertionError();
22 | }
23 |
24 | public static final String SUFFIX_FIELDS = "$Fields";
25 |
26 | public static final String SUFFIX_MODEL = "$$ModelHelper";
27 |
28 | public static final String SUFFIX_SPACE = "$$SpaceHelper";
29 | }
30 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/ContentType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import java.lang.annotation.Retention;
20 | import java.lang.annotation.Target;
21 |
22 | import static java.lang.annotation.ElementType.TYPE;
23 | import static java.lang.annotation.RetentionPolicy.CLASS;
24 |
25 | @Target(TYPE)
26 | @Retention(CLASS)
27 | public @interface ContentType {
28 | /** Remote ID */
29 | String value();
30 | }
31 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/FetchQuery.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import java.util.List;
20 |
21 | public final class FetchQuery extends AbsQuery> {
22 | FetchQuery(Class type, Vault vault) {
23 | super(type, vault);
24 | }
25 |
26 | List resolveAll(boolean resolveLinks, String locale) {
27 | if (locale == null) {
28 | locale = vault().getSqliteHelper().getSpaceHelper().getDefaultLocale();
29 | }
30 | return new QueryResolver<>(this).all(resolveLinks, locale);
31 | }
32 |
33 | T resolveFirst(boolean resolveLinks, String locale) {
34 | if (locale == null) {
35 | locale = vault().getSqliteHelper().getSpaceHelper().getDefaultLocale();
36 | }
37 | List all = limit(1).resolveAll(resolveLinks, locale);
38 | if (all.isEmpty()) {
39 | return null;
40 | }
41 | return all.get(0);
42 | }
43 |
44 | public List all() {
45 | return all(null);
46 | }
47 |
48 | public List all(String locale) {
49 | return resolveAll(true, locale);
50 | }
51 |
52 | public T first() {
53 | return first(null);
54 | }
55 |
56 | public T first(String locale) {
57 | return resolveFirst(true, locale);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/Field.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import java.lang.annotation.Retention;
20 | import java.lang.annotation.Target;
21 |
22 | import static java.lang.annotation.ElementType.FIELD;
23 | import static java.lang.annotation.RetentionPolicy.CLASS;
24 |
25 | @Target(FIELD)
26 | @Retention(CLASS)
27 | public @interface Field {
28 | /** Remote ID. Leave this blank in order to use the name of the annotated field as the ID. */
29 | String value() default "";
30 | }
31 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/FieldMeta.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import javax.lang.model.type.TypeMirror;
20 |
21 | public final class FieldMeta {
22 | private final String id;
23 |
24 | private final String name;
25 |
26 | private final TypeMirror type;
27 |
28 | private final String sqliteType;
29 |
30 | private final String linkType;
31 |
32 | private final String arrayType;
33 |
34 | FieldMeta(Builder builder) {
35 | this.id = builder.id;
36 | this.name = builder.name;
37 | this.type = builder.type;
38 | this.sqliteType = builder.sqliteType;
39 | this.linkType = builder.linkType;
40 | this.arrayType = builder.arrayType;
41 | }
42 |
43 | public String id() {
44 | return id;
45 | }
46 |
47 | public String name() {
48 | return name;
49 | }
50 |
51 | public TypeMirror type() {
52 | return type;
53 | }
54 |
55 | public String sqliteType() {
56 | return sqliteType;
57 | }
58 |
59 | public String linkType() {
60 | return linkType;
61 | }
62 |
63 | public String arrayType() {
64 | return arrayType;
65 | }
66 |
67 | public boolean isLink() {
68 | return linkType != null;
69 | }
70 |
71 | public boolean isArray() {
72 | return arrayType != null;
73 | }
74 |
75 | public boolean isArrayOfSymbols() {
76 | return isArray() && String.class.getName().equals(arrayType);
77 | }
78 |
79 | public boolean isArrayOfLinks() {
80 | return isArray() && !isArrayOfSymbols();
81 | }
82 |
83 | @Override public boolean equals(Object o) {
84 | if (this == o) return true;
85 | if (!(o instanceof FieldMeta)) return false;
86 |
87 | FieldMeta fieldMeta = (FieldMeta) o;
88 |
89 | return id.equals(fieldMeta.id);
90 | }
91 |
92 | @Override public int hashCode() {
93 | return id.hashCode();
94 | }
95 |
96 | public static class Builder {
97 | String id;
98 | String name;
99 | TypeMirror type;
100 | String sqliteType;
101 | String linkType;
102 | String arrayType;
103 |
104 | public Builder setId(String id) {
105 | this.id = id;
106 | return this;
107 | }
108 |
109 | public Builder setName(String name) {
110 | this.name = name;
111 | return this;
112 | }
113 |
114 | public Builder setType(TypeMirror type) {
115 | this.type = type;
116 | return this;
117 | }
118 |
119 | public Builder setSqliteType(String sqliteType) {
120 | this.sqliteType = sqliteType;
121 | return this;
122 | }
123 |
124 | public Builder setLinkType(String linkType) {
125 | this.linkType = linkType;
126 | return this;
127 | }
128 |
129 | public Builder setArrayType(String arrayType) {
130 | this.arrayType = arrayType;
131 | return this;
132 | }
133 |
134 | public FieldMeta build() {
135 | return new FieldMeta(this);
136 | }
137 | }
138 |
139 | public static Builder builder() {
140 | return new Builder();
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/Link.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | final class Link {
20 | private final String parent;
21 |
22 | private final String child;
23 |
24 | private final String fieldId;
25 |
26 | private final String childContentType;
27 |
28 | Link(String parent, String child, String fieldId, String childContentType) {
29 | this.parent = parent;
30 | this.child = child;
31 | this.fieldId = fieldId;
32 | this.childContentType = childContentType;
33 | }
34 |
35 | public String parent() {
36 | return parent;
37 | }
38 |
39 | public String child() {
40 | return child;
41 | }
42 |
43 | public String fieldId() {
44 | return fieldId;
45 | }
46 |
47 | public String childContentType() {
48 | return childContentType;
49 | }
50 |
51 | public boolean isAsset() {
52 | return childContentType == null;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/ModelHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import android.database.Cursor;
20 | import java.io.IOException;
21 | import java.io.Serializable;
22 | import java.util.List;
23 |
24 | public abstract class ModelHelper {
25 | public abstract String getTableName();
26 |
27 | public abstract List getFields();
28 |
29 | public abstract List getCreateStatements(SpaceHelper spaceHelper);
30 |
31 | public abstract T fromCursor(Cursor cursor);
32 |
33 | protected abstract boolean setField(T resource, String name, Object value);
34 |
35 | protected final E fieldFromBlob(Class clazz, Cursor cursor,
36 | int columnIndex) {
37 | byte[] blob = cursor.getBlob(columnIndex);
38 | if (blob == null || blob.length == 0) {
39 | return null;
40 | }
41 | E result = null;
42 | Exception exception = null;
43 | try {
44 | result = BlobUtils.fromBlob(clazz, blob);
45 | } catch (IOException | ClassNotFoundException e) {
46 | exception = e;
47 | }
48 | if (exception != null) {
49 | throw new RuntimeException(String.format("Failed creating BLOB from column %d of %s.",
50 | columnIndex, getTableName()), exception);
51 | }
52 | return result;
53 | }
54 |
55 | protected final void setContentType(T resource, String type) {
56 | resource.setContentType(type);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/ObserveQuery.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import java.util.List;
20 |
21 | import io.reactivex.rxjava3.annotations.NonNull;
22 | import io.reactivex.rxjava3.core.BackpressureStrategy;
23 | import io.reactivex.rxjava3.core.Flowable;
24 | import io.reactivex.rxjava3.core.FlowableEmitter;
25 | import io.reactivex.rxjava3.core.FlowableOnSubscribe;
26 |
27 | public final class ObserveQuery extends AbsQuery> {
28 | ObserveQuery(Class type, Vault vault) {
29 | super(type, vault);
30 | }
31 |
32 | public Flowable all() {
33 | return all(null);
34 | }
35 |
36 | public Flowable all(String locale) {
37 | return Flowable.create(new AllOnSubscribe(this, locale), BackpressureStrategy.BUFFER);
38 | }
39 |
40 | static class AllOnSubscribe implements FlowableOnSubscribe {
41 | private final ObserveQuery query;
42 | private final String locale;
43 |
44 | public AllOnSubscribe(ObserveQuery query, String locale) {
45 | this.query = query;
46 | this.locale = locale;
47 | }
48 |
49 | @Override
50 | public void subscribe(@NonNull FlowableEmitter emitter) {
51 | try {
52 | FetchQuery fetchQuery = query.vault().fetch(query.type());
53 | fetchQuery.setParams(query.params());
54 | List items = fetchQuery.all(locale);
55 | for (T item : items) {
56 | if (emitter.isCancelled()) {
57 | return;
58 | }
59 | emitter.onNext(item);
60 | }
61 | } catch (Throwable t) {
62 | if (!emitter.isCancelled()) {
63 | emitter.onError(t);
64 | }
65 | return;
66 | }
67 | if (!emitter.isCancelled()) {
68 | emitter.onComplete();
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/QueryResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import android.database.Cursor;
20 | import java.util.ArrayList;
21 | import java.util.HashMap;
22 | import java.util.List;
23 | import java.util.Map;
24 |
25 | import static android.text.TextUtils.join;
26 | import static com.contentful.vault.Sql.TABLE_ASSETS;
27 | import static com.contentful.vault.Sql.escape;
28 | import static com.contentful.vault.Sql.localizeName;
29 |
30 | final class QueryResolver {
31 | private final AbsQuery query;
32 |
33 | private final Vault vault;
34 |
35 | private final Map assets = new HashMap<>();
36 |
37 | private final Map entries = new HashMap<>();
38 |
39 | QueryResolver(AbsQuery query) {
40 | this.query = query;
41 | this.vault = query.vault();
42 | }
43 |
44 | List all(boolean resolveLinks, String locale) {
45 | Cursor cursor = cursorFromQuery(query, locale);
46 | List result = new ArrayList();
47 | try {
48 | if (cursor.moveToFirst()) {
49 | Map cache = cacheForType(query.type());
50 | do {
51 | T item = vault.getSqliteHelper().fromCursor(query.type(), cursor);
52 | if (item == null) {
53 | continue;
54 | }
55 | result.add(item);
56 | cache.put(item.remoteId(), item);
57 | } while (cursor.moveToNext());
58 | }
59 | } finally {
60 | cursor.close();
61 | }
62 |
63 | if (resolveLinks && query.type() != Asset.class && !result.isEmpty()) {
64 | resolveLinks(result, locale);
65 | }
66 |
67 | return result;
68 | }
69 |
70 | private Map cacheForType(Class type) {
71 | if (type == Asset.class) {
72 | return assets;
73 | }
74 | return entries;
75 | }
76 |
77 | private void resolveLinks(List resources, String locale) {
78 | LinkResolver resolver = new LinkResolver(query, assets, entries);
79 | for (T resource : resources) {
80 | resolver.resolveLinks(resource, helperForEntry(resource).getFields(), locale);
81 | }
82 | }
83 |
84 | private ModelHelper> helperForEntry(T resource) {
85 | SpaceHelper spaceHelper = vault.getSqliteHelper().getSpaceHelper();
86 | Class> modelType = spaceHelper.getTypes().get(resource.contentType());
87 | return spaceHelper.getModels().get(modelType);
88 | }
89 |
90 | private Cursor cursorFromQuery(AbsQuery query, String locale) {
91 | String[] orderArray = query.params().order();
92 | String order = null;
93 | if (orderArray != null && orderArray.length > 0) {
94 | order = join(", ", orderArray);
95 | }
96 | String tableName;
97 | if (query.type() == Asset.class) {
98 | tableName = TABLE_ASSETS;
99 | } else {
100 | tableName = query.vault()
101 | .getSqliteHelper()
102 | .getSpaceHelper()
103 | .getModels()
104 | .get(query.type())
105 | .getTableName();
106 | }
107 | return query.vault().getReadableDatabase().query(
108 | escape(localizeName(tableName, locale)),
109 | null, // columns
110 | query.params().selection(), // selection
111 | query.params().selectionArgs(), // selectionArgs
112 | null, // groupBy
113 | null, // having
114 | order, // order
115 | query.params().limit()); // limit
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/Resource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import org.apache.commons.lang3.StringUtils;
20 |
21 | public abstract class Resource {
22 | String remoteId;
23 |
24 | String createdAt;
25 |
26 | String updatedAt;
27 |
28 | String contentType;
29 |
30 | public String remoteId() {
31 | return remoteId;
32 | }
33 |
34 | public String createdAt() {
35 | return createdAt;
36 | }
37 |
38 | public String updatedAt() {
39 | return updatedAt;
40 | }
41 |
42 | void setRemoteId(String remoteId) {
43 | this.remoteId = remoteId;
44 | }
45 |
46 | void setCreatedAt(String createdAt) {
47 | this.createdAt = createdAt;
48 | }
49 |
50 | void setUpdatedAt(String updatedAt) {
51 | this.updatedAt = updatedAt;
52 | }
53 |
54 | void setContentType(String contentType) {
55 | this.contentType = contentType;
56 | }
57 |
58 | String contentType() {
59 | return contentType;
60 | }
61 |
62 | String getIdPrefix() {
63 | return null;
64 | }
65 |
66 | @Override public boolean equals(Object o) {
67 | if (this == o) return true;
68 | if (!(o instanceof Resource)) return false;
69 |
70 | Resource resource = (Resource) o;
71 | String prefix = StringUtils.defaultString(getIdPrefix(), "");
72 | if (!prefix.equals(StringUtils.defaultString(resource.getIdPrefix(), ""))) return false;
73 | return (prefix + remoteId()).equals(prefix + resource.remoteId());
74 | }
75 |
76 | @Override public int hashCode() {
77 | return (StringUtils.defaultString(getIdPrefix(), "") + remoteId).hashCode();
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/Space.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import java.lang.annotation.Retention;
20 | import java.lang.annotation.Target;
21 |
22 | import static java.lang.annotation.ElementType.TYPE;
23 | import static java.lang.annotation.RetentionPolicy.CLASS;
24 |
25 | @Target(TYPE)
26 | @Retention(CLASS)
27 | public @interface Space {
28 | /** Remote ID */
29 | String value();
30 |
31 | /** Supported {@link Resource} models. */
32 | Class>[] models();
33 |
34 | /**
35 | * Version of the database. Increasing this value will trigger a migration.
36 | * WARNING: Migrations invalidate any pre-existing data.
37 | */
38 | int dbVersion() default 1;
39 |
40 | /**
41 | * File path under the application's 'assets' folder pointing to an existing Vault database file.
42 | * This is used for pre-populating the database with static content prior to initial sync.
43 | * The first time the database file is created if this property is not blank Vault will attempt
44 | * and copy the contents to its database.
45 | *
46 | * If you wish to apply a {@code copyPath} to an shipped app make sure to increase
47 | * the {@code dbVersion} property.
48 | */
49 | String copyPath() default "";
50 |
51 | /** Array of locale codes. */
52 | String[] locales();
53 | }
54 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/SpaceHelper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import java.util.List;
20 | import java.util.Map;
21 |
22 | public abstract class SpaceHelper {
23 | public abstract String getDatabaseName();
24 |
25 | public abstract int getDatabaseVersion();
26 |
27 | public abstract Map, ModelHelper>> getModels();
28 |
29 | public abstract Map> getTypes();
30 |
31 | public abstract String getCopyPath();
32 |
33 | public abstract String getSpaceId();
34 |
35 | public abstract List getLocales();
36 |
37 | public final String getDefaultLocale() {
38 | return getLocales().get(0);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/Sql.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import java.util.Arrays;
20 | import java.util.List;
21 | import org.apache.commons.lang3.StringUtils;
22 |
23 | import static com.contentful.vault.BaseFields.CREATED_AT;
24 | import static com.contentful.vault.BaseFields.REMOTE_ID;
25 | import static com.contentful.vault.BaseFields.UPDATED_AT;
26 |
27 | public final class Sql {
28 | private Sql() {
29 | throw new AssertionError();
30 | }
31 |
32 | public static final String[] RESOURCE_COLUMNS = new String[] {
33 | declareField(REMOTE_ID, "STRING", false, " UNIQUE"),
34 | declareField(CREATED_AT, "STRING", false, null),
35 | declareField(UPDATED_AT, "STRING", true, null),
36 | };
37 |
38 | static final String TABLE_ENTRY_TYPES = "entry_types";
39 | static final String TABLE_SYNC_INFO = "sync_info";
40 | static final String TABLE_ASSETS = "assets";
41 | static final String TABLE_LINKS = "links";
42 |
43 | static final String CREATE_ENTRY_TYPES = "CREATE TABLE "
44 | + escape(TABLE_ENTRY_TYPES) + " ("
45 | + declareField(REMOTE_ID, "STRING", false, ", ")
46 | + declareField("type_id", "STRING", false, ", ")
47 | + "UNIQUE(" + escape(REMOTE_ID) + ")"
48 | + ");";
49 |
50 | static final String CREATE_SYNC_INFO = "CREATE TABLE "
51 | + escape(TABLE_SYNC_INFO) + " ("
52 | + declareField("token", "STRING", false, ", ")
53 | + declareField("last_sync_ts", "TIMESTAMP", false, " DEFAULT CURRENT_TIMESTAMP")
54 | + ");";
55 |
56 | static String createLinks(String locale) {
57 | return "CREATE TABLE " + escape(localizeName(TABLE_LINKS, locale)) + " ("
58 | + declareField("parent", "STRING", false, ", ")
59 | + declareField("child", "STRING", false, ", ")
60 | + declareField("field", "STRING", false, ", ")
61 | + declareField("is_asset", "INT", false, ", ")
62 | + declareField("position", "INT", false, ", ")
63 | + "UNIQUE ("
64 | + escape("parent") + ", "
65 | + escape("child") + ", "
66 | + escape("field") + ", "
67 | + escape("is_asset") + ", "
68 | + escape("position") + ")"
69 | + ");";
70 | }
71 |
72 | static String createAssets(String locale) {
73 | return "CREATE TABLE " + escape(localizeName(TABLE_ASSETS, locale)) + " ("
74 | + StringUtils.join(RESOURCE_COLUMNS, ", ") + ","
75 | + declareField(Asset.Fields.URL, "STRING", true, ", ")
76 | + declareField(Asset.Fields.MIME_TYPE, "STRING", true, ", ")
77 | + declareField(Asset.Fields.TITLE, "STRING", true, ", ")
78 | + declareField(Asset.Fields.DESCRIPTION, "STRING", true, ", ")
79 | + declareField(Asset.Fields.FILE, "BLOB", true, null)
80 | + ");";
81 | }
82 |
83 | static final List RESOURCE_COLUMN_INDEXES = Arrays.asList(
84 | REMOTE_ID,
85 | CREATED_AT,
86 | UPDATED_AT);
87 |
88 | static final List ASSET_COLUMN_INDEXES = Arrays.asList(
89 | Asset.Fields.URL,
90 | Asset.Fields.MIME_TYPE,
91 | Asset.Fields.TITLE,
92 | Asset.Fields.DESCRIPTION,
93 | Asset.Fields.FILE);
94 |
95 | static int resourceColumnIndex(String name) {
96 | int i = RESOURCE_COLUMN_INDEXES.indexOf(name);
97 | if (i == -1) {
98 | throw new IllegalArgumentException("Invalid resource column name '" + name + '.');
99 | }
100 | return i;
101 | }
102 |
103 | static int assetColumnIndex(String name) {
104 | int i = ASSET_COLUMN_INDEXES.indexOf(name);
105 | if (i == -1) {
106 | throw new IllegalArgumentException("Invalid asset column name '" + name + '.');
107 | }
108 | return RESOURCE_COLUMNS.length + i;
109 | }
110 |
111 | static String escape(String name) {
112 | return String.format("`%s`", name);
113 | }
114 |
115 | static String declareField(String name, String type, boolean nullable, String suffix) {
116 | StringBuilder builder = new StringBuilder();
117 | builder.append(escape(name))
118 | .append(" ")
119 | .append(type);
120 | if (!nullable) {
121 | builder.append(" ")
122 | .append("NOT NULL");
123 | }
124 | if (suffix != null) {
125 | builder.append(suffix);
126 | }
127 | return builder.toString();
128 | }
129 |
130 | static String localizeName(String name, String locale) {
131 | return String.format("%s$%s", name, locale);
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/SyncCallback.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | public abstract class SyncCallback {
20 | private String tag;
21 |
22 | public abstract void onResult(SyncResult result);
23 |
24 | final void setTag(String tag) {
25 | this.tag = tag;
26 | }
27 |
28 | final String getTag() {
29 | return tag;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/SyncConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import com.contentful.java.cda.CDAClient;
20 |
21 | import static com.contentful.vault.build.GeneratedBuildParameters.PROJECT_VERSION;
22 | import static java.text.MessageFormat.format;
23 |
24 | public final class SyncConfig {
25 | private final CDAClient client;
26 |
27 | private final boolean invalidate;
28 |
29 | SyncConfig(Builder builder) {
30 | this.invalidate = builder.invalidate;
31 |
32 | if (builder.client == null) {
33 | if (builder.accessToken == null) {
34 | throw new IllegalStateException("Cannot create a CDA client with no access token. " +
35 | "Please set it.");
36 | }
37 |
38 | if (builder.spaceId == null) {
39 | throw new IllegalStateException("Cannot create a CDA client with no space id. " +
40 | "Please set it.");
41 | }
42 |
43 | this.client = CDAClient
44 | .builder()
45 | .setToken(builder.accessToken)
46 | .setSpace(builder.spaceId)
47 | .setEnvironment(builder.environment)
48 | .setIntegration("Vault", PROJECT_VERSION)
49 | .build();
50 | } else {
51 | this.client = builder.client;
52 | }
53 | }
54 |
55 | public CDAClient client() {
56 | return client;
57 | }
58 |
59 | public boolean shouldInvalidate() {
60 | return invalidate;
61 | }
62 |
63 | public static Builder builder() {
64 | return new Builder();
65 | }
66 |
67 | public static class Builder {
68 |
69 | private static final String FIELD_ALREADY_EXISTS = "Do not set {0}, when {1} is already set. " +
70 | "Use either {0} or a previously added {1}.";
71 |
72 | CDAClient client;
73 | boolean invalidate;
74 | String accessToken;
75 | String spaceId;
76 | String environment;
77 |
78 | public Builder setAccessToken(String accessToken) {
79 | if (client != null) {
80 | throw new IllegalStateException(format(FIELD_ALREADY_EXISTS, "access token", "client"));
81 | }
82 | this.accessToken = accessToken;
83 | return this;
84 | }
85 |
86 | public Builder setSpaceId(String spaceId) {
87 | if (client != null) {
88 | throw new IllegalStateException(format(FIELD_ALREADY_EXISTS, "space id", "client"));
89 | }
90 | this.spaceId = spaceId;
91 | return this;
92 | }
93 |
94 | public Builder setEnvironment(String environment) {
95 | if (client != null) {
96 | throw new IllegalStateException(format(FIELD_ALREADY_EXISTS, "environment", "client"));
97 | }
98 | this.environment = environment;
99 | return this;
100 | }
101 |
102 | public Builder setClient(CDAClient client) {
103 | if (accessToken != null) {
104 | throw new IllegalStateException(format(FIELD_ALREADY_EXISTS, "client", "access token"));
105 | }
106 | if (spaceId != null) {
107 | throw new IllegalStateException(format(FIELD_ALREADY_EXISTS, "client", "space id"));
108 | }
109 |
110 | if (environment != null) {
111 | throw new IllegalStateException(format(FIELD_ALREADY_EXISTS, "client", "environment"));
112 | }
113 |
114 | this.client = client;
115 | return this;
116 | }
117 |
118 | public Builder setInvalidate(boolean invalidate) {
119 | this.invalidate = invalidate;
120 | return this;
121 | }
122 |
123 | public SyncConfig build() {
124 | return new SyncConfig(this);
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/SyncException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | public class SyncException extends RuntimeException {
20 |
21 | public SyncException(String message) {
22 | super(message);
23 | }
24 |
25 | public SyncException(String message, Throwable cause) {
26 | super(message, cause);
27 | }
28 |
29 | public SyncException(Throwable cause) {
30 | super(cause);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/SyncResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | public final class SyncResult {
20 | private final String spaceId;
21 |
22 | private final Throwable error;
23 |
24 | SyncResult(String spaceId, Throwable error) {
25 | this.spaceId = spaceId;
26 | this.error = error;
27 | }
28 |
29 | public String spaceId() {
30 | return spaceId;
31 | }
32 |
33 | public boolean isSuccessful() {
34 | return error == null;
35 | }
36 |
37 | public Throwable error() {
38 | return error;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/VaultDatabaseExporter.java:
--------------------------------------------------------------------------------
1 | package com.contentful.vault;
2 |
3 |
4 | import android.content.Context;
5 | import android.database.sqlite.SQLiteDatabase;
6 |
7 | import org.apache.commons.io.FileUtils;
8 |
9 | import java.io.File;
10 | import java.io.IOException;
11 | import java.util.concurrent.CountDownLatch;
12 | import java.util.concurrent.Executor;
13 |
14 | import static java.lang.String.format;
15 | import static java.util.Locale.getDefault;
16 |
17 | /**
18 | * This exporter takes a given space and syncs it's Contentful resources to a sqlite database.
19 | */
20 | public class VaultDatabaseExporter {
21 | boolean successful;
22 |
23 | /**
24 | * Use this method to export Contentful spaces into sqlite3 databases which can be imported later.
25 | *
26 | * @param context Android (Robolectric?) Context for creating the sqlite database.
27 | * @param spaceClass Configured {@link Space} containing the name and the id of the space.
28 | * @param accessToken a CDA access token, used for retrieving the resources.
29 | * @return true in case of success. On error, please read System.err output.
30 | */
31 | public boolean export(Context context, Class> spaceClass, String accessToken, String environment) {
32 | successful = false;
33 | final SpaceHelper helper = crateSpaceHelper(spaceClass);
34 | final String outputPath = createOutputPath(helper);
35 |
36 | final CountDownLatch countDownLatch = new CountDownLatch(1);
37 |
38 | final Vault vault = Vault.with(context, spaceClass);
39 | vault.requestSync(
40 | SyncConfig
41 | .builder()
42 | .setSpaceId(helper.getSpaceId())
43 | .setAccessToken(accessToken)
44 | .setEnvironment(environment)
45 | .build(),
46 | new SyncCallback() {
47 | @Override public void onResult(SyncResult result) {
48 | try {
49 | successful = saveResultInDatabaseFile(result, vault, outputPath);
50 | } catch (Throwable t) {
51 | t.printStackTrace(System.err);
52 | } finally {
53 | countDownLatch.countDown();
54 | }
55 | }
56 | }, new Executor() {
57 | @Override public void execute(Runnable runnable) {
58 | runnable.run();
59 | }
60 | });
61 |
62 | try {
63 | countDownLatch.await();
64 | } catch (InterruptedException e) {
65 | e.printStackTrace(System.err);
66 | }
67 |
68 | return successful;
69 | }
70 |
71 | String createOutputPath(SpaceHelper helper) {
72 | String outputPath = "src/main/assets/";
73 | if (helper.getCopyPath() != null) {
74 | outputPath += helper.getCopyPath();
75 | if (!new File(outputPath).exists()) {
76 | final String spaceName = getSpaceClassName(helper);
77 | throw new IllegalStateException("Database file does not exist on the filesystem. " +
78 | "Please remove it's annotation from " + spaceName + " and try again.");
79 | }
80 | } else {
81 | // no database name given, so use a default.
82 | outputPath += "initial_seed.db";
83 | }
84 |
85 | return outputPath;
86 | }
87 |
88 | String getSpaceClassName(SpaceHelper helper) {
89 | return helper.getClass().getCanonicalName().split("\\$")[0];
90 | }
91 |
92 | SpaceHelper crateSpaceHelper(Class> spaceClass) {
93 | final Class> clazz;
94 | try {
95 | clazz = Class.forName(spaceClass.getName() + Constants.SUFFIX_SPACE);
96 | } catch (ClassNotFoundException e) {
97 | throw new IllegalStateException("Could not find class", e);
98 | }
99 |
100 | final SpaceHelper helper;
101 | try {
102 | helper = (SpaceHelper) clazz.newInstance();
103 | } catch (InstantiationException | IllegalAccessException e) {
104 | throw new IllegalStateException("Cannot create a new instance of the space helper.", e);
105 | }
106 |
107 | if (helper == null) {
108 | throw new IllegalStateException("Cannot find SpaceHelper. " +
109 | "Did you use the Vault annotations and rebuild the app?");
110 | }
111 |
112 | return helper;
113 | }
114 |
115 | boolean saveResultInDatabaseFile(SyncResult result, Vault vault, String dataBaseFilePath) {
116 | boolean successful = result.isSuccessful();
117 | if (!successful) {
118 | throw new IllegalStateException("Could not return a valid result.", result.error());
119 | } else {
120 | final File outputDatabase = new File(dataBaseFilePath);
121 |
122 | final SQLiteDatabase readableDatabase = vault.getReadableDatabase();
123 | System.out.println(
124 | format(
125 | getDefault(),
126 | "Copying from '%s' to '%s'.",
127 | readableDatabase.getPath(),
128 | outputDatabase.getAbsolutePath())
129 | );
130 |
131 | try {
132 | FileUtils.copyFile(new File(readableDatabase.getPath()), outputDatabase);
133 | } catch (IOException e) {
134 | e.printStackTrace(System.err);
135 | successful = false;
136 | }
137 |
138 | System.out.println("Copying done.");
139 | }
140 |
141 | return successful;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/core/src/main/java/com/contentful/vault/VaultThreadFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vault;
18 |
19 | import android.os.Process;
20 | import java.util.concurrent.ThreadFactory;
21 |
22 | final class VaultThreadFactory implements ThreadFactory {
23 | @SuppressWarnings("NullableProblems")
24 | @Override
25 | public Thread newThread(Runnable r) {
26 | return new CFThread(r);
27 | }
28 |
29 | private static class CFThread extends Thread {
30 | public CFThread(Runnable target) {
31 | super(target);
32 | }
33 |
34 | @Override public void run() {
35 | Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
36 | super.run();
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/core/src/main/templates/com/contentful/vault/build/GeneratedBuildParameters.java:
--------------------------------------------------------------------------------
1 | package com.contentful.vault.build;
2 |
3 | /**
4 | * Generated class containing the project version.
5 | *
6 | * This is generated on build time, so we don't have to fetch the properties on application
7 | * load.
8 | */
9 | public final class GeneratedBuildParameters {
10 | /**
11 | * Which version of '${project.groupId}' is getting used?
12 | */
13 | public static final String PROJECT_VERSION = "${project.version}";
14 | }
15 |
--------------------------------------------------------------------------------
/core/src/test/resources/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/jitpack.yml:
--------------------------------------------------------------------------------
1 | jdk:
2 | - oraclejdk8
3 |
--------------------------------------------------------------------------------
/last-module/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | vault-parent
5 | com.contentful.vault
6 | 3.2.7-SNAPSHOT
7 |
8 | 4.0.0
9 |
10 | last-module
11 |
--------------------------------------------------------------------------------
/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM http://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/proguard-vault.cfg:
--------------------------------------------------------------------------------
1 | # Vault
2 | -keepattributes Signature
3 | -dontwarn javax.lang.model.type.TypeMirror
4 | -keep class com.contentful.vault.** { *; }
5 | -keep class **$$SpaceHelper { *; }
6 | -keep class **$$ModelHelper { *; }
7 | -keep class **$Fields extends com.contentful.vault.BaseFields { *; }
8 | -keep @com.contentful.vault.ContentType class * { *; }
9 | -keep @com.contentful.vault.Space class * { *; }
10 |
11 | # contentful.java
12 | -keep class com.contentful.java.cda.** { *; }
13 |
14 | # RxJava
15 | -dontwarn rx.**
16 |
17 | # OkHttp
18 | -keepattributes *Annotation*
19 | -keep class com.squareup.okhttp.** { *; }
20 | -keep interface com.squareup.okhttp.** { *; }
21 | -dontwarn com.squareup.okhttp.**
22 |
23 | # Retrofit
24 | -dontwarn retrofit.**
25 | -keep class retrofit.** { *; }
26 | -keepclasseswithmembers class * {
27 | @retrofit.http.* ;
28 | }
29 |
30 | # Okio
31 | -keep class sun.misc.Unsafe { *; }
32 | -dontwarn java.nio.file.*
33 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
34 | -dontwarn okio.**
35 |
36 | # Gson
37 | -keepattributes EnclosingMethod
38 | -keep class com.google.gson.stream.** { *; }
--------------------------------------------------------------------------------
/tests-integration/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | com.contentful.vault
7 | vault-parent
8 | 3.2.7-SNAPSHOT
9 |
10 |
11 | tests-integration
12 | apk
13 |
14 |
15 |
16 | com.contentful.vault
17 | compiler
18 | ${project.version}
19 |
20 |
21 | sun.jdk
22 | tools
23 |
24 |
25 |
26 |
27 |
28 | com.contentful.vault
29 | core
30 | ${project.version}
31 |
32 |
33 |
34 | com.google.android
35 | android
36 | provided
37 |
38 |
39 |
40 | junit
41 | junit
42 | test
43 |
44 |
45 |
46 | org.robolectric
47 | robolectric
48 | test
49 |
50 |
51 |
52 | com.squareup.okhttp3
53 | mockwebserver
54 | test
55 |
56 |
57 |
58 | com.squareup.okhttp3
59 | okhttp-urlconnection
60 | test
61 |
62 |
63 |
64 | commons-io
65 | commons-io
66 | test
67 |
68 |
69 |
70 | org.mockito
71 | mockito-core
72 | test
73 |
74 |
75 |
76 | com.google.truth
77 | truth
78 | test
79 |
80 |
81 |
82 | io.reactivex.rxjava3
83 | rxjava
84 | test
85 |
86 |
87 |
88 |
89 |
90 |
91 | com.simpligility.maven.plugins
92 | android-maven-plugin
93 | true
94 |
95 |
96 |
97 | org.apache.maven.plugins
98 | maven-deploy-plugin
99 |
100 | true
101 |
102 |
103 |
104 |
105 | org.sonatype.plugins
106 | nexus-staging-maven-plugin
107 |
108 | true
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/tests-integration/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/tests-integration/src/main/assets/cfexampleapi.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/contentful/vault/4f6a5ed4f6c592f4ee68a4fac23c876b173b9291/tests-integration/src/main/assets/cfexampleapi.db
--------------------------------------------------------------------------------
/tests-integration/src/test/java/com/contentful/vaultintegration/AllTheThingsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vaultintegration;
18 |
19 | import com.contentful.vault.Asset;
20 | import com.contentful.vault.Vault;
21 | import com.contentful.vaultintegration.lib.allthethings.AllTheThingsResource;
22 | import com.contentful.vaultintegration.lib.allthethings.AllTheThingsSpace;
23 |
24 | import org.junit.Test;
25 | import org.robolectric.RuntimeEnvironment;
26 | import org.robolectric.annotation.Config;
27 |
28 | import static com.contentful.vault.BaseFields.REMOTE_ID;
29 | import static com.google.common.truth.Truth.assertThat;
30 | import static org.junit.Assert.fail;
31 |
32 | @Config(manifest = "src/main/AndroidManifest.xml", sdk = 23)
33 | public class AllTheThingsTest extends BaseTest {
34 | @Override protected void setupVault() {
35 | vault = Vault.with(RuntimeEnvironment.application, AllTheThingsSpace.class);
36 | }
37 |
38 | @Test public void testAllTheThings() throws Exception {
39 | enqueueSync("allthethings");
40 | sync();
41 | checkEntryFoo();
42 | checkEntryBar();
43 | }
44 |
45 | @SuppressWarnings("unchecked")
46 | private void checkEntryBar() {
47 | AllTheThingsResource bar = vault.fetch(AllTheThingsResource.class)
48 | .where(REMOTE_ID + " = ?", "4EYJjgMg0oG084iuACY6Ue")
49 | .first();
50 |
51 | assertThat(bar).isNotNull();
52 | assertThat(bar.text()).isEqualTo("bar");
53 | assertThat(bar.number()).isEqualTo(1);
54 | assertThat(bar.decimal()).isEqualTo(2.0);
55 | assertThat(bar.yesno()).isFalse();
56 | assertThat(bar.dateTime()).isNull();
57 | assertThat(bar.location()).isNull();
58 | assertThat(bar.entry()).isNull();
59 | assertThat(bar.asset()).isNull();
60 | assertThat(bar.object()).isNull();
61 |
62 | assertThat(bar.entries()).isNotNull();
63 | assertThat(bar.entries()).isEmpty();
64 |
65 | assertThat(bar.assets()).isNotNull();
66 | assertThat(bar.assets()).isEmpty();
67 |
68 | assertThat(bar.symbols()).isNotNull();
69 | assertThat(bar.symbols()).isEmpty();
70 | }
71 |
72 | @SuppressWarnings("unchecked")
73 | private void checkEntryFoo() {
74 | AllTheThingsResource foo = vault.fetch(AllTheThingsResource.class)
75 | .where(REMOTE_ID + " = ?", "6K1Md1qADuOsoom2UIEKkq")
76 | .first();
77 |
78 | assertThat(foo).isNotNull();
79 | assertThat(foo.text()).isEqualTo("foo");
80 | assertThat(foo.number()).isEqualTo(31337);
81 | assertThat(foo.decimal()).isEqualTo(1.337);
82 | assertThat(foo.yesno()).isTrue();
83 | assertThat(foo.dateTime()).isEqualTo("2015-07-01");
84 |
85 | assertThat(foo.location()).isNotNull();
86 | assertThat(foo.location().get("lat")).isEqualTo(52.52000659999999);
87 | assertThat(foo.location().get("lon")).isEqualTo(13.404953999999975);
88 |
89 | assertThat(foo.entry()).isNotNull();
90 | assertThat(foo.entry().remoteId()).isEqualTo("4EYJjgMg0oG084iuACY6Ue");
91 |
92 | assertThat(foo.asset()).isNotNull();
93 | assertThat(foo.asset().remoteId()).isEqualTo("6Kknr7SqpGWs8kIKwCuQCU");
94 |
95 | assertThat(foo.object()).isNotNull();
96 | assertThat(foo.object()).hasSize(2);
97 | assertThat(foo.object()).containsEntry("foo", "bar");
98 | assertThat(foo.object()).containsEntry("bar", "foo");
99 |
100 | assertThat(foo.entries()).isNotNull();
101 | assertThat(foo.entries()).hasSize(1);
102 | assertThat(foo.entries().get(0).remoteId()).isEqualTo("4EYJjgMg0oG084iuACY6Ue");
103 |
104 | assertThat(foo.assets()).isNotNull();
105 | assertThat(foo.assets()).hasSize(2);
106 | boolean hasFoo = false, hasBar = false;
107 | for (Asset asset : foo.assets()) {
108 | if ("6Kknr7SqpGWs8kIKwCuQCU".equals(asset.remoteId())) {
109 | hasFoo = true;
110 | } else if ("w4ZPwQ0Cmko2QqyWgSEGy".equals(asset.remoteId())) {
111 | hasBar = true;
112 | } else {
113 | fail();
114 | }
115 | }
116 | assertThat(hasFoo).isTrue();
117 | assertThat(hasBar).isTrue();
118 |
119 | assertThat(foo.symbols()).isNotNull();
120 | assertThat(foo.symbols()).hasSize(2);
121 | assertThat(foo.symbols()).containsExactly("foo", "bar");
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/tests-integration/src/test/java/com/contentful/vaultintegration/ArrayLinks.java:
--------------------------------------------------------------------------------
1 | package com.contentful.vaultintegration;
2 |
3 | import com.contentful.vault.Vault;
4 | import com.contentful.vaultintegration.lib.arraylinks.MultiLinksSpace;
5 | import com.contentful.vaultintegration.lib.arraylinks.Product;
6 | import com.contentful.vaultintegration.lib.arraylinks.Product$Fields;
7 | import com.contentful.vaultintegration.lib.arraylinks.Shop;
8 |
9 | import org.junit.Test;
10 | import org.robolectric.RuntimeEnvironment;
11 |
12 | import java.util.List;
13 |
14 | import static com.google.common.truth.Truth.assertThat;
15 |
16 | public class ArrayLinks extends BaseTest {
17 |
18 | @Override protected void setupVault() {
19 | vault = Vault.with(RuntimeEnvironment.application, MultiLinksSpace.class);
20 | }
21 |
22 | @Test public void testLinks() throws Exception {
23 | // Initial
24 | enqueueSync("arraylinks");
25 | sync();
26 |
27 | // fetch only one
28 | final List all = vault.fetch(Product.class)
29 | .where(Product$Fields.REMOTE_ID + " = ?", "2ZMtY36Lj2M204kesAs4CK")
30 | .all();
31 |
32 | assertThat(all.size()).isEqualTo(1);
33 | final Product product = all.get(0);
34 | assertThat(product.remoteId().equals("2ZMtY36Lj2M204kesAs4CK")).isTrue();
35 |
36 | final Shop shop = product.shops().get(0);
37 | assertThat(shop.name()).isEqualTo("Alexa");
38 | assertThat(shop.products().size()).isEqualTo(6);
39 | assertThat(shop.products().get(3).remoteId()).isEqualTo(product.remoteId());
40 |
41 | assertThat(shop.products().get(2).shops().size()).isEqualTo(2);
42 | assertThat(shop.products().get(2).shops().get(1).name()).isEqualTo("Rewe");
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests-integration/src/test/java/com/contentful/vaultintegration/ArrayTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vaultintegration;
18 |
19 | import com.contentful.vault.Vault;
20 | import com.contentful.vaultintegration.lib.vault.ArraysResource;
21 | import com.contentful.vaultintegration.lib.vault.VaultSpace;
22 | import java.util.Arrays;
23 | import java.util.List;
24 | import org.junit.Test;
25 | import org.robolectric.RuntimeEnvironment;
26 |
27 | import static com.contentful.vault.BaseFields.REMOTE_ID;
28 | import static com.google.common.truth.Truth.assertThat;
29 |
30 | public class ArrayTest extends BaseTest {
31 | @Override protected void setupVault() {
32 | vault = Vault.with(RuntimeEnvironment.application, VaultSpace.class);
33 | }
34 |
35 | @Test public void testArray() throws Exception {
36 | enqueueSync("vault");
37 | sync();
38 |
39 | ArraysResource resource = vault.fetch(ArraysResource.class)
40 | .where(REMOTE_ID + " = ?", "u2L1goyi3eA4W0AKcqEou")
41 | .first();
42 |
43 | assertThat(resource).isNotNull();
44 |
45 | assertThat(resource.assets()).hasSize(2);
46 | List ids = Arrays.asList("1yj8f2uFEgGEkuqeoGIQws", "2cMA1o04G42KGoQioOqqUA");
47 | assertThat(ids).contains(resource.assets().get(0).remoteId());
48 | assertThat(ids).contains(resource.assets().get(1).remoteId());
49 |
50 | assertThat(resource.symbols()).isNotNull();
51 | assertThat(resource.symbols()).containsExactly("a", "b", "c");
52 |
53 | assertThat(resource.blobs()).isNotNull();
54 | assertThat(resource.blobs()).hasSize(1);
55 | assertThat(resource.blobs().get(0)).isNotNull();
56 | }
57 |
58 | @Test public void testEmptyFields() throws Exception {
59 | enqueueSync("vault");
60 | sync();
61 |
62 | ArraysResource resource = vault.fetch(ArraysResource.class)
63 | .where(REMOTE_ID + " = ?", "FyFV7zVpMQUG6IIEekeI0")
64 | .first();
65 |
66 | assertThat(resource).isNotNull();
67 | assertThat(resource.assets()).isNotNull();
68 | assertThat(resource.assets()).isEmpty();
69 |
70 | assertThat(resource.symbols()).isNotNull();
71 | assertThat(resource.symbols()).isEmpty();
72 |
73 | assertThat(resource.blobs()).isNotNull();
74 | assertThat(resource.blobs()).isEmpty();
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/tests-integration/src/test/java/com/contentful/vaultintegration/BaseTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vaultintegration;
18 |
19 | import com.contentful.java.cda.CDAClient;
20 | import com.contentful.vault.SyncCallback;
21 | import com.contentful.vault.SyncConfig;
22 | import com.contentful.vault.SyncResult;
23 | import com.contentful.vault.Vault;
24 |
25 | import org.apache.commons.io.FileUtils;
26 | import org.junit.After;
27 | import org.junit.Before;
28 | import org.junit.runner.RunWith;
29 | import org.robolectric.RobolectricTestRunner;
30 | import org.robolectric.annotation.Config;
31 |
32 | import java.io.File;
33 | import java.io.IOException;
34 | import java.net.URL;
35 | import java.nio.charset.Charset;
36 | import java.util.concurrent.CountDownLatch;
37 | import java.util.concurrent.Executor;
38 | import java.util.logging.LogManager;
39 |
40 | import okhttp3.mockwebserver.MockResponse;
41 | import okhttp3.mockwebserver.MockWebServer;
42 |
43 | import static com.google.common.truth.Truth.assertThat;
44 |
45 | @RunWith(RobolectricTestRunner.class)
46 | @Config(manifest = "src/main/AndroidManifest.xml", sdk = 23)
47 | public abstract class BaseTest {
48 | MockWebServer server;
49 | CDAClient client;
50 | Vault vault;
51 |
52 | @Before public void setUp() throws Exception {
53 | LogManager.getLogManager().reset();
54 | server = new MockWebServer();
55 | server.start();
56 | setupClient();
57 | setupVault();
58 | }
59 |
60 | @After public void tearDown() throws Exception {
61 | server.shutdown();
62 | vault.releaseAll();
63 | }
64 |
65 | protected abstract void setupVault();
66 |
67 | protected void setupClient() {
68 | client = CDAClient.builder()
69 | .setSpace("space")
70 | .setToken("token")
71 | .setEndpoint(getServerUrl())
72 | .build();
73 | }
74 |
75 | protected String getServerUrl() {
76 | return "http://" + server.getHostName() + ":" + server.getPort();
77 | }
78 |
79 | protected void enqueue(String fileName) throws IOException {
80 | URL resource = getClass().getClassLoader().getResource(fileName);
81 | if (resource == null) {
82 | throw new IllegalArgumentException("File not found");
83 | }
84 | server.enqueue(new MockResponse().setResponseCode(200)
85 | .setBody(FileUtils.readFileToString(new File(resource.getFile()),
86 | Charset.defaultCharset())));
87 | }
88 |
89 | protected void enqueueSync(String space) throws IOException {
90 | enqueueSync(space, false);
91 | }
92 |
93 | protected void enqueueSync(String space, boolean update) throws IOException {
94 | enqueue(space + "/locales.json");
95 | enqueue(space + "/types.json");
96 | if (update) {
97 | enqueue(space + "/update.json");
98 | } else {
99 | enqueue(space + "/initial.json");
100 | }
101 | }
102 |
103 | protected void sync() throws InterruptedException {
104 | sync(null);
105 | }
106 |
107 | protected void sync(SyncConfig config) throws InterruptedException {
108 | if (config == null) {
109 | config = SyncConfig.builder().setClient(client).build();
110 | }
111 |
112 | final CountDownLatch latch = new CountDownLatch(1);
113 |
114 | Executor executor = new Executor() {
115 | @Override public void execute(Runnable command) {
116 | command.run();
117 | }
118 | };
119 |
120 | final SyncResult[] result = {null};
121 | SyncCallback callback = new SyncCallback() {
122 | @Override public void onResult(SyncResult r) {
123 | result[0] = r;
124 | latch.countDown();
125 | }
126 | };
127 |
128 | vault.requestSync(config, callback, executor);
129 | latch.await();
130 |
131 | assertThat(result[0]).isNotNull();
132 |
133 | if (!result[0].isSuccessful()) {
134 | throw (RuntimeException) result[0].error();
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/tests-integration/src/test/java/com/contentful/vaultintegration/BlobTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vaultintegration;
18 |
19 | import com.contentful.vault.Vault;
20 | import com.contentful.vaultintegration.lib.vault.BlobResource;
21 | import com.contentful.vaultintegration.lib.vault.VaultSpace;
22 | import java.util.Map;
23 | import org.junit.Test;
24 | import org.robolectric.RuntimeEnvironment;
25 |
26 | import static com.contentful.vault.BaseFields.REMOTE_ID;
27 | import static com.google.common.truth.Truth.assertThat;
28 | import static org.junit.Assert.assertEquals;
29 |
30 | public class BlobTest extends BaseTest {
31 | @Override protected void setupVault() {
32 | vault = Vault.with(RuntimeEnvironment.application, VaultSpace.class);
33 | }
34 |
35 | @SuppressWarnings("unchecked")
36 | @Test public void testBlob() throws Exception {
37 | enqueueSync("vault");
38 | sync();
39 |
40 | BlobResource blobResource = vault.fetch(BlobResource.class)
41 | .where(REMOTE_ID + " = ?", "6tOdhkd6Ewekq8M6MQe4GY")
42 | .first();
43 |
44 | assertThat(blobResource).isNotNull();
45 | assertThat(blobResource.object()).isNotNull();
46 | assertThat(blobResource.object()).containsEntry("fieldString", "hello");
47 | assertThat(blobResource.object()).containsEntry("fieldInteger", 31337.0);
48 | assertThat(blobResource.object()).containsEntry("fieldFloat", 3.1337);
49 | assertThat(blobResource.object()).containsEntry("fieldBoolean", true);
50 |
51 | Object fieldMap = blobResource.object().get("fieldMap");
52 | assertThat(fieldMap).isNotNull();
53 | assertThat(fieldMap).isInstanceOf(Map.class);
54 | assertEquals("value", ((Map) fieldMap).get("key"));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests-integration/src/test/java/com/contentful/vaultintegration/DatabaseCopyTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vaultintegration;
18 |
19 | import com.contentful.vault.Asset;
20 | import com.contentful.vault.ContentType;
21 | import com.contentful.vault.Field;
22 | import com.contentful.vault.Resource;
23 | import com.contentful.vault.Space;
24 | import com.contentful.vault.Vault;
25 | import com.contentful.vault.VaultDatabaseExporter;
26 |
27 | import org.junit.Ignore;
28 | import org.junit.Test;
29 | import org.junit.runner.RunWith;
30 | import org.robolectric.RobolectricTestRunner;
31 | import org.robolectric.RuntimeEnvironment;
32 | import org.robolectric.annotation.Config;
33 |
34 | import java.util.List;
35 |
36 | import static com.google.common.truth.Truth.assertThat;
37 | import static org.junit.Assert.assertTrue;
38 |
39 | @RunWith(RobolectricTestRunner.class)
40 | @Config(manifest = "src/main/AndroidManifest.xml")
41 | public class DatabaseCopyTest extends BaseTest {
42 | @Space(
43 | value = "cfexampleapi",
44 | models = Cat.class,
45 | locales = {"en-US", "tlh"},
46 | copyPath = "cfexampleapi.db"
47 | ) interface Sp {
48 | String TOKEN = "b4c0n73n7fu1";
49 | String ENVIRONMENT = "environment";
50 | }
51 |
52 | @ContentType("cat")
53 | static class Cat extends Resource {
54 | @Field String name;
55 | @Field Cat bestFriend;
56 | @Field Asset image;
57 | }
58 |
59 | @Override protected void setupVault() {
60 | vault = Vault.with(RuntimeEnvironment.application, Sp.class);
61 | }
62 |
63 | @Test public void testDatabaseCopy() throws Exception {
64 | List cats = vault.fetch(Cat.class).all();
65 | assertThat(cats).hasSize(3);
66 | }
67 |
68 | @Ignore("Do not update db on ci.")
69 | @Test
70 | public void testSyncDBtoSqlite() throws Exception {
71 | assertTrue(
72 | new VaultDatabaseExporter()
73 | .export(
74 | RuntimeEnvironment.application,
75 | Sp.class,
76 | Sp.TOKEN,
77 | Sp.ENVIRONMENT)
78 | );
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/tests-integration/src/test/java/com/contentful/vaultintegration/LinksTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vaultintegration;
18 |
19 | import com.contentful.vault.Vault;
20 | import com.contentful.vaultintegration.lib.links.AssetsContainer;
21 | import com.contentful.vaultintegration.lib.links.LinksSpace;
22 | import java.util.Arrays;
23 | import java.util.List;
24 | import org.junit.Test;
25 | import org.robolectric.RuntimeEnvironment;
26 |
27 | import static com.contentful.vault.BaseFields.REMOTE_ID;
28 | import static com.google.common.truth.Truth.assertThat;
29 |
30 | public class LinksTest extends BaseTest {
31 | @Override protected void setupVault() {
32 | vault = Vault.with(RuntimeEnvironment.application, LinksSpace.class);
33 | }
34 |
35 | @Test public void testLinks() throws Exception {
36 | final String CONTAINER_ID = "34ljO1zKukgIYmcQ64IgOo";
37 |
38 | // Initial
39 | enqueueSync("links");
40 | sync();
41 |
42 | AssetsContainer container = vault.fetch(AssetsContainer.class)
43 | .where(REMOTE_ID + " = ?", CONTAINER_ID)
44 | .first();
45 |
46 | assertThat(container).isNotNull();
47 | assertThat(container.assets()).isNotNull();
48 | assertThat(container.assets()).hasSize(1);
49 | assertThat(container.assets().get(0).remoteId()).isEqualTo("4eHZNAfWq4UaiYIywMiSAy");
50 |
51 | // Update
52 | enqueueSync("links", true);
53 | sync();
54 |
55 | container = vault.fetch(AssetsContainer.class)
56 | .where(REMOTE_ID + " = ?", CONTAINER_ID)
57 | .first();
58 |
59 | assertThat(container).isNotNull();
60 | assertThat(container.assets()).isNotNull();
61 | assertThat(container.assets()).hasSize(2);
62 | List ids = Arrays.asList("2lD1fm3UBiwYk0m6CgmiQQ", "65ou5OAxawuQIkOAe2e42c");
63 | assertThat(ids).contains(container.assets().get(0).remoteId());
64 | assertThat(ids).contains(container.assets().get(1).remoteId());
65 | }
66 |
67 | @Test public void testLinkArrayOrder() throws Exception {
68 | final String CONTAINER_ID = "ordered";
69 |
70 | // Initial
71 | enqueueSync("links");
72 | sync();
73 |
74 | AssetsContainer container = vault.fetch(AssetsContainer.class)
75 | .where(REMOTE_ID + " = ?", CONTAINER_ID)
76 | .first();
77 |
78 | assertThat(container).isNotNull();
79 | assertThat(container.assets()).hasSize(4);
80 | assertThat(container.assets().get(0).remoteId()).isEqualTo("4eHZNAfWq4UaiYIywMiSAy");
81 | assertThat(container.assets().get(1).remoteId()).isEqualTo("1g07qGA9BMkucwiUysi8qQ");
82 | assertThat(container.assets().get(2).remoteId()).isEqualTo("2lD1fm3UBiwYk0m6CgmiQQ");
83 | assertThat(container.assets().get(3).remoteId()).isEqualTo("65ou5OAxawuQIkOAe2e42c");
84 | }
85 |
86 | @Test public void testLinkArrayDuplicates() throws Exception {
87 | final String CONTAINER_ID = "duplicates";
88 |
89 | // Initial
90 | enqueueSync("links");
91 | sync();
92 |
93 | AssetsContainer container = vault.fetch(AssetsContainer.class)
94 | .where(REMOTE_ID + " = ?", CONTAINER_ID)
95 | .first();
96 |
97 | assertThat(container).isNotNull();
98 | assertThat(container.assets()).hasSize(3);
99 |
100 | String id = "4eHZNAfWq4UaiYIywMiSAy";
101 | assertThat(container.assets().get(0).remoteId()).isEqualTo(id);
102 | assertThat(container.assets().get(1).remoteId()).isEqualTo(id);
103 | assertThat(container.assets().get(2).remoteId()).isEqualTo(id);
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/tests-integration/src/test/java/com/contentful/vaultintegration/LocaleTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vaultintegration;
18 |
19 | import com.contentful.vault.Vault;
20 | import com.contentful.vaultintegration.lib.demo.Cat;
21 | import com.contentful.vaultintegration.lib.demo.DemoSpace;
22 | import org.junit.Test;
23 | import org.robolectric.RuntimeEnvironment;
24 |
25 | import static com.contentful.vault.BaseFields.REMOTE_ID;
26 | import static com.google.common.truth.Truth.assertThat;
27 |
28 | public class LocaleTest extends BaseTest {
29 | @Override protected void setupVault() {
30 | vault = Vault.with(RuntimeEnvironment.application, DemoSpace.class);
31 | }
32 |
33 | @Test public void testLocale() throws Exception {
34 | enqueueSync("demo");
35 | sync();
36 | checkDefaultLocale();
37 | checkCustomLocale();
38 | }
39 |
40 | private void checkCustomLocale() {
41 | // Klingon
42 | Cat cat = vault.fetch(Cat.class)
43 | .where(REMOTE_ID + " = ?", "happycat")
44 | .first("tlh");
45 |
46 | assertThat(cat).isNotNull();
47 | assertThat(cat.name()).isEqualTo("Quch vIghro'");
48 | }
49 |
50 | private void checkDefaultLocale() throws Exception {
51 | // Default locale
52 | enqueueSync("demo");
53 | sync();
54 |
55 | Cat cat = vault.fetch(Cat.class)
56 | .where(REMOTE_ID + " = ?", "happycat")
57 | .first();
58 |
59 | assertThat(cat).isNotNull();
60 | assertThat(cat.name()).isEqualTo("Happy Cat");
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/tests-integration/src/test/java/com/contentful/vaultintegration/LocalizedLinksTest.java:
--------------------------------------------------------------------------------
1 | package com.contentful.vaultintegration;
2 |
3 | import com.contentful.vault.Vault;
4 | import com.contentful.vaultintegration.lib.localizedlinks.Container;
5 | import com.contentful.vaultintegration.lib.localizedlinks.LocalizedLinksSpace;
6 | import org.junit.Test;
7 | import org.robolectric.RuntimeEnvironment;
8 |
9 | import static com.google.common.truth.Truth.assertThat;
10 |
11 | public final class LocalizedLinksTest extends BaseTest {
12 | @Override protected void setupVault() {
13 | vault = Vault.with(RuntimeEnvironment.application, LocalizedLinksSpace.class);
14 | }
15 |
16 | @Test public void localizedLink() throws Exception {
17 | enqueueSync("localizedlinks");
18 | sync();
19 |
20 | final Container english = vault.fetch(Container.class).first();
21 | final Container hebrew = vault.fetch(Container.class).first("he-IL");
22 |
23 | assertThat(english.one().title()).isEqualTo("hello");
24 | assertThat(hebrew.one().title()).isEqualTo("shalom");
25 | }
26 |
27 | @Test public void testNonLocalizedArray() throws Exception {
28 | enqueueSync("localizedlinks");
29 | sync();
30 |
31 | final Container english = vault.fetch(Container.class).first();
32 | final Container hebrew = vault.fetch(Container.class).first("he-IL");
33 |
34 | assertThat(english.assets()).hasSize(2);
35 | assertThat(hebrew.assets()).hasSize(2);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests-integration/src/test/java/com/contentful/vaultintegration/ObserveTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vaultintegration;
18 |
19 | import com.contentful.vault.BaseFields;
20 | import com.contentful.vault.SyncResult;
21 | import com.contentful.vault.Vault;
22 | import com.contentful.vaultintegration.lib.demo.Cat;
23 | import com.contentful.vaultintegration.lib.demo.Cat$Fields;
24 | import com.contentful.vaultintegration.lib.demo.DemoSpace;
25 | import java.util.List;
26 |
27 | import io.reactivex.rxjava3.subscribers.TestSubscriber;
28 | import org.junit.Test;
29 | import org.robolectric.RuntimeEnvironment;
30 |
31 |
32 | import static com.google.common.truth.Truth.assertThat;
33 |
34 | public class ObserveTest extends BaseTest {
35 | @Override protected void setupVault() {
36 | vault = Vault.with(RuntimeEnvironment.application, DemoSpace.class);
37 | }
38 |
39 | @Test public void observeQuery() throws Exception {
40 | enqueue("demo/locales.json");
41 | enqueue("demo/types.json");
42 | enqueue("demo/initial.json");
43 | sync();
44 |
45 | TestSubscriber subscriber = new TestSubscriber<>();
46 | vault.observe(Cat.class)
47 | .where(BaseFields.REMOTE_ID + " IN(?, ?, ?)", "happycat", "nyancat", "garfield")
48 | .limit(2)
49 | .order(Cat$Fields.UPDATED_AT + " DESC")
50 | .all()
51 | .subscribe(subscriber);
52 |
53 | subscriber.assertNoErrors();
54 | subscriber.assertComplete();
55 |
56 | List cats = subscriber.values();
57 | assertThat(cats).hasSize(2);
58 | assertThat(cats.get(0).updatedAt()).isEqualTo("2013-11-18T15:58:02.018Z");
59 | assertThat(cats.get(1).updatedAt()).isEqualTo("2013-09-04T09:19:39.027Z");
60 | }
61 |
62 | @Test public void observeSyncResults() throws Exception {
63 | enqueue("demo/locales.json");
64 | enqueue("demo/types.json");
65 | enqueue("demo/initial.json");
66 |
67 | TestSubscriber subscriber = new TestSubscriber<>();
68 | Vault.observeSyncResults().subscribe(subscriber);
69 |
70 | subscriber.assertNoValues();
71 | sync();
72 | subscriber.assertNoErrors();
73 |
74 | List events = subscriber.values();
75 | assertThat(events).hasSize(1);
76 | assertThat(events.get(0).isSuccessful()).isTrue();
77 | assertThat(events.get(0).spaceId()).isEqualTo("cfexampleapi");
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/tests-integration/src/test/java/com/contentful/vaultintegration/ParcelableTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2018 Contentful GmbH
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.contentful.vaultintegration;
18 |
19 | import android.os.Parcel;
20 | import com.contentful.vault.Asset;
21 | import com.contentful.vault.Vault;
22 | import com.contentful.vaultintegration.lib.demo.DemoSpace;
23 | import java.util.List;
24 | import org.junit.Test;
25 | import org.robolectric.RuntimeEnvironment;
26 |
27 | import static com.google.common.truth.Truth.assertThat;
28 |
29 | public class ParcelableTest extends BaseTest {
30 | @Override protected void setupVault() {
31 | vault = Vault.with(RuntimeEnvironment.application, DemoSpace.class);
32 | }
33 |
34 | @Test public void asset() throws Exception {
35 | enqueue("demo/locales.json");
36 | enqueue("demo/types.json");
37 | enqueue("demo/initial.json");
38 | sync();
39 |
40 | List assets = vault.fetch(Asset.class).all();
41 | assertThat(assets).isNotEmpty();
42 |
43 | for (Asset asset : assets) {
44 | checkParcelable(asset);
45 | }
46 | }
47 |
48 | @SuppressWarnings("unchecked")
49 | private void checkParcelable(Asset source) {
50 | Parcel parcel = Parcel.obtain();
51 | source.writeToParcel(parcel, 0);
52 | parcel.setDataPosition(0);
53 | Asset reconstructed = Asset.CREATOR.createFromParcel(parcel);
54 | assertThat(reconstructed).isNotNull();
55 | assertThat(source.url()).isEqualTo(reconstructed.url());
56 | assertThat(source.mimeType()).isEqualTo(reconstructed.mimeType());
57 | assertThat(source.title()).isEqualTo(reconstructed.title());
58 | assertThat(source.description()).isEqualTo(reconstructed.description());
59 |
60 | assertThat((Iterable) source.file().keySet())
61 | .containsAllIn(reconstructed.file().keySet());
62 |
63 | assertThat((Iterable) source.file().keySet()).hasSize(reconstructed.file().keySet().size());
64 |
65 | assertThat((Iterable