Merge branch 'master' of github.com:SpringSource/spring-gemfire
Conflicts: samples/hello-world/gradle.properties
This commit is contained in:
@@ -58,8 +58,9 @@ dependencies {
|
||||
}
|
||||
~~~~~
|
||||
|
||||
Latest GA release is _1.1.0.RELEASE_
|
||||
Latest nightly build is _1.1.1.BUILD-SNAPSHOT_
|
||||
Latest GA release is _1.1.1.RELEASE_
|
||||
Latest milestone release is _1.2.0.M1_
|
||||
Latest nightly build is _1.2.0.BUILD-SNAPSHOT_
|
||||
|
||||
|
||||
* Configure a GemFire cache and Region (replicated, partitioned, client and so on):
|
||||
|
||||
@@ -48,6 +48,7 @@ allprojects {
|
||||
mavenRepo name: "sonatype-snapshot", urls: "http://oss.sonatype.org/content/repositories/snapshots"
|
||||
mavenRepo name: "ext-snapshots", urls: "http://springframework.svn.sourceforge.net/svnroot/springframework/repos/repo-ext/"
|
||||
mavenRepo name: "gemstone-com-release", urls: "http://dist.gemstone.com/maven/release"
|
||||
//mavenRepo name: "gemstone-com-release", urls: "http://repo.springsource.org/gemstone-release"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -87,10 +88,15 @@ dependencies {
|
||||
compile("com.gemstone.gemfire:gemfire:$gemfireVersion")
|
||||
|
||||
// Testing
|
||||
testCompile "junit:junit:$junitVersion"
|
||||
testCompile "junit:junit-dep:$junitVersion"
|
||||
testCompile "org.mockito:mockito-core:$mockitoVersion"
|
||||
testCompile "org.hamcrest:hamcrest-core:$hamcrestVersion"
|
||||
testCompile "org.hamcrest:hamcrest-library:$hamcrestVersion"
|
||||
testCompile "org.springframework:spring-test:$springVersion"
|
||||
testCompile("javax.annotation:jsr250-api:1.0") { optional = true }
|
||||
|
||||
// Spring Data
|
||||
compile "org.springframework.data:spring-data-commons-core:${springDataCommonsVersion}"
|
||||
}
|
||||
|
||||
javaprojects = rootProject
|
||||
|
||||
@@ -2,11 +2,29 @@ SPRING DATA GEMFIRE CHANGELOG
|
||||
=============================
|
||||
http://www.springsource.org/spring-gemfire
|
||||
|
||||
Changes in version 1.1.0.RELEASE (2011-12-14)
|
||||
Changes in version 1.2.0.M1 (2012-03-20)
|
||||
----------------------------------------
|
||||
|
||||
General
|
||||
* Introduced support for annotation-based entity mapping (@Id, @PersistenceConstructor, @Id)
|
||||
* Introduced support for Spring Data Repositories (query exception & derivation)
|
||||
|
||||
|
||||
Changes in version 1.1.1.RELEASE (2012-03-20)
|
||||
---------------------------------------------
|
||||
|
||||
General
|
||||
* Upgraded to GemFire 6.6.2
|
||||
* Upgraded to Spring Framework 3.1.1 GA
|
||||
|
||||
Package org.springframework.data.gemfire
|
||||
* Fixed incorrect parsing of pdx-serializer (from value to reference)
|
||||
* Fixed incorrect parsing of use-bean-factory-locator
|
||||
* Fixed GemfireTransactionCommitException class hierarchy
|
||||
* Improved handling of GemFire 6.5+ transaction exceptions
|
||||
|
||||
Package org.springframework.data.gemfire.client
|
||||
* Fixed bug that caused client namespace to create only local regions
|
||||
|
||||
|
||||
Changes in version 1.1.0.RELEASE (2011-12-14)
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
<surname>Leau</surname>
|
||||
<affiliation>SpringSource, a division of VMware</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Oliver</firstname>
|
||||
<surname>Gierke</surname>
|
||||
<affiliation>SpringSource, a division of VMware</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
|
||||
@@ -41,6 +46,11 @@
|
||||
<xi:include href="reference/bootstrap.xml"/>
|
||||
<xi:include href="reference/data.xml"/>
|
||||
<xi:include href="reference/serialization.xml"/>
|
||||
<xi:include href="reference/mapping.xml"/>
|
||||
<xi:include href="https://github.com/SpringSource/spring-data-commons/raw/master/src/docbkx/repositories.xml">
|
||||
<xi:fallback href="../../../../../../spring-data-commons/src/docbkx/repositories.xml" />
|
||||
</xi:include>
|
||||
<xi:include href="reference/repositories.xml"/>
|
||||
<xi:include href="reference/samples.xml"/>
|
||||
</part>
|
||||
|
||||
|
||||
84
docs/src/reference/docbook/reference/mapping.xml
Normal file
84
docs/src/reference/docbook/reference/mapping.xml
Normal file
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter version="5.0" xml:id="mapping" xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:ns5="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ns4="http://www.w3.org/2000/svg"
|
||||
xmlns:ns3="http://www.w3.org/1998/Math/MathML"
|
||||
xmlns:ns="http://docbook.org/ns/docbook">
|
||||
<title>POJO mapping</title>
|
||||
|
||||
<section xml:id="mapping.entities">
|
||||
<title>Entity mapping</title>
|
||||
|
||||
<para>Spring Data Gemfire provides support to map entities to be stored in
|
||||
a Gemfire grid. The mapping metadata is define by using annotations at the
|
||||
domain classes just like this: </para>
|
||||
|
||||
<example>
|
||||
<title>Mapping a domain class to Gemfire</title>
|
||||
|
||||
<programlisting language="java">@Region("myRegion")
|
||||
public class Person {
|
||||
|
||||
@Id Long id;
|
||||
String firstname;
|
||||
String lastname;
|
||||
|
||||
@PersistenceConstructor
|
||||
public Person(String firstname, String lastname) {
|
||||
// …
|
||||
}
|
||||
|
||||
…
|
||||
} </programlisting>
|
||||
</example>
|
||||
|
||||
<para>The first thing you see here is the
|
||||
<interfacename>@Region</interfacename> annotation that can be used to
|
||||
customize the region instances of the <classname>Person</classname> class
|
||||
are stored in. The <interfacename>@Id</interfacename> annotation can be
|
||||
used to annotate the property that shall be used as cache key. The
|
||||
<interfacename>@PersistenceConstructor</interfacename> annotation actually
|
||||
helps disambiguing multiple potentially available constructors taking
|
||||
parameters and explicitly marking the one annotated as the one to be used
|
||||
to create entities. With none or only a single constructor you can omit
|
||||
the annotation.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="mapping.pdx-serializer">
|
||||
<title>Mapping PDX serializer</title>
|
||||
|
||||
<para>Spring Data Gemfire provides a custom
|
||||
<interfacename>PDXSerializer</interfacename> implementation that uses the
|
||||
mapping information to customize entity serialization. Beyond that it
|
||||
allows customizing the entity instantiation by using the Spring Data
|
||||
<interfacename>EntityInstantiator</interfacename> abstraction. By default
|
||||
the serializer uses a <classname>ReflectionEntityInstantiator</classname>
|
||||
that will use the persistence constructor of the mapped entity (either the
|
||||
single declared one or explicitly annoted with
|
||||
<interfacename>@PersistenceConstructor</interfacename>). To provide values
|
||||
for constructor parameters it will read fields with name of the
|
||||
constructor parameters from the <interfacename>PDXReader</interfacename>
|
||||
supplied.</para>
|
||||
|
||||
<example>
|
||||
<title>Using @Value on entity constructor parameters</title>
|
||||
|
||||
<programlisting language="java">public class Person {
|
||||
|
||||
public Person(@Value("#root.foo") String firstname, @Value("bean") String lastname) {
|
||||
// …
|
||||
}
|
||||
|
||||
…
|
||||
} </programlisting>
|
||||
</example>
|
||||
|
||||
<para>The entity annotated as such will get the field <code>foo</code>
|
||||
read from the <interfacename>PDXReader</interfacename> and handed as
|
||||
constructor parameter value for <code>firstname</code>. The value for
|
||||
<code>lastname</code> will be the Spring bean with name
|
||||
<code>bean</code>.</para>
|
||||
</section>
|
||||
</chapter>
|
||||
218
docs/src/reference/docbook/reference/repositories.xml
Normal file
218
docs/src/reference/docbook/reference/repositories.xml
Normal file
@@ -0,0 +1,218 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter version="5.0" xml:id="gemfire-repositories"
|
||||
xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xmlns:ns5="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ns4="http://www.w3.org/2000/svg"
|
||||
xmlns:ns3="http://www.w3.org/1998/Math/MathML"
|
||||
xmlns:ns="http://docbook.org/ns/docbook">
|
||||
<title>Gemfire Repositories</title>
|
||||
|
||||
<section>
|
||||
<title xml:id="gemfire-repositories.intro">Introduction</title>
|
||||
|
||||
<para>Spring Data Gemfire provides support to use the Spring Data
|
||||
repository abstraction to easily persist entities into Gemfire and execute
|
||||
queries. A general introduction into the repository programmin model has
|
||||
been provided in <xref linkend="repositories" />.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="gemfire-repositories.spring-configuration">
|
||||
<title>Spring configuration</title>
|
||||
|
||||
<para>To bootstrap Spring Data repositories you use the
|
||||
<code><repositories /></code> element from the Gemfire
|
||||
namespace:</para>
|
||||
|
||||
<example>
|
||||
<title>Bootstrap Gemfire repositories</title>
|
||||
|
||||
<programlisting language="xml"><beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:gf="http://www.springframework.org/schema/gemfire"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/gemfire
|
||||
http://www.springframework.org/schema/gemfire/spring-gemfire.xsd>
|
||||
|
||||
<gf:repositories base-package="com.acme.repository" />
|
||||
|
||||
</beans></programlisting>
|
||||
</example>
|
||||
|
||||
<para>This configuration snippet will look for interfaces below the
|
||||
configured base package and create repository instances for those
|
||||
interfaces backed by a <classname>SimpleGemfireRepository</classname>.
|
||||
Note that you have to have your domain classes correctly mapped to
|
||||
configured regions as the bottstrap process will fail otherwise.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="gemfire-repositories.executing-queries">
|
||||
<title>Executing OQL queries</title>
|
||||
|
||||
<para>The Gemfire repositories allow the definition of query methods to
|
||||
easily execute OQL queries against the Region the managed entity is mapped
|
||||
to.</para>
|
||||
|
||||
<example>
|
||||
<title>Sample repository</title>
|
||||
|
||||
<programlisting language="java">@Region("myRegion")
|
||||
public class Person { … }</programlisting>
|
||||
|
||||
<programlisting language="java">public interface PersonRepository extends CrudRepository<Person, Long> {
|
||||
|
||||
Person findByEmailAddress(String emailAddress);
|
||||
|
||||
Collection<Person> findByFirstname(String firstname);
|
||||
|
||||
@Query("SELECT * FROM /Person p WHERE p.firstname = $1")
|
||||
Collection<Person> findByFirstnameAnnotated(String firstname);
|
||||
|
||||
@Query("SELECT * FROM /Person p WHERE p.firstname IN SET $1")
|
||||
Collection<Person> findByFirstnamesAnnotated(Collection<String> firstnames);
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<para>The first method listed here will cause the following query to be
|
||||
derived: <code>SELECT x FROM /myRegion x WHERE x.emailAddress = $1</code>.
|
||||
The second method works the same way except it's returning all entities
|
||||
found whereas the first one expects a single result value. In case the
|
||||
supported keywords are not sufficient to declare your query or the method
|
||||
name gets to verbose you can annotate the query methods with
|
||||
<interfacename>@Query</interfacename> as seen for methods 3 and 4.</para>
|
||||
|
||||
<para><table>
|
||||
<title>Supported keywords for query methods</title>
|
||||
|
||||
<tgroup cols="3">
|
||||
<colspec colwidth="1*" />
|
||||
|
||||
<colspec colwidth="2*" />
|
||||
|
||||
<colspec colwidth="2*" />
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Keyword</entry>
|
||||
|
||||
<entry>Sample</entry>
|
||||
|
||||
<entry>Logical result</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><literal>GreaterThan</literal></entry>
|
||||
|
||||
<entry><methodname>findByAgeGreaterThan(int
|
||||
age)</methodname></entry>
|
||||
|
||||
<entry><code>x.age > $1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>GreaterThanEqual</literal></entry>
|
||||
|
||||
<entry><methodname>findByAgeGreaterThanEqual(int
|
||||
age)</methodname></entry>
|
||||
|
||||
<entry><code>x.age >= $1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>LessThan</literal></entry>
|
||||
|
||||
<entry><methodname>findByAgeLessThan(int
|
||||
age)</methodname></entry>
|
||||
|
||||
<entry><code>x.age < $1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>LessThanEqual</literal></entry>
|
||||
|
||||
<entry><methodname>findByAgeLessThanEqual(int
|
||||
age)</methodname></entry>
|
||||
|
||||
<entry><code>x.age <= $1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>IsNotNull</literal>,
|
||||
<literal>NotNull</literal></entry>
|
||||
|
||||
<entry><methodname>findByFirstnameNotNull()</methodname></entry>
|
||||
|
||||
<entry><code>x.firstname =! NULL</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>IsNull</literal>,
|
||||
<literal>Null</literal></entry>
|
||||
|
||||
<entry><methodname>findByFirstnameNull()</methodname></entry>
|
||||
|
||||
<entry><code>x.firstname = NULL</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>In</literal></entry>
|
||||
|
||||
<entry><methodname>findByFirstnameIn(Collection<String>
|
||||
x)</methodname></entry>
|
||||
|
||||
<entry><code>x.firstname IN SET $1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>NotIn</literal></entry>
|
||||
|
||||
<entry><methodname>findByFirstnameNotIn(Collection<String>
|
||||
x)</methodname></entry>
|
||||
|
||||
<entry><code>x.firstname NOT IN SET $1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>(No keyword)</entry>
|
||||
|
||||
<entry><methodname>findByFirstname(String
|
||||
name)</methodname></entry>
|
||||
|
||||
<entry><code>x.firstname = $1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>Not</literal></entry>
|
||||
|
||||
<entry><methodname>findByFirstnameNot(String
|
||||
name)</methodname></entry>
|
||||
|
||||
<entry><code>x.firstname != $1</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>IsTrue</literal>,
|
||||
<literal>True</literal></entry>
|
||||
|
||||
<entry><code>findByActiveIsTrue()</code></entry>
|
||||
|
||||
<entry><code>x.active = true</code></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><literal>IsFalse</literal>,
|
||||
<literal>False</literal></entry>
|
||||
|
||||
<entry><code>findByActiveIsFalse()</code></entry>
|
||||
|
||||
<entry><code>x.active = false</code></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table></para>
|
||||
</section>
|
||||
</chapter>
|
||||
@@ -5,20 +5,22 @@ log4jVersion = 1.2.16
|
||||
slf4jVersion = 1.6.4
|
||||
|
||||
# Common libraries
|
||||
springVersion = 3.1.0.RELEASE
|
||||
gemfireVersion = 6.6.1
|
||||
springVersion = 3.1.1.RELEASE
|
||||
springDataCommonsVersion = 1.3.0.BUILD-SNAPSHOT
|
||||
gemfireVersion = 6.6.2
|
||||
|
||||
# Testing
|
||||
junitVersion = 4.8.1
|
||||
mockitoVersion = 1.8.5
|
||||
hamcrestVersion = 1.2.1
|
||||
|
||||
# Manifest properties
|
||||
|
||||
## OSGi ranges
|
||||
spring.range = "[3.1.0, 4.0.0)"
|
||||
spring.range = "[3.0.0, 4.0.0)"
|
||||
gemfire.range = "[6.5, 7.0)"
|
||||
|
||||
# --------------------
|
||||
# Project wide version
|
||||
# --------------------
|
||||
springGemfireVersion=1.1.1.BUILD-SNAPSHOT
|
||||
springGemfireVersion=1.1.1.BUILD-SNAPSHOT
|
||||
|
||||
20
maven.gradle
20
maven.gradle
@@ -105,6 +105,14 @@ def customizePom(pom) {
|
||||
}
|
||||
|
||||
pom.project {
|
||||
name = project.description
|
||||
description = project.description
|
||||
url = 'http://github.com/SpringSource/spring-gemfire'
|
||||
organization {
|
||||
name = 'SpringSource'
|
||||
url = 'http://www.springsource.org/spring-gemfire'
|
||||
}
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name 'The Apache Software License, Version 2.0'
|
||||
@@ -112,6 +120,18 @@ def customizePom(pom) {
|
||||
distribution 'repo'
|
||||
}
|
||||
}
|
||||
scm {
|
||||
url = 'http://github.com/SpringSource/spring-gemfire'
|
||||
connection = 'scm:git:git://github.com/SpringSource/spring-gemfire'
|
||||
developerConnection = 'scm:git:git://github.com/SpringSource/spring-gemfire'
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id = 'costin'
|
||||
name = 'Costin Leau'
|
||||
email = 'cleau@vmware.com'
|
||||
}
|
||||
}
|
||||
|
||||
// similar to Spring's configuration
|
||||
dependencies {
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
junitVersion = 4.8.1
|
||||
springVersion = 3.1.0.RELEASE
|
||||
version = 1.1.1.BUILD-SNAPSHOT
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import com.gemstone.gemfire.cache.TransactionException;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
|
||||
/**
|
||||
* Gemfire-specific subclass of {@link org.springframework.transaction.TransactionException}, indicating a transaction failure at commit time.
|
||||
@@ -25,10 +25,6 @@ import com.gemstone.gemfire.cache.TransactionException;
|
||||
*/
|
||||
public class GemfireTransactionCommitException extends TransactionException {
|
||||
|
||||
public GemfireTransactionCommitException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public GemfireTransactionCommitException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
@@ -36,8 +32,4 @@ public class GemfireTransactionCommitException extends TransactionException {
|
||||
public GemfireTransactionCommitException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public GemfireTransactionCommitException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import org.springframework.util.Assert;
|
||||
|
||||
import com.gemstone.gemfire.cache.Cache;
|
||||
import com.gemstone.gemfire.cache.CacheTransactionManager;
|
||||
import com.gemstone.gemfire.cache.CommitConflictException;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
@@ -136,7 +135,7 @@ public class GemfireTransactionManager extends AbstractPlatformTransactionManage
|
||||
} catch (IllegalStateException ex) {
|
||||
throw new NoTransactionException(
|
||||
"No transaction associated with the current thread; are there multiple transaction managers ?", ex);
|
||||
} catch (CommitConflictException ex) {
|
||||
} catch (TransactionException ex) {
|
||||
throw new GemfireTransactionCommitException("Unexpected failure on commit of Cache local transaction", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.gemstone.gemfire.cache.client.ClientCache;
|
||||
import com.gemstone.gemfire.cache.client.ClientRegionFactory;
|
||||
import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
|
||||
import com.gemstone.gemfire.cache.client.Pool;
|
||||
import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
|
||||
|
||||
/**
|
||||
* Client extension for GemFire regions.
|
||||
@@ -74,8 +75,12 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
|
||||
@Override
|
||||
protected Region<K, V> lookupFallback(GemFireCache cache, String regionName) throws Exception {
|
||||
Assert.isTrue(cache instanceof ClientCache, "Unable to create regions from " + cache);
|
||||
|
||||
ClientCache c = (ClientCache) cache;
|
||||
|
||||
if (cache instanceof GemFireCacheImpl) {
|
||||
Assert.isTrue(((GemFireCacheImpl) cache).isClient(), "A client-cache instance is required");
|
||||
}
|
||||
|
||||
|
||||
// first look at shortcut
|
||||
ClientRegionShortcut s = null;
|
||||
@@ -88,8 +93,16 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
|
||||
else if (DataPolicy.PERSISTENT_REPLICATE.equals(dataPolicy)) {
|
||||
s = ClientRegionShortcut.LOCAL_PERSISTENT;
|
||||
}
|
||||
else if (DataPolicy.NORMAL.equals(this.dataPolicy)) {
|
||||
s = ClientRegionShortcut.CACHING_PROXY;
|
||||
}
|
||||
else {
|
||||
s = ClientRegionShortcut.LOCAL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
s = ClientRegionShortcut.LOCAL;
|
||||
}
|
||||
s = ClientRegionShortcut.LOCAL;
|
||||
} else {
|
||||
s = shortcut;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class CacheParser extends AbstractSingleBeanDefinitionParser {
|
||||
ParsingUtils.setPropertyValue(element, builder, "cache-xml-location", "cacheXml");
|
||||
ParsingUtils.setPropertyReference(element, builder, "properties-ref", "properties");
|
||||
ParsingUtils.setPropertyReference(element, builder, "pdx-serializer", "pdxSerializer");
|
||||
ParsingUtils.setPropertyValue(element, builder, "pdx-disk-store", "pdxDiskStore");
|
||||
ParsingUtils.setPropertyValue(element, builder, "pdx-disk-store", "pdxDiskStoreName");
|
||||
ParsingUtils.setPropertyValue(element, builder, "pdx-persistent", "pdxPersistent");
|
||||
ParsingUtils.setPropertyValue(element, builder, "pdx-read-serialized", "pdxReadSerialized");
|
||||
ParsingUtils.setPropertyValue(element, builder, "pdx-ignore-unread-fields", "pdxIgnoreUnreadFields");
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.data.gemfire.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
import org.springframework.data.gemfire.repository.config.GemfireRepositoryParser;
|
||||
|
||||
/**
|
||||
* Namespace handler for GemFire definitions.
|
||||
@@ -40,5 +41,7 @@ class GemfireNamespaceHandler extends NamespaceHandlerSupport {
|
||||
registerBeanDefinitionParser("transaction-manager", new TransactionManagerParser());
|
||||
|
||||
registerBeanDefinitionParser("cq-listener-container", new GemfireListenerContainerParser());
|
||||
|
||||
registerBeanDefinitionParser("repositories", new GemfireRepositoryParser());
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -68,6 +68,7 @@ import com.gemstone.gemfire.cache.query.CqQuery;
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Costin Leau
|
||||
* @author Oliver Gierke
|
||||
* @see org.springframework.jms.listener.adapter.MessageListenerAdapter
|
||||
*/
|
||||
public class ContinuousQueryListenerAdapter implements ContinuousQueryListener {
|
||||
@@ -260,7 +261,6 @@ public class ContinuousQueryListenerAdapter implements ContinuousQueryListener {
|
||||
* @param event the incoming GemFire event
|
||||
* @see #handleListenerException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onEvent(CqEvent event) {
|
||||
try {
|
||||
|
||||
@@ -269,6 +269,7 @@ public class ContinuousQueryListenerAdapter implements ContinuousQueryListener {
|
||||
if (delegate != this) {
|
||||
if (delegate instanceof ContinuousQueryListener) {
|
||||
((ContinuousQueryListener) delegate).onEvent(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +284,6 @@ public class ContinuousQueryListenerAdapter implements ContinuousQueryListener {
|
||||
+ "override the 'getListenerMethodName' method.");
|
||||
}
|
||||
|
||||
|
||||
invokeListenerMethod(event, methodName);
|
||||
} catch (Throwable th) {
|
||||
handleListenerException(th);
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.springframework.data.mapping.context.AbstractMappingContext;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GemfireMappingContext extends
|
||||
AbstractMappingContext<GemfirePersistentEntity<?>, GemfirePersistentProperty> {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation)
|
||||
*/
|
||||
@Override
|
||||
protected <T> GemfirePersistentEntity<?> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
return new GemfirePersistentEntity<T>(typeInformation);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.mapping.model.MutablePersistentEntity, org.springframework.data.mapping.model.SimpleTypeHolder)
|
||||
*/
|
||||
@Override
|
||||
protected GemfirePersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor,
|
||||
GemfirePersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
return new GemfirePersistentProperty(field, descriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.model.BasicPersistentEntity;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link PersistentEntity} implementation adding custom Gemfire related metadata, such as the region the entity is
|
||||
* mapped to etc.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GemfirePersistentEntity<T> extends BasicPersistentEntity<T, GemfirePersistentProperty> {
|
||||
|
||||
private final String regionName;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GemfirePersistentEntity} for the given {@link TypeInformation}.
|
||||
*
|
||||
* @param information must not be {@literal null}.
|
||||
*/
|
||||
public GemfirePersistentEntity(TypeInformation<T> information) {
|
||||
|
||||
super(information);
|
||||
|
||||
Class<T> rawType = information.getType();
|
||||
Region region = rawType.getAnnotation(Region.class);
|
||||
String fallbackName = rawType.getSimpleName();
|
||||
|
||||
this.regionName = region == null || !StringUtils.hasText(region.value()) ? fallbackName : region.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the region the entity shall be stored in.
|
||||
*
|
||||
* @return the name of the region the entity shall be stored in.
|
||||
*/
|
||||
public String getRegionName() {
|
||||
return this.regionName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
|
||||
import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
|
||||
/**
|
||||
* {@link PersistentProperty} implementation to for Gemfire related metadata.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GemfirePersistentProperty extends AnnotationBasedPersistentProperty<GemfirePersistentProperty> {
|
||||
|
||||
/**
|
||||
* @param field
|
||||
* @param propertyDescriptor
|
||||
* @param owner
|
||||
* @param simpleTypeHolder
|
||||
*/
|
||||
public GemfirePersistentProperty(Field field, PropertyDescriptor propertyDescriptor,
|
||||
PersistentEntity<?, GemfirePersistentProperty> owner, SimpleTypeHolder simpleTypeHolder) {
|
||||
super(field, propertyDescriptor, owner, simpleTypeHolder);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.model.AbstractPersistentProperty#createAssociation()
|
||||
*/
|
||||
@Override
|
||||
protected Association<GemfirePersistentProperty> createAssociation() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import org.springframework.data.mapping.model.PropertyValueProvider;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.gemstone.gemfire.pdx.PdxReader;
|
||||
|
||||
/**
|
||||
* {@link PropertyValueProvider} to read property values from a {@link PdxReader}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class GemfirePropertyValueProvider implements PropertyValueProvider<GemfirePersistentProperty> {
|
||||
|
||||
private final PdxReader reader;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GemfirePropertyValueProvider} with the given {@link PdxReader}.
|
||||
*
|
||||
* @param reader must not be {@literal null}.
|
||||
*/
|
||||
public GemfirePropertyValueProvider(PdxReader reader) {
|
||||
Assert.notNull(reader);
|
||||
this.reader = reader;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.convert.PropertyValueProvider#getPropertyValue(org.springframework.data.mapping.PersistentProperty)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getPropertyValue(GemfirePersistentProperty property) {
|
||||
return (T) reader.readObject(property.getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.convert.EntityInstantiator;
|
||||
import org.springframework.data.convert.EntityInstantiators;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.mapping.model.BeanWrapper;
|
||||
import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider;
|
||||
import org.springframework.data.mapping.model.SpELContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.gemstone.gemfire.pdx.PdxReader;
|
||||
import com.gemstone.gemfire.pdx.PdxSerializer;
|
||||
import com.gemstone.gemfire.pdx.PdxWriter;
|
||||
|
||||
/**
|
||||
* {@link PdxSerializer} implementation that uses a {@link GemfireMappingContext} to read and write entities.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingPdxSerializer implements PdxSerializer, ApplicationContextAware {
|
||||
|
||||
private final GemfireMappingContext mappingContext;
|
||||
private final ConversionService conversionService;
|
||||
|
||||
private EntityInstantiators instantiators;
|
||||
private SpELContext context;
|
||||
|
||||
/**
|
||||
* Creates a new {@link MappingPdxSerializer} using the given {@link GemfireMappingContext} and
|
||||
* {@link ConversionService}.
|
||||
*
|
||||
* @param mappingContext must not be {@literal null}.
|
||||
* @param conversionService must not be {@literal null}.
|
||||
*/
|
||||
public MappingPdxSerializer(GemfireMappingContext mappingContext, ConversionService conversionService) {
|
||||
|
||||
Assert.notNull(mappingContext);
|
||||
Assert.notNull(conversionService);
|
||||
|
||||
this.mappingContext = mappingContext;
|
||||
this.conversionService = conversionService;
|
||||
this.instantiators = new EntityInstantiators();
|
||||
this.context = new SpELContext(PdxReaderPropertyAccessor.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link EntityInstantiator}s to be used to create the instances to be read.
|
||||
*
|
||||
* @param gemfireInstantiators must not be {@literal null}.
|
||||
*/
|
||||
public void setGemfireInstantiators(Map<Class<?>, EntityInstantiator> gemfireInstantiators) {
|
||||
Assert.notNull(gemfireInstantiators);
|
||||
this.instantiators = new EntityInstantiators(gemfireInstantiators);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.context = new SpELContext(context, applicationContext);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.gemstone.gemfire.pdx.PdxSerializer#fromData(java.lang.Class, com.gemstone.gemfire.pdx.PdxReader)
|
||||
*/
|
||||
public Object fromData(Class<?> type, final PdxReader reader) {
|
||||
|
||||
final GemfirePersistentEntity<?> entity = mappingContext.getPersistentEntity(type);
|
||||
EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
|
||||
GemfirePropertyValueProvider propertyValueProvider = new GemfirePropertyValueProvider(reader);
|
||||
|
||||
PersistentEntityParameterValueProvider<GemfirePersistentProperty> provider = new PersistentEntityParameterValueProvider<GemfirePersistentProperty>(
|
||||
entity, propertyValueProvider, null);
|
||||
provider.setSpELEvaluator(new DefaultSpELExpressionEvaluator(reader, context));
|
||||
|
||||
Object instance = instantiator.createInstance(entity, provider);
|
||||
|
||||
final BeanWrapper<PersistentEntity<Object, ?>, Object> wrapper = BeanWrapper.create(instance, conversionService);
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<GemfirePersistentProperty>() {
|
||||
public void doWithPersistentProperty(GemfirePersistentProperty persistentProperty) {
|
||||
|
||||
if (entity.isConstructorArgument(persistentProperty)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object value = reader.readField(persistentProperty.getName());
|
||||
|
||||
try {
|
||||
wrapper.setProperty(persistentProperty, value);
|
||||
} catch (Exception e) {
|
||||
throw new MappingException("Could not read value " + value.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return wrapper.getBean();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.gemstone.gemfire.pdx.PdxSerializer#toData(java.lang.Object, com.gemstone.gemfire.pdx.PdxWriter)
|
||||
*/
|
||||
public boolean toData(Object value, final PdxWriter writer) {
|
||||
|
||||
GemfirePersistentEntity<?> entity = mappingContext.getPersistentEntity(value.getClass());
|
||||
final BeanWrapper<PersistentEntity<Object, ?>, Object> wrapper = BeanWrapper.create(value, conversionService);
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<GemfirePersistentProperty>() {
|
||||
public void doWithPersistentProperty(GemfirePersistentProperty persistentProperty) {
|
||||
|
||||
try {
|
||||
Object value = wrapper.getProperty(persistentProperty);
|
||||
writer.writeObject(persistentProperty.getName(), value);
|
||||
} catch (Exception e) {
|
||||
throw new MappingException("Could not write value for property " + persistentProperty.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
GemfirePersistentProperty idProperty = entity.getIdProperty();
|
||||
|
||||
if (idProperty != null) {
|
||||
writer.markIdentityField(idProperty.getName());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
import com.gemstone.gemfire.pdx.PdxReader;
|
||||
|
||||
/**
|
||||
* {@link PropertyAccessor} to read values from a {@link PdxReader}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
enum PdxReaderPropertyAccessor implements PropertyAccessor {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.PropertyAccessor#getSpecificTargetClasses()
|
||||
*/
|
||||
@Override
|
||||
public Class<?>[] getSpecificTargetClasses() {
|
||||
return new Class<?>[] { PdxReader.class };
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.PropertyAccessor#canRead(org.springframework.expression.EvaluationContext, java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) {
|
||||
return ((PdxReader) target).hasField(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.PropertyAccessor#read(org.springframework.expression.EvaluationContext, java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) {
|
||||
Object object = ((PdxReader) target).readObject(name);
|
||||
return object == null ? TypedValue.NULL : new TypedValue(object);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.PropertyAccessor#canWrite(org.springframework.expression.EvaluationContext, java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.expression.PropertyAccessor#write(org.springframework.expression.EvaluationContext, java.lang.Object, java.lang.String, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation to define the region an entity will be stored in.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
public @interface Region {
|
||||
|
||||
/**
|
||||
* The name of the {@link com.gemstone.gemfire.cache.Region} the entity shall be stored in.
|
||||
*
|
||||
* @return the name of the region the entity shall be persisted in.
|
||||
*/
|
||||
String value() default "";
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.gemstone.bp.edu.emory.mathcs.backport.java.util.Collections;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* Simple value object to abstract access to regions by name and mapped type.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class Regions implements Iterable<Region<?, ?>> {
|
||||
|
||||
private final Map<String, Region<?, ?>> regions;
|
||||
private final MappingContext<? extends GemfirePersistentEntity<?>, ?> context;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Regions} wrapper for the given {@link Region}s and {@link MappingContext}.
|
||||
*
|
||||
* @param regions must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Regions(Iterable<Region<?, ?>> regions, MappingContext<? extends GemfirePersistentEntity<?>, ?> context) {
|
||||
|
||||
Assert.notNull(regions);
|
||||
Assert.notNull(context);
|
||||
|
||||
Map<String, com.gemstone.gemfire.cache.Region<?, ?>> regionMap = new HashMap<String, Region<?, ?>>();
|
||||
|
||||
for (Region<?, ?> region : regions) {
|
||||
regionMap.put(region.getName(), region);
|
||||
}
|
||||
|
||||
this.regions = Collections.unmodifiableMap(regionMap);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Region} the given type is mapped to. Will try to find a {@link Region} with the simple class
|
||||
* name in case no mapping information is found.
|
||||
*
|
||||
* @param type must not be {@literal null}.
|
||||
* @return the {@link Region} the given type is mapped to.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Region<?, T> getRegion(Class<T> type) {
|
||||
|
||||
Assert.notNull(type);
|
||||
|
||||
GemfirePersistentEntity<?> entity = context.getPersistentEntity(type);
|
||||
return (Region<?, T>) (entity == null ? regions.get(type.getSimpleName()) : regions.get(entity.getRegionName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Region} with the given name.
|
||||
*
|
||||
* @param name must not be {@literal null}.
|
||||
* @return the {@link Region} with the given name.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S, T> Region<S, T> getRegion(String name) {
|
||||
|
||||
Assert.notNull(name);
|
||||
|
||||
return (Region<S, T>) regions.get(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Iterable#iterator()
|
||||
*/
|
||||
@Override
|
||||
public Iterator<Region<?, ?>> iterator() {
|
||||
return regions.values().iterator();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* Gemfire-specific extension of the {@link CrudRepository} interface.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface GemfireRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
|
||||
|
||||
T save(Wrapper<T, ID> wrapper);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Query {
|
||||
|
||||
String value() default "";
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Simple value object to hold an entity alongside an external key the entity shall be stored under.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public final class Wrapper<T, KEY extends Serializable> {
|
||||
|
||||
private final KEY key;
|
||||
private final T entity;
|
||||
|
||||
/**
|
||||
* The entity to handle as well as the key.
|
||||
*
|
||||
* @param entity
|
||||
* @param key must not be {@literal null}.
|
||||
*/
|
||||
public Wrapper(T entity, KEY key) {
|
||||
|
||||
Assert.notNull(key);
|
||||
|
||||
this.entity = entity;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the key
|
||||
*/
|
||||
public KEY getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entity
|
||||
*/
|
||||
public T getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object value) {
|
||||
|
||||
if (this == value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(value instanceof Wrapper)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Wrapper<?, ?> that = (Wrapper<?, ?>) value;
|
||||
|
||||
return this.key.equals(that.key) && ObjectUtils.nullSafeEquals(this.entity, that.entity);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
int result = 17;
|
||||
|
||||
result += 31 * key.hashCode();
|
||||
result += 31 * ObjectUtils.nullSafeHashCode(entity);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.config;
|
||||
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.data.gemfire.repository.config.SimpleGemfireRepositoryConfiguration.GemfireRepositoryConfiguration;
|
||||
import org.springframework.data.gemfire.repository.support.GemfireRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.config.AbstractRepositoryConfigDefinitionParser;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* {@link BeanDefinitionParser} to create {@link GemfireRepositoryFactoryBean}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GemfireRepositoryParser extends
|
||||
AbstractRepositoryConfigDefinitionParser<SimpleGemfireRepositoryConfiguration, GemfireRepositoryConfiguration> {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.AbstractRepositoryConfigDefinitionParser#getGlobalRepositoryConfigInformation(org.w3c.dom.Element)
|
||||
*/
|
||||
@Override
|
||||
protected SimpleGemfireRepositoryConfiguration getGlobalRepositoryConfigInformation(Element element) {
|
||||
return new SimpleGemfireRepositoryConfiguration(element);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.config;
|
||||
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.repository.config.SimpleGemfireRepositoryConfiguration.GemfireRepositoryConfiguration;
|
||||
import org.springframework.data.gemfire.repository.support.GemfireRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.config.AutomaticRepositoryConfigInformation;
|
||||
import org.springframework.data.repository.config.ManualRepositoryConfigInformation;
|
||||
import org.springframework.data.repository.config.RepositoryConfig;
|
||||
import org.springframework.data.repository.config.SingleRepositoryConfigInformation;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Repository configuration implementation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class SimpleGemfireRepositoryConfiguration extends
|
||||
RepositoryConfig<GemfireRepositoryConfiguration, SimpleGemfireRepositoryConfiguration> {
|
||||
|
||||
private static final String GEMFIRE_TEMPLATE_REF = "gemfire-template-ref";
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimpleGemfireRepositoryConfiguration} for the given {@link Element}.
|
||||
*
|
||||
* @param repositoriesElement must not be {@literal null}.
|
||||
*/
|
||||
protected SimpleGemfireRepositoryConfiguration(Element repositoriesElement) {
|
||||
super(repositoriesElement, GemfireRepositoryFactoryBean.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bean name of the {@link GemfireTemplate} to be used.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getGemfireTemplateRef() {
|
||||
|
||||
String attribute = getSource().getAttribute(GEMFIRE_TEMPLATE_REF);
|
||||
return StringUtils.hasText(attribute) ? attribute : null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.GlobalRepositoryConfigInformation#getAutoconfigRepositoryInformation(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public GemfireRepositoryConfiguration getAutoconfigRepositoryInformation(String interfaceName) {
|
||||
return new AutomaticGemfireRepositoryConfiguration(interfaceName, this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.CommonRepositoryConfigInformation#getNamedQueriesLocation()
|
||||
*/
|
||||
@Override
|
||||
public String getNamedQueriesLocation() {
|
||||
return "classpath*:META-INF/gemfire-named-queries.properties";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.config.RepositoryConfig#createSingleRepositoryConfigInformationFor(org.w3c.dom.Element)
|
||||
*/
|
||||
@Override
|
||||
protected GemfireRepositoryConfiguration createSingleRepositoryConfigInformationFor(Element element) {
|
||||
return new ManualGemfireRepositoryConfiguration(element, this);
|
||||
}
|
||||
|
||||
public interface GemfireRepositoryConfiguration extends
|
||||
SingleRepositoryConfigInformation<SimpleGemfireRepositoryConfiguration> {
|
||||
|
||||
String getGemfireTemplateRef();
|
||||
}
|
||||
|
||||
static class ManualGemfireRepositoryConfiguration extends
|
||||
ManualRepositoryConfigInformation<SimpleGemfireRepositoryConfiguration> implements GemfireRepositoryConfiguration {
|
||||
|
||||
/**
|
||||
* @param element
|
||||
* @param parent
|
||||
*/
|
||||
public ManualGemfireRepositoryConfiguration(Element element, SimpleGemfireRepositoryConfiguration parent) {
|
||||
super(element, parent);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.config.GemfireRepositoryParser.SimpleGemfireRepositoryConfiguration.GemfireRepositoryConfiguration#getGemfireTemplateRef()
|
||||
*/
|
||||
@Override
|
||||
public String getGemfireTemplateRef() {
|
||||
return getAttribute(GEMFIRE_TEMPLATE_REF);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class AutomaticGemfireRepositoryConfiguration extends
|
||||
AutomaticRepositoryConfigInformation<SimpleGemfireRepositoryConfiguration> implements
|
||||
GemfireRepositoryConfiguration {
|
||||
|
||||
/**
|
||||
* @param interfaceName
|
||||
* @param parent
|
||||
*/
|
||||
public AutomaticGemfireRepositoryConfiguration(String interfaceName, SimpleGemfireRepositoryConfiguration parent) {
|
||||
super(interfaceName, parent);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.config.GemfireRepositoryParser.SimpleGemfireRepositoryConfiguration.GemfireRepositoryConfiguration#getGemfireTemplateRef()
|
||||
*/
|
||||
@Override
|
||||
public String getGemfireTemplateRef() {
|
||||
|
||||
return getParent().getGemfireTemplateRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Implementations of Spring Data COmmons Core repository abstraction.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository;
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
|
||||
import org.springframework.data.repository.core.support.DelegatingEntityInformation;
|
||||
import org.springframework.data.repository.core.support.ReflectionEntityInformation;
|
||||
|
||||
/**
|
||||
* Implementation of {@link GemfireEntityInformation} using reflection to lookup region names.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class DefaultGemfireEntityInformation<T, ID extends Serializable> extends DelegatingEntityInformation<T, ID>
|
||||
implements GemfireEntityInformation<T, ID> {
|
||||
|
||||
private final GemfirePersistentEntity<T> entity;
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultGemfireEntityInformation}.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
*/
|
||||
public DefaultGemfireEntityInformation(GemfirePersistentEntity<T> entity) {
|
||||
super(new ReflectionEntityInformation<T, ID>(entity.getType()));
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.repository.query.GemfireEntityInformation#getRegionName()
|
||||
*/
|
||||
@Override
|
||||
public String getRegionName() {
|
||||
return entity.getRegionName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.repository.core.EntityInformation;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* {@link EntityInformation} to capture Gemfire specific information.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface GemfireEntityInformation<T, ID extends Serializable> extends EntityInformation<T, ID> {
|
||||
|
||||
/**
|
||||
* Returns the name of the {@link Region} the entity is held in.
|
||||
*
|
||||
* @return the name of the {@link Region} the entity is held in.
|
||||
*/
|
||||
String getRegionName();
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
|
||||
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
|
||||
/**
|
||||
* Query creator to create {@link QueryString} instances.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class GemfireQueryCreator extends AbstractQueryCreator<QueryString, Predicates> {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(GemfireQueryCreator.class);
|
||||
|
||||
private final QueryBuilder query;
|
||||
private Iterator<Integer> indexes;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GemfireQueryCreator} using the given {@link PartTree} and domain class.
|
||||
*
|
||||
* @param tree must not be {@literal null}.
|
||||
* @param entity must not be {@literal null}.
|
||||
*/
|
||||
public GemfireQueryCreator(PartTree tree, GemfirePersistentEntity<?> entity) {
|
||||
|
||||
super(tree);
|
||||
|
||||
this.query = new QueryBuilder(entity);
|
||||
this.indexes = new IndexProvider();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#createQuery(org.springframework.data.domain.Sort)
|
||||
*/
|
||||
@Override
|
||||
public QueryString createQuery(Sort dynamicSort) {
|
||||
|
||||
this.indexes = new IndexProvider();
|
||||
return super.createQuery(dynamicSort);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#create(org.springframework.data.repository.query.parser.Part, java.util.Iterator)
|
||||
*/
|
||||
@Override
|
||||
protected Predicates create(Part part, Iterator<Object> iterator) {
|
||||
return Predicates.create(part, this.indexes);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#and(org.springframework.data.repository.query.parser.Part, java.lang.Object, java.util.Iterator)
|
||||
*/
|
||||
@Override
|
||||
protected Predicates and(Part part, Predicates base, Iterator<Object> iterator) {
|
||||
return base.and(Predicates.create(part, this.indexes));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#or(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected Predicates or(Predicates base, Predicates criteria) {
|
||||
return base.or(criteria);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.parser.AbstractQueryCreator#complete(java.lang.Object, org.springframework.data.domain.Sort)
|
||||
*/
|
||||
@Override
|
||||
protected QueryString complete(Predicates criteria, Sort sort) {
|
||||
|
||||
QueryString result = query.create(criteria);
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Created query: " + result.toString());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static class IndexProvider implements Iterator<Integer> {
|
||||
|
||||
private int index;
|
||||
|
||||
public IndexProvider() {
|
||||
this.index = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.util.Iterator#hasNext()
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return index <= Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.util.Iterator#next()
|
||||
*/
|
||||
@Override
|
||||
public Integer next() {
|
||||
return index++;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.util.Iterator#remove()
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentProperty;
|
||||
import org.springframework.data.gemfire.repository.Query;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Gemfire specific {@link QueryMethod}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GemfireQueryMethod extends QueryMethod {
|
||||
|
||||
private final Method method;
|
||||
private final GemfirePersistentEntity<?> entity;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GemfireQueryMethod} from the given {@link Method} and {@link RepositoryMetadata}.
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param metadata must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
*/
|
||||
public GemfireQueryMethod(Method method, RepositoryMetadata metadata,
|
||||
MappingContext<? extends GemfirePersistentEntity<?>, GemfirePersistentProperty> context) {
|
||||
|
||||
super(method, metadata);
|
||||
|
||||
Assert.notNull(context);
|
||||
|
||||
this.method = method;
|
||||
this.entity = context.getPersistentEntity(getDomainClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the query method contains an annotated, non-empty query.
|
||||
*
|
||||
* @return whether the query method contains an annotated, non-empty query.
|
||||
*/
|
||||
public boolean hasAnnotatedQuery() {
|
||||
return StringUtils.hasText(getAnnotatedQuery());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link GemfirePersistentEntity} the method deals with.
|
||||
*
|
||||
* @return the {@link GemfirePersistentEntity} the method deals with.
|
||||
*/
|
||||
public GemfirePersistentEntity<?> getPersistentEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the query annotated to the query method.
|
||||
*
|
||||
* @return the annotated query or {@literal null} in case it's empty or none available.
|
||||
*/
|
||||
String getAnnotatedQuery() {
|
||||
|
||||
Query query = method.getAnnotation(Query.class);
|
||||
String queryString = query == null ? null : (String) AnnotationUtils.getValue(query);
|
||||
|
||||
return StringUtils.hasText(queryString) ? queryString : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base class for GemFire specific {@link RepositoryQuery} implementations.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
abstract class GemfireRepositoryQuery implements RepositoryQuery {
|
||||
|
||||
private final GemfireQueryMethod queryMethod;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GemfireRepositoryQuery} using the given {@link GemfireQueryMethod}.
|
||||
*
|
||||
* @param queryMethod must not be {@literal null}.
|
||||
*/
|
||||
public GemfireRepositoryQuery(GemfireQueryMethod queryMethod) {
|
||||
|
||||
Assert.notNull(queryMethod);
|
||||
this.queryMethod = queryMethod;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#getQueryMethod()
|
||||
*/
|
||||
@Override
|
||||
public QueryMethod getQueryMethod() {
|
||||
return this.queryMethod;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
|
||||
/**
|
||||
* {@link GemfireRepositoryQuery} backed by a {@link PartTree} and thus, deriving an OQL query from the backing query
|
||||
* method's name.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class PartTreeGemfireRepositoryQuery extends GemfireRepositoryQuery {
|
||||
|
||||
private final GemfireQueryMethod method;
|
||||
private final PartTree tree;
|
||||
private final GemfireTemplate template;
|
||||
|
||||
/**
|
||||
* Creates a new {@link PartTreeGemfireRepositoryQuery} using the given {@link GemfireQueryMethod} and
|
||||
* {@link GemfireTemplate}.
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param template must not be {@literal null}.
|
||||
*/
|
||||
public PartTreeGemfireRepositoryQuery(GemfireQueryMethod method, GemfireTemplate template) {
|
||||
|
||||
super(method);
|
||||
|
||||
Class<?> domainClass = method.getEntityInformation().getJavaType();
|
||||
|
||||
this.tree = new PartTree(method.getName(), domainClass);
|
||||
this.method = method;
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Object[] parameters) {
|
||||
|
||||
ParametersParameterAccessor parameterAccessor = new ParametersParameterAccessor(method.getParameters(), parameters);
|
||||
QueryString query = new GemfireQueryCreator(tree, method.getPersistentEntity()).createQuery(parameterAccessor
|
||||
.getSort());
|
||||
|
||||
RepositoryQuery repositoryQuery = new StringBasedGemfireRepositoryQuery(query.toString(), method, template);
|
||||
|
||||
return repositoryQuery.execute(parameters);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
interface Predicate {
|
||||
|
||||
String toString(String alias);
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
import org.springframework.data.repository.query.parser.Part.Type;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
class Predicates implements Predicate {
|
||||
|
||||
private final Predicate current;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Predicates} wrapper instance.
|
||||
*
|
||||
* @param predicate must not be {@literal null}.
|
||||
*/
|
||||
private Predicates(Predicate predicate) {
|
||||
this.current = predicate;
|
||||
}
|
||||
|
||||
private static Predicates create(Predicate predicate) {
|
||||
return new Predicates(predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Predicate for the given {@link Part} and index iterator.
|
||||
*
|
||||
* @param part must not be {@literal null}.
|
||||
* @param value must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public static Predicates create(Part part, Iterator<Integer> value) {
|
||||
return create(new AtomicPredicate(part, value));
|
||||
}
|
||||
|
||||
/**
|
||||
* And-concatenates the given {@link Predicate} to the current one.
|
||||
*
|
||||
* @param predicate must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public Predicates and(final Predicate predicate) {
|
||||
|
||||
return create(new Predicate() {
|
||||
@Override
|
||||
public String toString(String alias) {
|
||||
return String.format("%s AND %s", Predicates.this.current.toString(alias), predicate.toString(alias));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Or-concatenates the given {@link Predicate} to the current one.
|
||||
*
|
||||
* @param predicate must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public Predicates or(final Predicate predicate) {
|
||||
|
||||
return create(new Predicate() {
|
||||
@Override
|
||||
public String toString(String alias) {
|
||||
return String.format("%s OR %s", Predicates.this.current.toString(alias), predicate.toString(alias));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.repository.query.Predicate#toString(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public String toString(String alias) {
|
||||
return current.toString(alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate to create a predicate expression for a {@link Part}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static class AtomicPredicate implements Predicate {
|
||||
|
||||
private final Part part;
|
||||
private final Iterator<Integer> value;
|
||||
|
||||
/**
|
||||
* Creates a new {@link AtomicPredicate}.
|
||||
*
|
||||
* @param part must not be {@literal null}.
|
||||
* @param value must not be {@literal null}.
|
||||
*/
|
||||
public AtomicPredicate(Part part, Iterator<Integer> value) {
|
||||
|
||||
Assert.notNull(part);
|
||||
Assert.notNull(value);
|
||||
|
||||
this.part = part;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.repository.query.Predicate#toString(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public String toString(String alias) {
|
||||
|
||||
Type type = part.getType();
|
||||
return String.format("%s.%s %s", alias == null ? QueryBuilder.DEFAULT_ALIAS : alias, part.getProperty()
|
||||
.toDotPath(), toClause(type));
|
||||
}
|
||||
|
||||
private String toClause(Type type) {
|
||||
|
||||
switch (type) {
|
||||
case IS_NULL:
|
||||
case IS_NOT_NULL:
|
||||
return String.format("%s NULL", getOperator(type));
|
||||
default:
|
||||
return String.format("%s $%s", getOperator(type), value.next());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the given {@link Type} to an OQL operator.
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
private String getOperator(Type type) {
|
||||
|
||||
switch (type) {
|
||||
case IN:
|
||||
return "IN SET";
|
||||
case NOT_IN:
|
||||
return "NOT IN SET";
|
||||
case GREATER_THAN:
|
||||
return ">";
|
||||
case GREATER_THAN_EQUAL:
|
||||
return ">=";
|
||||
case LESS_THAN:
|
||||
return "<";
|
||||
case LESS_THAN_EQUAL:
|
||||
return "<=";
|
||||
case IS_NOT_NULL:
|
||||
case NEGATING_SIMPLE_PROPERTY:
|
||||
return "!=";
|
||||
case IS_NULL:
|
||||
case SIMPLE_PROPERTY:
|
||||
return "=";
|
||||
default:
|
||||
throw new IllegalArgumentException(String.format("Unsupported operator %s!", type));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class QueryBuilder {
|
||||
|
||||
static final String DEFAULT_ALIAS = "x";
|
||||
|
||||
private final String query;
|
||||
|
||||
public QueryBuilder(String source) {
|
||||
Assert.hasText(source);
|
||||
this.query = source;
|
||||
}
|
||||
|
||||
public QueryBuilder(GemfirePersistentEntity<?> entity) {
|
||||
this(String.format("SELECT * FROM /%s %s", entity.getRegionName(), DEFAULT_ALIAS));
|
||||
}
|
||||
|
||||
public QueryString create(Predicate predicate) {
|
||||
|
||||
return new QueryString(query + " WHERE " + predicate.toString(DEFAULT_ALIAS));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return query;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* Value object to work with OQL query strings.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
class QueryString {
|
||||
|
||||
private static final String REGION_PATTERN = "(?<=\\/)%s";
|
||||
private static final String IN_PARAMETER_PATTERN = "(?<=IN (SET|LIST) \\$)\\d";
|
||||
private static final String IN_PATTERN = "(?<=IN (SET|LIST) )\\$\\d";
|
||||
|
||||
private final String query;
|
||||
|
||||
/**
|
||||
* Creates a {@link QueryString} from the given {@link String} query.
|
||||
*
|
||||
* @param source
|
||||
*/
|
||||
public QueryString(String source) {
|
||||
|
||||
Assert.hasText(source);
|
||||
this.query = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@literal SELECT} query for the given domain class.
|
||||
*
|
||||
* @param domainClass must not be {@literal null}.
|
||||
*/
|
||||
public QueryString(Class<?> domainClass) {
|
||||
this(String.format("SELECT * FROM /%s", domainClass.getSimpleName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the domain classes referenced inside the current query with the given {@link Region}.
|
||||
*
|
||||
* @param domainClass must not be {@literal null}.
|
||||
* @param region must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public QueryString forRegion(Class<?> domainClass, Region<?, ?> region) {
|
||||
|
||||
String pattern = String.format(REGION_PATTERN, domainClass.getSimpleName());
|
||||
return new QueryString(query.replaceAll(pattern, region.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the given values to the {@literal IN} parameter keyword by expanding the given values into a comma-separated
|
||||
* {@link String}.
|
||||
*
|
||||
* @param values the values to bind, returns the {@link QueryString} as is if {@literal null} is given.
|
||||
* @return
|
||||
*/
|
||||
public QueryString bindIn(Collection<?> values) {
|
||||
|
||||
if (values == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
String valueString = StringUtils.collectionToDelimitedString(values, ", ", "'", "'");
|
||||
return new QueryString(query.replaceFirst(IN_PATTERN, String.format("(%s)", valueString)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parameter indexes used in this query.
|
||||
*
|
||||
* @return the parameter indexes used in this query or an empty {@link Iterable} if none are used.
|
||||
*/
|
||||
public Iterable<Integer> getInParameterIndexes() {
|
||||
|
||||
Pattern pattern = Pattern.compile(IN_PARAMETER_PATTERN);
|
||||
Matcher matcher = pattern.matcher(query);
|
||||
List<Integer> result = new ArrayList<Integer>();
|
||||
|
||||
while (matcher.find()) {
|
||||
result.add(Integer.parseInt(matcher.group()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return query;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.repository.query.ParametersParameterAccessor;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link GemfireRepositoryQuery} using plain {@link String} based OQL queries.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class StringBasedGemfireRepositoryQuery extends GemfireRepositoryQuery {
|
||||
|
||||
private final QueryString query;
|
||||
private final GemfireQueryMethod method;
|
||||
private final GemfireTemplate template;
|
||||
|
||||
/**
|
||||
* Creates a new {@link StringBasedGemfireRepositoryQuery} using the given {@link GemfireQueryMethod} and
|
||||
* {@link GemfireTemplate}. The actual query {@link String} will be looked up from the query method.
|
||||
*
|
||||
* @param method must not be {@literal null}.
|
||||
* @param template must not be {@literal null}.
|
||||
*/
|
||||
public StringBasedGemfireRepositoryQuery(GemfireQueryMethod method, GemfireTemplate template) {
|
||||
this(method.getAnnotatedQuery(), method, template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link StringBasedGemfireRepositoryQuery} using the given query {@link String},
|
||||
* {@link GemfireQueryMethod} and {@link GemfireTemplate}.
|
||||
*
|
||||
* @param query will fall back to the query annotated to the given {@link GemfireQueryMethod} if {@literal null} is
|
||||
* given.
|
||||
* @param method must not be {@literal null}.
|
||||
* @param template must not be {@literal null}.
|
||||
*/
|
||||
public StringBasedGemfireRepositoryQuery(String query, GemfireQueryMethod method, GemfireTemplate template) {
|
||||
|
||||
super(method);
|
||||
|
||||
Assert.notNull(template);
|
||||
|
||||
this.query = new QueryString(StringUtils.hasText(query) ? query : method.getAnnotatedQuery());
|
||||
this.method = method;
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Object[] parameters) {
|
||||
|
||||
ParametersParameterAccessor accessor = new ParametersParameterAccessor(method.getParameters(), parameters);
|
||||
QueryString query = this.query.forRegion(method.getEntityInformation().getJavaType(), template.getRegion());
|
||||
|
||||
Iterator<Integer> indexes = query.getInParameterIndexes().iterator();
|
||||
while (indexes.hasNext()) {
|
||||
query = query.bindIn(toCollection(accessor.getBindableValue(indexes.next() - 1)));
|
||||
}
|
||||
|
||||
return template.find(query.toString(), parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given object as collection. Collections will be returned as is, Arrays will be converted into a
|
||||
* collection and all other objects will be wrapped into a single-element collection.
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
private Collection<?> toCollection(Object source) {
|
||||
|
||||
if (source instanceof Collection) {
|
||||
return (Collection<?>) source;
|
||||
}
|
||||
|
||||
return source.getClass().isArray() ? CollectionUtils.arrayToList(source) : Collections.singleton(source);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentProperty;
|
||||
import org.springframework.data.gemfire.mapping.Regions;
|
||||
import org.springframework.data.gemfire.repository.query.DefaultGemfireEntityInformation;
|
||||
import org.springframework.data.gemfire.repository.query.GemfireEntityInformation;
|
||||
import org.springframework.data.gemfire.repository.query.GemfireQueryMethod;
|
||||
import org.springframework.data.gemfire.repository.query.PartTreeGemfireRepositoryQuery;
|
||||
import org.springframework.data.gemfire.repository.query.StringBasedGemfireRepositoryQuery;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* {@link RepositoryFactorySupport} implementation creating repository proxies for Gemfire.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GemfireRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
private final MappingContext<? extends GemfirePersistentEntity<?>, GemfirePersistentProperty> context;
|
||||
private final Regions regions;
|
||||
|
||||
/**
|
||||
* Creates a new {@link GemfireRepositoryFactory}.
|
||||
*
|
||||
* @param regions must not be {@literal null}.
|
||||
* @param context
|
||||
*/
|
||||
public GemfireRepositoryFactory(Iterable<Region<?, ?>> regions,
|
||||
MappingContext<? extends GemfirePersistentEntity<?>, GemfirePersistentProperty> context) {
|
||||
|
||||
Assert.notNull(regions);
|
||||
|
||||
this.context = context == null ? new GemfireMappingContext() : context;
|
||||
this.regions = new Regions(regions, this.context);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getEntityInformation(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, ID extends Serializable> GemfireEntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
|
||||
GemfirePersistentEntity<T> entity = (GemfirePersistentEntity<T>) context.getPersistentEntity(domainClass);
|
||||
return new DefaultGemfireEntityInformation<T, ID>(entity);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getTargetRepository(org.springframework.data.repository.core.RepositoryMetadata)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected Object getTargetRepository(RepositoryMetadata metadata) {
|
||||
|
||||
GemfireEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());
|
||||
GemfireTemplate gemfireTemplate = getTemplate(metadata);
|
||||
|
||||
return new SimpleGemfireRepository(gemfireTemplate, entityInformation);
|
||||
}
|
||||
|
||||
private GemfireTemplate getTemplate(RepositoryMetadata metadata) {
|
||||
|
||||
Class<?> domainClass = metadata.getDomainType();
|
||||
GemfirePersistentEntity<?> entity = context.getPersistentEntity(domainClass);
|
||||
|
||||
Region<?, ?> region = regions.getRegion(domainClass);
|
||||
|
||||
if (region == null) {
|
||||
throw new IllegalStateException(String.format("No region '%s' found for domain class %s! Make sure you have "
|
||||
+ "configured a Gemfire region of that name in your application context!", entity.getRegionName(), domainClass));
|
||||
}
|
||||
|
||||
Class<?> regionKeyType = region.getAttributes().getKeyConstraint();
|
||||
Class<?> entityIdType = metadata.getIdType();
|
||||
|
||||
if (regionKeyType != null && entity.getIdProperty() != null) {
|
||||
Assert.isTrue(regionKeyType.isAssignableFrom(entityIdType), String.format(
|
||||
"The region referenced only supports keys of type %s but the entity to be stored has an id of type %s!",
|
||||
regionKeyType, entityIdType));
|
||||
}
|
||||
|
||||
return new GemfireTemplate(region);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getRepositoryBaseClass(org.springframework.data.repository.core.RepositoryMetadata)
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
|
||||
return SimpleGemfireRepository.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key)
|
||||
*/
|
||||
@Override
|
||||
protected QueryLookupStrategy getQueryLookupStrategy(Key key) {
|
||||
return new QueryLookupStrategy() {
|
||||
@Override
|
||||
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, NamedQueries namedQueries) {
|
||||
|
||||
GemfireQueryMethod queryMethod = new GemfireQueryMethod(method, metadata, context);
|
||||
GemfireTemplate template = getTemplate(metadata);
|
||||
|
||||
if (queryMethod.hasAnnotatedQuery()) {
|
||||
return new StringBasedGemfireRepositoryQuery(queryMethod, template);
|
||||
}
|
||||
|
||||
String namedQueryName = queryMethod.getNamedQueryName();
|
||||
if (namedQueries.hasQuery(namedQueryName)) {
|
||||
return new StringBasedGemfireRepositoryQuery(namedQueries.getQuery(namedQueryName), queryMethod, template);
|
||||
}
|
||||
|
||||
return new PartTreeGemfireRepositoryQuery(queryMethod, template);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentProperty;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
|
||||
import com.gemstone.bp.edu.emory.mathcs.backport.java.util.Collections;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* {@link FactoryBean} adapter for {@link GemfireRepositoryFactory}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GemfireRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends
|
||||
RepositoryFactoryBeanSupport<T, S, ID> implements ApplicationContextAware {
|
||||
|
||||
private MappingContext<? extends GemfirePersistentEntity<?>, GemfirePersistentProperty> context;
|
||||
private Iterable<Region<?, ?>> regions;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
Collection<Region> regions = applicationContext.getBeansOfType(Region.class).values();
|
||||
this.regions = Collections.unmodifiableCollection(regions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the {@link MappingContext} to be used.
|
||||
*
|
||||
* @param context the context to set
|
||||
*/
|
||||
public void setMappingContext(MappingContext<? extends GemfirePersistentEntity<?>, GemfirePersistentProperty> context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#createRepositoryFactory()
|
||||
*/
|
||||
@Override
|
||||
protected RepositoryFactorySupport createRepositoryFactory() {
|
||||
return new GemfireRepositoryFactory(regions, context);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package org.springframework.data.gemfire.repository.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.gemfire.GemfireCallback;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.repository.GemfireRepository;
|
||||
import org.springframework.data.gemfire.repository.Wrapper;
|
||||
import org.springframework.data.repository.core.EntityInformation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.gemstone.gemfire.GemFireCheckedException;
|
||||
import com.gemstone.gemfire.GemFireException;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* Basic repository implementation.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SimpleGemfireRepository<T, ID extends Serializable> implements GemfireRepository<T, ID> {
|
||||
|
||||
private final GemfireTemplate template;
|
||||
private final EntityInformation<T, ID> entityInformation;
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimpleGemfireRepository}.
|
||||
*
|
||||
* @param template must not be {@literal null}.
|
||||
* @param entityInformation must not be {@literal null}.
|
||||
*/
|
||||
public SimpleGemfireRepository(GemfireTemplate template, EntityInformation<T, ID> entityInformation) {
|
||||
|
||||
Assert.notNull(template);
|
||||
Assert.notNull(entityInformation);
|
||||
|
||||
this.template = template;
|
||||
this.entityInformation = entityInformation;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#save(S)
|
||||
*/
|
||||
public <U extends T> U save(U entity) {
|
||||
template.put(entityInformation.getId(entity), entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#save(java.lang.Iterable)
|
||||
*/
|
||||
public <U extends T> Iterable<U> save(Iterable<U> entities) {
|
||||
List<U> result = new ArrayList<U>();
|
||||
for (U entity : entities) {
|
||||
result.add(save(entity));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public T findOne(ID id) {
|
||||
Object object = template.get(id);
|
||||
return (T) object;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#exists(java.io.Serializable)
|
||||
*/
|
||||
public boolean exists(ID id) {
|
||||
return findOne(id) != null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#findAll()
|
||||
*/
|
||||
public Collection<T> findAll() {
|
||||
return template.execute(new GemfireCallback<Collection<T>>() {
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public Collection<T> doInGemfire(Region region) {
|
||||
return region.values();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#findAll(java.lang.Iterable)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<T> findAll(Iterable<ID> ids) {
|
||||
|
||||
List<ID> parameters = new ArrayList<ID>();
|
||||
for (ID id : ids) {
|
||||
parameters.add(id);
|
||||
}
|
||||
|
||||
return (Collection<T>) template.getAll(parameters).values();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#count()
|
||||
*/
|
||||
public long count() {
|
||||
return template.execute(new GemfireCallback<Long>() {
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Long doInGemfire(Region region) throws GemFireCheckedException, GemFireException {
|
||||
return Long.valueOf(region.keySet().size());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.lang.Object)
|
||||
*/
|
||||
public void delete(T entity) {
|
||||
template.remove(entityInformation.getId(entity));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.lang.Iterable)
|
||||
*/
|
||||
public void delete(Iterable<? extends T> entities) {
|
||||
for (T entity : entities) {
|
||||
delete(entity);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#deleteAll()
|
||||
*/
|
||||
public void deleteAll() {
|
||||
|
||||
template.execute(new GemfireCallback<Void>() {
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Void doInGemfire(Region region) {
|
||||
region.clear();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.io.Serializable)
|
||||
*/
|
||||
public void delete(ID id) {
|
||||
template.remove(id);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.repository.GemfireRepository#save(org.springframework.data.gemfire.repository.Wrapper)
|
||||
*/
|
||||
@Override
|
||||
public T save(Wrapper<T, ID> wrapper) {
|
||||
return template.put(wrapper.getKey(), wrapper.getEntity());
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
http\://www.springframework.org/schema/gemfire/spring-gemfire-1.0.xsd=org/springframework/data/gemfire/config/spring-gemfire-1.0.xsd
|
||||
http\://www.springframework.org/schema/gemfire/spring-gemfire-1.1.xsd=org/springframework/data/gemfire/config/spring-gemfire-1.1.xsd
|
||||
http\://www.springframework.org/schema/gemfire/spring-gemfire.xsd=org/springframework/data/gemfire/config/spring-gemfire-1.1.xsd
|
||||
http\://www.springframework.org/schema/gemfire/spring-gemfire-1.2.xsd=org/springframework/data/gemfire/config/spring-gemfire-1.2.xsd
|
||||
http\://www.springframework.org/schema/gemfire/spring-gemfire.xsd=org/springframework/data/gemfire/config/spring-gemfire-1.2.xsd
|
||||
@@ -6,7 +6,7 @@
|
||||
targetNamespace="http://www.springframework.org/schema/gemfire"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified"
|
||||
version="1.1">
|
||||
version="1.1.1">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
|
||||
@@ -1074,7 +1074,7 @@ The client subscription configuration that is used to control a clients use of s
|
||||
<xsd:attribute name="max-time-between-pings" use="optional" type="xsd:string" default="60000" />
|
||||
<xsd:attribute name="message-time-to-live" use="optional" type="xsd:string" default="180" />
|
||||
<xsd:attribute name="socket-buffer-size" use="optional" type="xsd:string" default="32768" />
|
||||
<xsd:attribute name="notify-by-subscription" use="optional" type="xsd:boolean" default="true" />
|
||||
<xsd:attribute name="notify-by-subscription" use="optional" type="xsd:string" default="true" />
|
||||
<xsd:attribute name="groups" use="optional" type="xsd:string" default="">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,11 +16,9 @@
|
||||
|
||||
package org.springframework.data.gemfire.listener.adapter;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -31,9 +29,9 @@ import com.gemstone.gemfire.cache.query.CqEvent;
|
||||
import com.gemstone.gemfire.cache.query.CqQuery;
|
||||
import com.gemstone.gemfire.cache.query.internal.CqQueryImpl;
|
||||
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class QueryListenerAdapterTest {
|
||||
|
||||
@@ -92,16 +90,17 @@ public class QueryListenerAdapterTest {
|
||||
void handleOperation(Operation op);
|
||||
|
||||
void handleArray(byte[] ba);
|
||||
|
||||
|
||||
void handleKey(Object key);
|
||||
|
||||
|
||||
void handleKV(Object k, Object v);
|
||||
|
||||
|
||||
void handleEx(Throwable th);
|
||||
|
||||
|
||||
void handleOps(Operation base, Operation query);
|
||||
|
||||
void handleAll(CqEvent event, CqQuery query, byte[] ba, Object key, Operation op, Throwable th, Operation qOp, Object v);
|
||||
void handleAll(CqEvent event, CqQuery query, byte[] ba, Object key, Operation op, Throwable th, Operation qOp,
|
||||
Object v);
|
||||
|
||||
void handleInvalid(Object o1, Object o2, Object o3);
|
||||
}
|
||||
@@ -212,4 +211,31 @@ public class QueryListenerAdapterTest {
|
||||
doThrow(new IllegalArgumentException()).when(mock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see SGF-89
|
||||
*/
|
||||
@Test
|
||||
public void triggersListenerImplementingInterfaceCorrectly() {
|
||||
|
||||
SampleListener listener = new SampleListener();
|
||||
|
||||
ContinuousQueryListener listenerAdapter = new ContinuousQueryListenerAdapter(listener) {
|
||||
protected void handleListenerException(Throwable ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
};
|
||||
|
||||
listenerAdapter.onEvent(event());
|
||||
assertThat(listener.count, is(1));
|
||||
}
|
||||
|
||||
class SampleListener implements ContinuousQueryListener {
|
||||
|
||||
int count;
|
||||
|
||||
@Override
|
||||
public void onEvent(CqEvent event) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GemfirePersistentEntity}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GemfirePersistentEntityUnitTests {
|
||||
|
||||
@Test
|
||||
public void defaultsRegionNameToClassName() {
|
||||
GemfirePersistentEntity<UnannotatedRegion> entity = new GemfirePersistentEntity<UnannotatedRegion>(
|
||||
ClassTypeInformation.from(UnannotatedRegion.class));
|
||||
assertThat(entity.getRegionName(), is(UnannotatedRegion.class.getSimpleName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultsAnnotatedRegionToCLassName() {
|
||||
GemfirePersistentEntity<UnnamedRegion> entity = new GemfirePersistentEntity<UnnamedRegion>(
|
||||
ClassTypeInformation.from(UnnamedRegion.class));
|
||||
assertThat(entity.getRegionName(), is(UnnamedRegion.class.getSimpleName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readsRegionNameFromAnnotation() {
|
||||
|
||||
GemfirePersistentEntity<AnnotatedRegion> entity = new GemfirePersistentEntity<AnnotatedRegion>(
|
||||
ClassTypeInformation.from(AnnotatedRegion.class));
|
||||
assertThat(entity.getRegionName(), is("Foo"));
|
||||
}
|
||||
|
||||
static class UnannotatedRegion {
|
||||
|
||||
}
|
||||
|
||||
@Region("Foo")
|
||||
static class AnnotatedRegion {
|
||||
|
||||
}
|
||||
|
||||
@Region
|
||||
static class UnnamedRegion {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
|
||||
import org.springframework.data.gemfire.mapping.MappingPdxSerializer;
|
||||
import org.springframework.data.gemfire.repository.sample.Address;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
|
||||
import com.gemstone.gemfire.cache.Cache;
|
||||
import com.gemstone.gemfire.cache.CacheFactory;
|
||||
import com.gemstone.gemfire.cache.DataPolicy;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.RegionFactory;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MappingPdxSerializer}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class MappingPdxSerializerIntegrationTest {
|
||||
|
||||
Region<Object, Object> region;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
MappingPdxSerializer serializer = new MappingPdxSerializer(new GemfireMappingContext(),
|
||||
new DefaultConversionService());
|
||||
|
||||
CacheFactory factory = new CacheFactory();
|
||||
factory.setPdxSerializer(serializer);
|
||||
factory.setPdxPersistent(true);
|
||||
|
||||
Cache cache = factory.create();
|
||||
|
||||
RegionFactory<Object, Object> regionFactory = cache.createRegionFactory();
|
||||
regionFactory.setDataPolicy(DataPolicy.PERSISTENT_REPLICATE);
|
||||
region = regionFactory.create("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void serializeAndDeserializeCorrectly() {
|
||||
|
||||
Address address = new Address();
|
||||
address.zipCode = "01234";
|
||||
address.city = "London";
|
||||
|
||||
Person person = new Person(1L, "Oliver", "Gierke");
|
||||
person.address = address;
|
||||
|
||||
region.put(1L, person);
|
||||
Object result = region.get(1L);
|
||||
|
||||
assertThat(result instanceof Person, is(true));
|
||||
|
||||
Person reference = person;
|
||||
assertThat(reference.getFirstname(), is(person.getFirstname()));
|
||||
assertThat(reference.getLastname(), is(person.getLastname()));
|
||||
assertThat(reference.address, is(person.address));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.data.convert.EntityInstantiator;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
import org.springframework.data.mapping.model.ParameterValueProvider;
|
||||
|
||||
import com.gemstone.gemfire.pdx.PdxReader;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MappingPdxSerializer}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MappingPdxSerializerUnitTests {
|
||||
|
||||
GemfireMappingContext context;
|
||||
ConversionService conversionService;
|
||||
MappingPdxSerializer serializer;
|
||||
|
||||
@Mock
|
||||
EntityInstantiator instantiator;
|
||||
@Mock
|
||||
PdxReader reader;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
context = new GemfireMappingContext();
|
||||
conversionService = new GenericConversionService();
|
||||
serializer = new MappingPdxSerializer(context, conversionService);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void usesRegisteredInstantiator() {
|
||||
|
||||
Person person = new Person(1L, "Oliver", "Gierke");
|
||||
|
||||
ParameterValueProvider<GemfirePersistentProperty> provider = any(ParameterValueProvider.class);
|
||||
GemfirePersistentEntity<?> entity = any(GemfirePersistentEntity.class);
|
||||
when(instantiator.createInstance(entity, provider)).thenReturn(person);
|
||||
|
||||
Map<Class<?>, EntityInstantiator> instantiators = new HashMap<Class<?>, EntityInstantiator>();
|
||||
instantiators.put(Person.class, instantiator);
|
||||
|
||||
serializer.setGemfireInstantiators(instantiators);
|
||||
serializer.fromData(Person.class, reader);
|
||||
|
||||
verify(instantiator, times(1)).createInstance(eq(context.getPersistentEntity(Person.class)),
|
||||
any(ParameterValueProvider.class));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.mapping;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
import com.gemstone.bp.edu.emory.mathcs.backport.java.util.Arrays;
|
||||
import com.gemstone.gemfire.pdx.PdxReader;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class PdxReaderPropertyAccessorUnitTests {
|
||||
|
||||
@Mock
|
||||
PdxReader reader;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void appliesToPdxReadersOnly() {
|
||||
List<Class<?>> classes = Arrays.asList(PdxReaderPropertyAccessor.INSTANCE.getSpecificTargetClasses());
|
||||
assertThat(classes, hasItem(PdxReader.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canReadPropertyIfReaderHasField() {
|
||||
|
||||
when(reader.hasField("key")).thenReturn(true);
|
||||
assertThat(PdxReaderPropertyAccessor.INSTANCE.canRead(null, reader, "key"), is(true));
|
||||
|
||||
when(reader.hasField("key")).thenReturn(false);
|
||||
assertThat(PdxReaderPropertyAccessor.INSTANCE.canRead(null, reader, "key"), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsTypedNullIfNullIsReadFromReader() {
|
||||
|
||||
when(reader.readObject("key")).thenReturn(null);
|
||||
assertThat(PdxReaderPropertyAccessor.INSTANCE.read(null, reader, "key"), is(TypedValue.NULL));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsTypeValueWithValueReadFromReader() {
|
||||
|
||||
when(reader.readObject("key")).thenReturn("String");
|
||||
|
||||
TypedValue result = PdxReaderPropertyAccessor.INSTANCE.read(null, reader, "key");
|
||||
|
||||
assertThat(result.getTypeDescriptor(), is(TypeDescriptor.valueOf(String.class)));
|
||||
assertThat(result.getValue(), is((Object) "String"));
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void doesNotSupportWrites() {
|
||||
|
||||
assertThat(PdxReaderPropertyAccessor.INSTANCE.canWrite(null, null, null), is(false));
|
||||
PdxReaderPropertyAccessor.INSTANCE.write(null, null, null, reader);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.gemfire.mapping.Regions;
|
||||
import org.springframework.data.gemfire.repository.sample.PersonRepository;
|
||||
import org.springframework.data.gemfire.repository.support.AbstractGemfireRepositoryFactoryIntegrationTests;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
/**
|
||||
* Integration tests for namespace usage.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@ContextConfiguration("repo-context.xml")
|
||||
public class NamespaceRepositoryIntegrationTests extends AbstractGemfireRepositoryFactoryIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
PersonRepository repository;
|
||||
|
||||
@Override
|
||||
protected PersonRepository getRepository(Regions regions) {
|
||||
return repository;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
|
||||
import org.springframework.data.gemfire.mapping.GemfirePersistentEntity;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GemfireQueryCreator}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class GemfireQueryCreatorUnitTests {
|
||||
|
||||
GemfirePersistentEntity<Person> entity;
|
||||
|
||||
@Before
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setUp() {
|
||||
|
||||
GemfireMappingContext context = new GemfireMappingContext();
|
||||
entity = (GemfirePersistentEntity<Person>) context.getPersistentEntity(Person.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createsQueryForSimplePropertyReferenceCorrectly() {
|
||||
|
||||
PartTree partTree = new PartTree("findByFirstname", Person.class);
|
||||
GemfireQueryCreator creator = new GemfireQueryCreator(partTree, entity);
|
||||
|
||||
QueryString query = creator.createQuery();
|
||||
assertThat(query.toString(), is("SELECT * FROM /simple x WHERE x.firstname = $1"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
|
||||
import org.springframework.data.gemfire.repository.Query;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class GemfireQueryMethodUnitTests {
|
||||
|
||||
@Mock
|
||||
RepositoryMetadata metadata;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void detectsAnnotatedQueryCorrectly() throws Exception {
|
||||
|
||||
GemfireMappingContext context = new GemfireMappingContext();
|
||||
when(metadata.getDomainType()).thenReturn((Class) Person.class);
|
||||
when(metadata.getReturnedDomainClass(Mockito.any(Method.class))).thenReturn((Class) Person.class);
|
||||
|
||||
GemfireQueryMethod method = new GemfireQueryMethod(Sample.class.getMethod("annotated"), metadata, context);
|
||||
assertThat(method.hasAnnotatedQuery(), is(true));
|
||||
assertThat(method.getAnnotatedQuery(), is("foo"));
|
||||
|
||||
method = new GemfireQueryMethod(Sample.class.getMethod("annotatedButEmpty"), metadata, context);
|
||||
assertThat(method.hasAnnotatedQuery(), is(false));
|
||||
assertThat(method.getAnnotatedQuery(), is(nullValue()));
|
||||
|
||||
method = new GemfireQueryMethod(Sample.class.getMethod("notAnnotated"), metadata, context);
|
||||
assertThat(method.hasAnnotatedQuery(), is(false));
|
||||
assertThat(method.getAnnotatedQuery(), is(nullValue()));
|
||||
}
|
||||
|
||||
interface Sample {
|
||||
|
||||
@Query("foo")
|
||||
void annotated();
|
||||
|
||||
@Query("")
|
||||
void annotatedButEmpty();
|
||||
|
||||
void notAnnotated();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.gemfire.repository.query.Predicates.AtomicPredicate;
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class PredicatesUnitTests {
|
||||
|
||||
@Test
|
||||
public void atomicPredicateDefaultsAlias() {
|
||||
|
||||
Part part = new Part("firstname", Person.class);
|
||||
|
||||
Iterable<Integer> indexes = Arrays.asList(1);
|
||||
|
||||
Predicate predicate = new AtomicPredicate(part, indexes.iterator());
|
||||
assertThat(predicate.toString(null), is("x.firstname = $1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void concatenatesAndPredicateCorrectly() {
|
||||
|
||||
Part left = new Part("firstname", Person.class);
|
||||
Part right = new Part("lastname", Person.class);
|
||||
Iterator<Integer> indexes = Arrays.asList(1, 2).iterator();
|
||||
|
||||
Predicates predicate = Predicates.create(left, indexes);
|
||||
predicate = predicate.and(new AtomicPredicate(right, indexes));
|
||||
|
||||
assertThat(predicate.toString(null), is("x.firstname = $1 AND x.lastname = $2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void concatenatesOrPredicateCorrectly() {
|
||||
|
||||
Part left = new Part("firstname", Person.class);
|
||||
Part right = new Part("lastname", Person.class);
|
||||
Iterator<Integer> indexes = Arrays.asList(1, 2).iterator();
|
||||
|
||||
Predicates predicate = Predicates.create(left, indexes);
|
||||
predicate = predicate.or(new AtomicPredicate(right, indexes));
|
||||
|
||||
assertThat(predicate.toString(null), is("x.firstname = $1 OR x.lastname = $2"));
|
||||
}
|
||||
|
||||
static class Person {
|
||||
|
||||
String firstname;
|
||||
String lastname;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class QueryStringUnitTests {
|
||||
|
||||
@Mock
|
||||
@SuppressWarnings("rawtypes")
|
||||
Region region;
|
||||
|
||||
@Test
|
||||
public void replacesDomainObjectWithRegionNameCorrectly() {
|
||||
|
||||
QueryString query = new QueryString("SELECT * FROM /Person p WHERE p.firstname = $1");
|
||||
|
||||
when(region.getName()).thenReturn("foo");
|
||||
assertThat(query.forRegion(Person.class, region).toString(), is("SELECT * FROM /foo p WHERE p.firstname = $1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindsInValuesCorrectly() {
|
||||
|
||||
QueryString query = new QueryString("SELECT * FROM /Person p WHERE p.firstname IN SET $1");
|
||||
List<Integer> values = Arrays.asList(1, 2, 3);
|
||||
assertThat(query.bindIn(values).toString(), is("SELECT * FROM /Person p WHERE p.firstname IN SET ('1', '2', '3')"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void detectsInParameterIndexesCorrectly() {
|
||||
|
||||
QueryString query = new QueryString("IN SET $1 OR IN SET $2");
|
||||
Iterable<Integer> indexes = query.getInParameterIndexes();
|
||||
assertThat(indexes, is((Iterable<Integer>) Arrays.asList(1, 2)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.sample;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class Address {
|
||||
|
||||
public String zipCode;
|
||||
public String city;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.sample;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.gemfire.mapping.Region;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Region("simple")
|
||||
public class Person implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 508843183613325255L;
|
||||
|
||||
@Id
|
||||
public Long id;
|
||||
public String firstname;
|
||||
public String lastname;
|
||||
public Address address;
|
||||
|
||||
public Person(Long id, String firstname, String lastname) {
|
||||
this.id = id;
|
||||
this.firstname = firstname;
|
||||
this.lastname = lastname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the firstname
|
||||
*/
|
||||
public String getFirstname() {
|
||||
return firstname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lastname
|
||||
*/
|
||||
public String getLastname() {
|
||||
return lastname;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.sample;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.data.gemfire.repository.Query;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public interface PersonRepository extends Repository<Person, Long> {
|
||||
|
||||
@Query("SELECT * FROM /Person p WHERE p.firstname = $1")
|
||||
Collection<Person> findByFirstnameAnnotated(String firstname);
|
||||
|
||||
@Query("SELECT * FROM /Person p WHERE p.firstname IN SET $1")
|
||||
Collection<Person> findByFirstnamesAnnotated(Collection<String> firstnames);
|
||||
|
||||
Collection<Person> findByFirstname(String firstname);
|
||||
|
||||
Collection<Person> findByFirstnameIn(Collection<String> firstnames);
|
||||
|
||||
Collection<Person> findByFirstnameIn(String... firstnames);
|
||||
|
||||
Collection<Person> findByFirstnameAndLastname(String firstname, String lastname);
|
||||
|
||||
Collection<Person> findByFirstnameOrLastname(String firstname, String lastname);
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.support;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.mapping.GemfireMappingContext;
|
||||
import org.springframework.data.gemfire.mapping.Regions;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
import org.springframework.data.gemfire.repository.sample.PersonRepository;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* Integration test for {@link GemfireRepositoryFactory}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public abstract class AbstractGemfireRepositoryFactoryIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
List<Region<?, ?>> regions;
|
||||
|
||||
Person dave, carter, boyd, stefan, leroi, jeff;
|
||||
PersonRepository repository;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
dave = new Person(1L, "Dave", "Matthews");
|
||||
carter = new Person(2L, "Carter", "Beauford");
|
||||
boyd = new Person(3L, "Boyd", "Tinsley");
|
||||
stefan = new Person(4L, "Stefan", "Lessard");
|
||||
leroi = new Person(5L, "Leroi", "Moore");
|
||||
jeff = new Person(6L, "Jeff", "Coffin");
|
||||
|
||||
GemfireMappingContext context = new GemfireMappingContext();
|
||||
|
||||
Regions regions = new Regions(this.regions, context);
|
||||
GemfireTemplate template = new GemfireTemplate(regions.getRegion(Person.class));
|
||||
|
||||
template.put(dave.id, dave);
|
||||
template.put(carter.id, carter);
|
||||
template.put(boyd.id, boyd);
|
||||
template.put(stefan.id, stefan);
|
||||
template.put(leroi.id, leroi);
|
||||
template.put(jeff.id, jeff);
|
||||
|
||||
repository = getRepository(regions);
|
||||
}
|
||||
|
||||
protected abstract PersonRepository getRepository(Regions regions);
|
||||
|
||||
@Test
|
||||
public void foo() {
|
||||
assertResultsFound(repository.findByFirstnameAnnotated("Dave"), dave);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executesAnnotatedInQueryMethodCorrectly() {
|
||||
assertResultsFound(repository.findByFirstnamesAnnotated(Arrays.asList("Carter", "Dave")), carter, dave);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executesInQueryMethodCorrectly() {
|
||||
assertResultsFound(repository.findByFirstnameIn(Arrays.asList("Carter", "Dave")), carter, dave);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executesDerivedQueryCorrectly() {
|
||||
assertResultsFound(repository.findByFirstname("Carter"), carter);
|
||||
assertResultsFound(repository.findByFirstnameIn(Arrays.asList("Stefan", "Boyd")), stefan, boyd);
|
||||
assertResultsFound(repository.findByFirstnameIn("Leroi"), leroi);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executesDerivedQueryWithAndCorrectly() {
|
||||
assertResultsFound(repository.findByFirstnameAndLastname("Carter", "Beauford"), carter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executesDerivedQueryWithOrCorrectly() {
|
||||
assertResultsFound(repository.findByFirstnameOrLastname("Carter", "Matthews"), carter, dave);
|
||||
}
|
||||
|
||||
private <T> void assertResultsFound(Collection<T> result, T... expected) {
|
||||
|
||||
assertThat(result, is(notNullValue()));
|
||||
assertThat(result.size(), is(expected.length));
|
||||
|
||||
for (T element : expected) {
|
||||
assertThat(result.contains(element), is(true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.support;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.gemfire.mapping.Regions;
|
||||
import org.springframework.data.gemfire.repository.sample.PersonRepository;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
import com.gemstone.bp.edu.emory.mathcs.backport.java.util.Collections;
|
||||
|
||||
/**
|
||||
* Integration test for {@link GemfireRepositoryFactory}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@ContextConfiguration("../config/repo-context.xml")
|
||||
public class GemfireRepositoryFactoryIntegrationTests extends AbstractGemfireRepositoryFactoryIntegrationTests {
|
||||
|
||||
@Override
|
||||
protected PersonRepository getRepository(Regions regions) {
|
||||
|
||||
GemfireRepositoryFactory factory = new GemfireRepositoryFactory(regions, null);
|
||||
return factory.getRepository(PersonRepository.class);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
@SuppressWarnings("unchecked")
|
||||
public void throwsExceptionIfReferencedRegionIsNotConfigured() {
|
||||
|
||||
GemfireRepositoryFactory factory = new GemfireRepositoryFactory(Collections.emptySet(), null);
|
||||
factory.getRepository(PersonRepository.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.repository.support;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.gemfire.GemfireTemplate;
|
||||
import org.springframework.data.gemfire.repository.sample.Person;
|
||||
import org.springframework.data.repository.core.EntityInformation;
|
||||
import org.springframework.data.repository.core.support.ReflectionEntityInformation;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.gemstone.gemfire.cache.query.SelectResults;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link SimpleGemfireRepository}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("../../basic-template.xml")
|
||||
public class SimpleGemfireRepositoryIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
GemfireTemplate template;
|
||||
|
||||
SimpleGemfireRepository<Person, Long> repository;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
EntityInformation<Person, Long> information = new ReflectionEntityInformation<Person, Long>(Person.class);
|
||||
repository = new SimpleGemfireRepository<Person, Long>(template, information);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void storeAndDeleteEntity() {
|
||||
|
||||
Person person = new Person(1L, "Oliver", "Gierke");
|
||||
|
||||
repository.save(person);
|
||||
|
||||
assertThat(repository.count(), is(1L));
|
||||
assertThat(repository.findOne(person.id), is(person));
|
||||
assertThat(repository.findAll().size(), is(1));
|
||||
|
||||
repository.delete(person);
|
||||
|
||||
assertThat(repository.count(), is(0L));
|
||||
assertThat(repository.findOne(person.id), is(nullValue()));
|
||||
assertThat(repository.findAll().size(), is(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queryRegion() throws Exception {
|
||||
|
||||
Person person = new Person(1L, "Oliver", "Gierke");
|
||||
|
||||
template.put(1L, person);
|
||||
|
||||
SelectResults<Person> persons = template.find("SELECT * FROM /simple s WHERE s.firstname = $1", person.firstname);
|
||||
|
||||
assertThat(persons.size(), is(1));
|
||||
assertThat(persons.iterator().next(), is(person));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findAllWithGivenIds() {
|
||||
|
||||
Person dave = new Person(1L, "Dave", "Matthews");
|
||||
Person carter = new Person(2L, "Carter", "Beauford");
|
||||
Person leroi = new Person(3L, "Leroi", "Moore");
|
||||
|
||||
template.put(dave.id, dave);
|
||||
template.put(carter.id, carter);
|
||||
template.put(leroi.id, leroi);
|
||||
|
||||
Collection<Person> result = repository.findAll(Arrays.asList(carter.id, leroi.id));
|
||||
assertThat(result, hasItems(carter, leroi));
|
||||
assertThat(result, not(hasItems(dave)));
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
|
||||
|
||||
log4j.category.org.springframework.data.gemfire.listener=TRACE
|
||||
log4j.category.org.springframework.data.gemfire.repository=DEBUG
|
||||
|
||||
# for debugging datasource initialization
|
||||
# log4j.category.test.jdbc=DEBUG
|
||||
|
||||
@@ -12,6 +12,6 @@
|
||||
</gfe:pool>
|
||||
-->
|
||||
|
||||
<gfe:cache/>
|
||||
<gfe:client-cache/>
|
||||
<gfe:client-region data-policy="NORMAL" name="ChallengeQuestions" id="challengeQuestionsRegion"/>
|
||||
</beans>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<gfe:cache />
|
||||
<gfe:client-cache />
|
||||
|
||||
<gfe:client-region id="simple" pool-name="gemfire-pool"/>
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<gfe:repositories base-package="org.springframework.data.gemfire.repository.sample" />
|
||||
|
||||
<gfe:cache use-bean-factory-locator="false" />
|
||||
<gfe:replicated-region id="simple" />
|
||||
|
||||
</beans>
|
||||
@@ -12,6 +12,8 @@ Import-Template:
|
||||
org.springframework.context.*;version=${spring.range},
|
||||
org.springframework.core.*;version=${spring.range},
|
||||
org.springframework.dao.*;version=${spring.range},
|
||||
org.springframework.data.*;version="${springDataCommonsVersion:[=.=.=.=,+1.0.0)}",
|
||||
org.springframework.expression.*;version="${springVersion:[=.=.=,+1.0.0)}",
|
||||
org.springframework.util.*;version=${spring.range},
|
||||
org.springframework.transaction.*;version=${spring.range},
|
||||
com.gemstone.gemfire.*;version=${gemfire.range},
|
||||
|
||||
Reference in New Issue
Block a user