Compare commits

..

101 Commits

Author SHA1 Message Date
Oliver Gierke
4cdd59ffd4 DATAMONGO-1304 - After release cleanups. 2015-10-14 14:18:24 +02:00
Spring Buildmaster
5160cdadb6 DATAMONGO-1304 - Prepare next development iteration. 2015-10-14 03:37:30 -07:00
Spring Buildmaster
296ca28efa DATAMONGO-1304 - Release version 1.6.4.RELEASE (Evans SR4). 2015-10-14 03:37:13 -07:00
Oliver Gierke
86fa1d902a DATAMONGO-1304 - Prepare 1.6.4.RELEASE (Evans SR4). 2015-10-14 11:25:06 +02:00
Oliver Gierke
80834d8321 DATAMONGO-1304 - Updated changelog. 2015-10-14 11:24:57 +02:00
Oliver Gierke
30b0ec8f57 DATAMONGO-1282 - Updated changelog. 2015-10-14 08:52:52 +02:00
Oliver Gierke
b157981507 DATAMONGO-1268 - Updated changelog. 2015-10-14 08:52:40 +02:00
Oliver Gierke
bfd96d529c DATAMONGO-1261 - Updated changelog. 2015-10-14 08:52:26 +02:00
Oliver Gierke
bf51bcd7ea DATAMONGO-1246 - Updated changelog. 2015-10-14 08:49:35 +02:00
Oliver Gierke
f9317b9f09 DATAMONGO-1250 - Fixed inline code formatting in reference docs. 2015-07-04 19:07:24 +02:00
Oliver Gierke
99bb92db4e DATAMONGO-1250 - Fixed accidental duplicate invocation of value conversion in UpdateMapper.
UpdateMapper.getMappedObjectForField(…) invokes the very same method of the super class but handed in an already mapped value so that value conversion was invoked twice.

This was especially problematic in cases a dedicated converter had been registered for an object that is already a Mongo-storable one (e.g. an enum-to-string converter and back) without indicating which of the tow converter is the reading or the writing one. This basically caused the source value converted back and forth during the update mapping creating the impression the value wasn't converted at all.

This is now fixed by removing the superfluous mapping.
2015-07-04 14:16:48 +02:00
Oliver Gierke
87d609e1c4 DATAMONGO-1247 - After release cleanups. 2015-07-01 01:41:45 +02:00
Spring Buildmaster
8f223bf12f DATAMONGO-1247 - Prepare next development iteration. 2015-06-30 16:04:51 -07:00
Spring Buildmaster
a96253f9a4 DATAMONGO-1247 - Release version 1.6.3.RELEASE (Evans SR3). 2015-06-30 16:04:49 -07:00
Oliver Gierke
a0884b8227 DATAMONGO-1247 - Prepare 1.6.3.RELEASE (Evans SR3). 2015-07-01 00:12:28 +02:00
Oliver Gierke
2e6efae925 DATAMONGO-1247 - Updated changelog. 2015-07-01 00:12:11 +02:00
Oliver Gierke
4e688574fc DATAMONGO-1248 - Updated changelog. 2015-06-30 14:00:01 +02:00
Oliver Gierke
3abd38953c DATAMONGO-1228 - Updated changelog. 2015-06-30 13:59:53 +02:00
Oliver Gierke
026f3fadd3 DATAMONGO-1189 - Updated changelog. 2015-06-30 13:59:34 +02:00
Oliver Gierke
14e352aeae DATAMONGO-1236 - Polishing.
Removed the creation of a BasicMongoPersistentEntity in favor of always handing ClassTypeInformation.OBJECT into the converter in case not entity can be found.

This makes sure type information is written for updates on properties of type Object (which essentially leads to no PersistentEntity being available).

Original pull request: #301.
2015-06-30 09:55:42 +02:00
Christoph Strobl
41aa498a1e DATAMONGO-1236 - Update now include type hint correctly.
We now use property type information when mapping fields affected by an update in case we do not have proper entity information within the context. This allows more precise type resolution required for determining the need to write type hints for a given property.

Original pull request: #301.
2015-06-30 09:55:37 +02:00
Christoph Strobl
74cead91fc DATAMONGO-1232 - IngoreCase in criteria now escapes query.
We now quote the original criteria before actually wrapping it inside of an regular expression for case insensitive search. This happens not only to case insensitive is, startsWith, endsWith criteria but also to those using like. In that case we quote the part between leading and trailing wildcard if required.

Original pull request: #301.
2015-06-22 12:51:32 +02:00
Christoph Strobl
559f160b21 DATAMONGO-1166 - ReadPreference is now be used for aggregations.
We now use MongoTemplate.readPreference(…) when executing commands such as geoNear(…) and aggregate(…).

Original pull request: #303.
2015-06-22 08:47:22 +02:00
Christoph Strobl
62fdd3e519 DATAMONGO-1157 - Throw meaningful exception when @DbRef is used with unsupported types.
We now eagerly check DBRef properties for invalid definitions such as final class or array. In that case we throw a MappingException when verify is called.
2015-06-19 15:54:32 +02:00
Thomas Darimont
1a414fa2b6 DATAMONGO-1242 - Update MongoDB Java driver to 3.0.2 in mongo3 profile.
Update mongo driver.

Original pull request: #304.
2015-06-19 15:38:01 +02:00
Oliver Gierke
29a712e298 DATAMONGO-1229 - Fixed application of ignore case flag on nested properties.
Previously we tried to apply the ignore case settings found in the PartTree to the root PropertyPath we handle in MongoQueryCreator.create(). This is now changed to work on the leaf property of the PropertyPath.
2015-06-05 06:56:55 +02:00
Eddú Meléndez
65a164874a DATAMONGO-1234 - Fix typos in JavaDoc. 2015-06-05 06:38:45 +02:00
Oliver Gierke
d6ff5162b3 DATAMONGO-1210 - Polishing.
Moved getTypeHint(…) method to Field class.

Original pull request: #292.
2015-06-01 13:26:54 +02:00
Christoph Strobl
28a84cafc5 DATAMONGO-1210 - Fixed type hints for usage with findAndModify(…).
We now inspect the actual field type during update mapping and provide a type hint accordingly. Simple, non interface and non abstract types will no longer be decorated with the _class attribute. We now honor positional parameters when trying to map paths to properties. This allows more decent type mapping since we have now access to the meta model which allows us to check if presence of type hint (aka _class) is required.

We now add a special type hint indicating nested types to the converter. This allows more fine grained removal of _class property without the need to break the contract of MongoWriter.convertToMongoType(…).

Original pull request: #292.
2015-06-01 13:26:40 +02:00
Stefan Ganzer
eb10b5c426 DATAMONGO-1210 - Add breaking test case for findAndModify/addToSet/each.
The problem stems from the inconsistent handling of type hints such as MongoTemplate.save(…) does not add a type hint, but findAndModify(…) does. The same values are then treated differently by MongoDB, depending on whether they have a type hint or not. To verify this behavior, you can manually add the (superfluous) type hint to the saved object - findAndModify will then work as expected.

Additional tests demonstrate that findAndModify(…) removes type hints from complex documents in collections that are either nested in another collection or in a document, or doesn't add them in the first place.

Original pull requests: #290, #291.
Related pull request: #292.
CLA: 119820150506013701 (Stefan Ganzer)
2015-06-01 13:26:15 +02:00
Thomas Darimont
b7b24215e3 DATAMONGO-1133 - Fixed broken tests,
AggregationTests.shouldHonorFieldAliasesForFieldReferences() now correctly sets up 3 different instances of MeterData and correctly calculates the aggreated counter values.

Original pull request: #279.
2015-05-25 13:55:59 +02:00
Oliver Gierke
2a27eb7404 DATAMONGO-1224 - Ensure Spring Framework 4.2 compatibility.
Removed obsolete generics in MongoPersistentEntityIndexCreator to make sure MappingContextEvents are delivered to the listener on Spring 4.2 which applies more strict generics handling to ApplicationEvents.

Tweaked PersonBeforeSaveListener in test code to actually reflect how an ApplicationEventListener for MongoDB would be implemented.

Removed deprecated (and now removed) usage of ConversionServiceFactory in AbstractMongoConverter. Added MongoMappingEventPublisher.publishEvent(Object) as NoOp.
2015-05-25 13:13:40 +02:00
Oliver Gierke
ad3ad1f65f DATAMONGO-1221 - Removed <relativePath /> element from parent POM declaration. 2015-05-15 15:08:13 +02:00
Oliver Gierke
e7278888a7 DATAMONGO-1213 - Included section on dependency management in reference documentation.
Related ticket: DATACMNS-687.
2015-05-04 14:53:01 +02:00
Oliver Gierke
374fa5a1f2 DATAMONGO-1207 - Fixed potential NPE in MongoTemplate.doInsertAll(…).
If a collection containing null values is handed to MongoTempalte.insertAll(…), a NullPointerException was caused by the unguarded attempt to lookup the class of the element. We now explicitly handle this case and skip the element.

Some code cleanups in MongoTemplate.doInsertAll(…).
2015-05-02 14:48:57 +02:00
Oliver Gierke
be92489c58 DATAMONGO-1196 - Upgraded build profiles after MongoDB 3.0 Java driver GA release. 2015-04-01 17:15:55 +02:00
Christoph Strobl
88172c8674 DATAMONGO-1124 - Switch log level for cyclic reference index warnings to INFO.
Reduce log level from warn to info to avoid noise during application startup.

Original pull request: #282.
2015-03-23 09:00:37 +01:00
Oliver Gierke
2dc2072fce DATAMONGO-1180 - Polishing.
Fixed copyright ranges in license headers. Added unit test to PartTreeMongoQueryUnitTests to verify the root exception being propagated correctly.

Original pull request: #280.
Related pull request: #259.
2015-03-10 12:23:30 +01:00
Thomas Darimont
a7b70d68d7 DATAMONGO-1180 - Fixed incorrect exception message creation in PartTreeMongoQuery.
The JSONParseException caught in PartTreeMongoQuery is now passed to the IllegalStateException we throw from the method. Previously it was passed to the String.format(…) varargs. Verified by manually throwing a JSONParseException in the debugger.

Original pull request: #280.
Related pull request: #259.
2015-03-10 12:23:22 +01:00
Oliver Gierke
6dc2de03ad DATAMONGO-1173 - Updated changelog. 2015-03-06 08:02:08 +01:00
Thomas Darimont
dc0a03ee63 DATAMONGO-1133 - Assert that field aliasing is honored in aggregation operations.
Added some test to show that field aliases are honored during object rendering in aggregation operations.

Original pull request: #279.
2015-03-05 12:25:05 +01:00
Thomas Darimont
504c44cdf3 DATAMONGO-1081 - Improve documentation on field mapping semantics.
Added table with examples to identifier field mapping section.

Original pull request: #276.
2015-03-02 18:15:27 +01:00
Oliver Gierke
9ea8b6f6d1 DATAMONGO-1144 - Fixed version numbers to point to the next bugfix release. 2015-02-03 11:54:58 +01:00
Oliver Gierke
37c9de6af9 DATAMONGO-1155 - Upgraded mongo-next build profile to driver version 2.13.0.
Related ticket: DATAMONGO-1154.
2015-01-29 21:16:48 +01:00
Oliver Gierke
9a1ee81f3f DATAMONGO-1153 - Fix documentation build.
Movend jconsole.png to the images folder. Extracted MongoDB-specific auditing documentation into separate file for inclusion after the general auditing docs.
2015-01-29 14:03:46 +01:00
Oliver Gierke
c8331c3a1c DATAMONGO-1144 - After release cleanups. 2015-01-28 17:41:43 +01:00
Spring Buildmaster
b794d536c5 DATAMONGO-1144 - Prepare next development iteration. 2015-01-28 04:17:48 -08:00
Spring Buildmaster
afa05122d2 DATAMONGO-1144 - Release version 1.6.2.RELEASE (Evans SR2). 2015-01-28 04:17:39 -08:00
Oliver Gierke
cf06a6527c DATAMONGO-1144 - Prepare 1.6.2.RELEASE (Evans SR2). 2015-01-28 12:03:12 +01:00
Oliver Gierke
0760a8b425 DATAMONGO-1144 - Updated changelog. 2015-01-28 11:23:25 +01:00
Oliver Gierke
f65cd1d235 DATAMONGO-1143 - Updated changelog. 2015-01-28 10:00:30 +01:00
Oliver Gierke
6f86208111 DATAMONGO-1148 - Favor EclipseLink’s JPA over the Hibernate one. 2015-01-27 21:43:59 +01:00
Oliver Gierke
0c33f7e01a DATAMONGO-712 - Another round of performance improvements.
Refactored CustomConversions to unify locked access to the cached types. Added a cache for raw-write-targets so that they’re cached, too.

DBObjectAccessor now avoids expensive code paths for both reads and writes in case of simple field names.

MappingMongoConverter now eagerly skips conversions of simple types in case the value is already assignable to the target type.

QueryMapper now checks the ConversionService and only triggers a conversion if it’s actually capable of doing so instead of catching a more expensive exception.

CachingMongoPersistentProperty now also caches usePropertyAccess() and isTransient() as they’re used quite frequently.

Related ticket: DATACMNS-637.
2015-01-25 18:39:54 +01:00
alex-on-java
047df58724 DATAMONGO-1147 - Remove manual array copy.
Remove manual array coping by using Arrays.copyOf(values, values.length).

Original pull request: #258.
2015-01-23 18:02:50 +01:00
Christoph Strobl
9716a93576 DATAMONGO-1144 - Upgrade dependencies.
mongo-java-driver: 2.12.3 > 2.12.5
2015-01-22 08:50:19 +01:00
Thomas Darimont
03e5ebb741 DATAMONGO-1082 - Improved documentation of alias usage in aggregation framework.
Added missing JavaDoc and added short note to the reference documentation.

Original pull request: #268.
2015-01-22 08:48:03 +01:00
Thomas Darimont
6ac908b72e DATAMONGO-1127 - Add support for geoNear queries with distance information.
Made unit tests more robust to small differences in distance calculations between MongoDB versions.
2015-01-20 19:05:23 +01:00
Thomas Darimont
5f1049f2de DATAMONGO-1127 - Add support for geoNear queries with distance information.
We now support geoNear queries in Aggregations. Exposed GeoNearOperation factory method in Aggregation. Introduced new distanceField property to NearQuery since it is required for geoNear queries in Aggregations.

Original pull request: #261.
2015-01-20 18:19:52 +01:00
Christoph Strobl
07c79e8ba9 DATAMONGO-1121 - Fix false positive when checking for potential cycles.
We now only check for cycles on entity types and explicitly exclude simple types.

Original pull request: #267.
2015-01-20 12:18:43 +01:00
Oliver Gierke
a94cca3494 DATAMONGO-1106 - Updated changelog. 2015-01-20 07:37:27 +01:00
Oliver Gierke
90842844d4 DATAMONGO-1139 - MongoQueryCreator now only uses $nearSpherical if non-neutral Metric is used.
Fixed the evaluation of the Distance for a near clause handed into a query method. Previously we evaluated against null, which will never result in true as Distance returns Metrics.NEUTRAL by default.
2015-01-12 19:24:48 +01:00
Oliver Gierke
f4c27407ac DATAMONGO-1123 - Improve JavaDoc of MongoOperations.geoNear(…).
The JavaDoc of the geoNear(…) methods in MongoOperations now contain a hint to MongoDB limiting the number of results by default and an explicit limit on the NearQuery can be used to disable that.
2015-01-07 15:02:41 +01:00
Oliver Gierke
00e1ebb880 DATAMONGO-1118 - Polishing.
Created dedicated prepareMapKey(…) method to chain calls to potentiallyConvertMapKey(…) and potentiallyEscapeMapKey(…) and make sure they always get applied in combination.

Fixed initial map creation for DBRefs to apply the fixed behavior, too.

Original pull request: #260.
2015-01-06 15:49:46 +01:00
Thomas Darimont
dd32479ad4 DATAMONGO-1118 - Simplified potentiallyConvertMapKey in MappingMongoConverter.
Fixed typos in CustomConversions.

Original pull request: #260.
2015-01-06 15:48:44 +01:00
Christoph Strobl
ce5fe50550 DATAMONGO-1118 - MappingMongoConverter now uses custom conversions for Map keys, too.
We now allow conversions of map keys using custom Converter implementations if the conversion target type is a String.

Original pull request: #260.
2015-01-06 15:48:28 +01:00
Christophe Fargette
3a04bcb5d3 DATACMNS-1132 - Fixed keyword translation table in the reference documentation.
Original pull request: #262.
2015-01-06 13:29:46 +01:00
Oliver Gierke
acfe6ccc2c DATAMONGO-1120 - Fix execution of query methods using pagination and field mapping customizations.
Repository queries that used pagination and referred to a field that was customized were failing as the count query executed was not mapped correctly in MongoOperations.

This result from the fix for DATAMONGO-1080 which removed the premature field name translation from AbstractMongoQuery and thus lead to unmapped field names being used for the count query.

We now expose the previously existing, but not public count(…) method on MongoOperations that takes both an entity type as well as an explicit collection name to be able to count-query a dedicated collection but still get the query mapping applied for a certain type.

Related ticket: DATAMONGO-1080.
2014-12-18 15:54:29 +01:00
Oliver Gierke
3f3ec19364 DATAMONGO-1096 - Polishing.
Fixed formatting for changes introduced with DATAMONGO-1096.
2014-12-17 18:38:17 +01:00
Thomas Darimont
24cbef9bc5 DATAMONGO-1085 - Fixed sorting with Querydsl in QueryDslMongoRepository.
We now translate QSort's OrderSpecifiers into appropriate sort criteria.
Previously the OrderSpecifiers were not correctly translated to appropriate property path expressions.

We're now overriding support for findAll(Pageable) and findAll(Sort) to QueryDslMongoRepository to apply special QSort handling.

Original pull request: #236.
2014-12-01 12:08:43 +01:00
Oliver Gierke
b5f74444de DATAMONGO-1043 - Make sure we dynamically lookup SpEL based collection names for query execution.
Changed SimpleMongoEntityMetadata to keep a reference to the collection entity instead of the eagerly resolved collection name. This is to make sure the name gets re-evaluated for every query execution to support dynamically changing collections defined via SpEL expressions.

Related pull request: #238.
2014-11-28 20:26:32 +01:00
Oliver Gierke
1b7e077296 DATAMONGO-1054 - Polishing.
Tweaked JavaDoc of the APIs to be less specific about implementation internals and rather point to the save(…) methods. Changed SimpleMongoRepository.save(…) methods to inspect the given entity/entities and use the optimized insert(All)-calls if all entities are considered new.

Original pull request: #253.
2014-11-28 18:38:06 +01:00
Thomas Darimont
7ebaf935d4 DATAMONGO-1054 - Add support for fast insertion via MongoRepository.insert(..).
Introduced new insert(..) method variants on MongoRepositories that delegates to MongoTemplate.insert(..). This bypasses ID-population, save event generation and version checking and allows for fast insertion of bulk data.

Original pull request: #253.
2014-11-28 18:37:55 +01:00
Oliver Gierke
295d7579cb DATAMONGO-1108 - Performance improvements in BasicMongoPersistentEntity.
BasicMongoPersistentEntity.getCollection() now avoids repeated SpEL-parsing and evaluating in case no SpEL expression is used. Parsing is happening at most once now. Evaluation is skipped entirely if the configured collection String is not or does not contain an expression.
2014-11-28 16:23:48 +01:00
Christoph Strobl
a99950d83e DATAMONGO-1087 - Fix index resolver detecting cycles for partial match.
We now check for presence of a dot path to verify that we’ve detected a cycle.

Original pull request: #240.
2014-11-28 12:03:55 +01:00
Christoph Strobl
0bf4ee2711 DATAMONGO-1075 - Containing keyword is now correctly translated for collection properties.
We now inspect the properties type when creating criteria for CONTAINS keyword so that, if the target property is of type String, we use an expression, and if the property is collection like we try to finds an exact match within the collection using $in.

Original pull request: #241.
2014-11-27 17:14:23 +01:00
Thomas Darimont
5b8da8dd41 DATAMONGO-1093 - Added hashCode() and equals(…) in BasicQuery.
We now have equals(…) and hashCode(…) methods on BasicQuery. Previously we solely relied on Query.hashCode()/equals(…) which didn't consider the fields of BasicQuery.

Introduced equals verifier library to automatically test equals contracts.
Added some additional test cases to BasicQueryUnitTests.

Original pull request: #252.
2014-11-27 16:46:24 +01:00
Mikhail Mikhaylenko
b56ca97f68 DATAMONGO-1096 - Use null-safe toString representation of query for debug logging.
We now use the null-safe serailizeToJsonSafely to avoid potential RuntimeExceptions during debug query printing in MongoTemplate.

Based on original PR: #247.

Original pull request: #251.
2014-11-26 09:42:51 +01:00
Thomas Darimont
f183b5c7e6 DATAMONGO-1094 - Fixed ambiguous field mapping error message in BasicMongoPersistentEntity.
Original pull request: #245.
2014-11-25 17:36:03 +01:00
Oliver Gierke
1fdde8f0c3 DATAMONGO-1078 - Polishing.
Polished test cases. Simplified equals(…)/hashCode() for sample entity and its identifier type.

Original pull request: #239.
2014-11-10 16:38:24 +01:00
Christoph Strobl
b7c3e69653 DATAMONGO-1078 - @Query annotated repository method fails for complex Id when used with Collection type.
Remove object type hint defaulting.
2014-11-10 16:38:21 +01:00
Oliver Gierke
e64d69b8f5 DATAMONGO-1079 - After release cleanups. 2014-10-31 21:44:01 +01:00
Spring Buildmaster
d81ed203db DATAMONGO-1079 - Prepare next development iteration. 2014-10-30 14:36:37 +01:00
Spring Buildmaster
eae463622c DATAMONGO-1079 - Release version 1.6.1.RELEASE (Evans SR1). 2014-10-30 14:36:13 +01:00
Oliver Gierke
6ba8144bca DATAMONGO-1079 - Prepare 1.6.1.RELEASE (Evans SR1). 2014-10-30 12:33:08 +01:00
Oliver Gierke
9d1c1a9fc5 DATAMONGO-1079 - Updated changelog. 2014-10-30 11:57:35 +01:00
Oliver Gierke
f552ca8073 DATAMONGO-1080 - AbstractMongoQuery now refrains from eagerly post-processing the query execution results.
To properly support general post processing of query execution results (in QueryExecutorMethodInterceptor) we need to remove the eager post-processing of query execution results in AbstractMongoQuery.

Removed the usage of the local ConversionService all together.
2014-10-30 11:36:02 +01:00
Thomas Darimont
d7bd82c643 DATAMONGO-1076 - Avoid resolving lazy-loading proxy for DBRefs during finalize.
We now handle intercepted finalize method invocations by not resolving the proxy. Previously the LazyLoadingProxy tried to resolve the proxy during finalization which could lead to unnecessary database accesses.

Original pull request: #234.
2014-10-29 10:16:34 +01:00
Christoph Strobl
078cca83e3 DATAMONGO-1077 - Fix Update removing $ operator for DBRef.
We now retain the positional parameter "$" when mapping field names for associations.

Orignal pull request: #235.
2014-10-28 14:30:08 +01:00
Christoph Strobl
93ae6815bd DATAMONGO-1072 - Fix annotated query placeholders not replaced correctly.
We now also check field names for potential placeholder matches to ensure those are registered for binding parameters.

Original pull request: #233.
2014-10-22 13:56:59 +02:00
Christoph Strobl
13dcb8cda1 DATAMONGO-1068 - Fix getCritieriaObject returns empty DBO when no key defined.
We now check for the presence of a Critieria key.

Original pull request: #232.
2014-10-21 12:06:51 +02:00
Oliver Gierke
a4497bcf8a DATAMONGO-1070 - Fixed a few glitches in DBRef binding for repository query methods.
The QueryMapping for derived repository queries pointing to the identifier of the referenced document. We now reduce the query field's key from reference.id to reference so that the generated DBRef is applied correctly and also take care that the id's are potentially converted to ObjectIds. This is mainly achieved by using the AssociationConverter pulled up from UpdateMapper in ObjectMapper.getMappedKey().

MongoQueryCreator now refrains from translating the field keys as that will fail the QueryMapper to correctly detect id properties.

Fixed DBRef handling for StringBasedMongoQuery which previously didn't parse the DBRef instance created after JSON parsing for placeholders.
2014-10-15 10:14:12 +02:00
Christoph Strobl
6a82c47a4d DATAMONGO-1063 - Fix application of Querydsl'S any().in() throwing Exception.
We now only convert paths that point to either a property or variable.

Original pull request: #230.
2014-10-10 11:35:57 +02:00
Christoph Strobl
8f8f5b7ce4 DATAMONGO-1053 - Type check is now only performed on explicit language properties.
We now only perform a type check on via @Language explicitly defined language properties. Prior to this change non-String properties named language caused errors on entity validation.

Original pull request: #228.
2014-10-10 11:31:39 +02:00
Oliver Gierke
c683813a7a DATAMONGO-1057 - Polishing.
Slightly tweaked the changes in SlicedExecution to simplify the implementation. We now apply the given pageable but tweak the limit the query uses to peek into the next page.

Original pull request: #226.
2014-10-08 07:06:35 +02:00
Christoph Strobl
dbe983c3cb DATAMONGO-1057 - Fix SliceExecution skipping elements.
We now directly set the offset to use instead of reading it from the used pageable. This asserts that every single element is read from the store.
Prior to this change the altered pageSize lead to an unintended increase of the number of elements to skip.

Original pull request: #226.
2014-10-08 07:06:35 +02:00
Oliver Gierke
8e11fe84df DATAMONGO-1062 - Polishing.
Removed exploded static imports. Updated copyright header.

Original pull request: #229.
2014-10-07 16:29:48 +02:00
Christoph Strobl
9eb2856840 DATAMONGO-1058 - DBRef should respect explicit field name.
We now use property.getFieldName() for mapping DbRefs. This assures we also capture explicitly defined names set via @Field.

Original pull request: #227.
2014-10-01 10:05:52 +02:00
Thomas Darimont
828b379f1f DATAMONGO-1062 - Fix failing test in ServerAddressPropertyEditorUnitTests.
The test rejectsAddressConfigWithoutASingleParsableServerAddress fails because the supposedly non-existing hostname "bar" "now" resolves to a real host-address.

The addresses "gugu.nonexistant.example.org, gaga.nonexistant.example.org" shouldn't be resolvable TM.

Original pull request: #229.
2014-10-01 09:44:48 +02:00
Christoph Strobl
161fd8c09d DATAMONGO-1049 - Check for explicitly declared language field.
We now check for an explicitly declared language field for setting language_override within a text index. Therefore the attribute (even if named with the reserved keyword language) has to be explicitly marked with @Language. Prior to this change having:

@Language String lang;
String language;

would have caused trouble when trying to resolve index structures as one cannot set language override to more than one property.

Original pull request: #224.
2014-09-25 12:43:46 +02:00
Oliver Gierke
dc037dfef6 DATAMONGO-1046 - After release cleanups. 2014-09-05 14:17:02 +02:00
Spring Buildmaster
c41653f9da DATAMONGO-1046 - Prepare next development iteration. 2014-09-05 14:09:48 +02:00
182 changed files with 1985 additions and 11801 deletions

View File

@@ -1,22 +0,0 @@
language: java
jdk:
- oraclejdk8
services:
- mongodb
env:
matrix:
- PROFILE=ci
- PROFILE=mongo-next
sudo: false
cache:
directories:
- $HOME/.m2
install: true
script: "mvn clean dependency:list test -P${PROFILE} -Dsort"

22
pom.xml
View File

@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.8.0.M1</version>
<version>1.6.5.BUILD-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Spring Data MongoDB</name>
@@ -15,7 +15,7 @@
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>1.7.0.M1</version>
<version>1.5.5.BUILD-SNAPSHOT</version>
</parent>
<modules>
@@ -28,9 +28,9 @@
<properties>
<project.type>multi</project.type>
<dist.id>spring-data-mongodb</dist.id>
<springdata.commons>1.11.0.M1</springdata.commons>
<mongo>2.13.0</mongo>
<mongo.osgi>2.13.0</mongo.osgi>
<springdata.commons>1.9.5.BUILD-SNAPSHOT</springdata.commons>
<mongo>2.12.5</mongo>
<mongo.osgi>2.12.5</mongo.osgi>
</properties>
<developers>
@@ -123,14 +123,14 @@
<id>mongo3</id>
<properties>
<mongo>3.0.0</mongo>
<mongo>3.0.2</mongo>
</properties>
</profile>
<profile>
<id>mongo3-next</id>
<id>mongo-3-next</id>
<properties>
<mongo>3.0.0-SNAPSHOT</mongo>
</properties>
@@ -156,15 +156,15 @@
<repositories>
<repository>
<id>spring-libs-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
<id>spring-libs-snapshot</id>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-plugins-release</id>
<url>https://repo.spring.io/plugins-release</url>
<url>http://repo.spring.io/plugins-release</url>
</pluginRepository>
</pluginRepositories>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.8.0.M1</version>
<version>1.6.5.BUILD-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -48,7 +48,7 @@
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.8.0.M1</version>
<version>1.6.5.BUILD-SNAPSHOT</version>
</dependency>
<dependency>

View File

@@ -13,7 +13,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.8.0.M1</version>
<version>1.6.5.BUILD-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.8.0.M1</version>
<version>1.6.5.BUILD-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.8.0.M1</version>
<version>1.6.5.BUILD-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -138,20 +138,6 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.threeten</groupId>
<artifactId>threetenbp</artifactId>
<version>${threetenbp}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
@@ -165,13 +151,6 @@
<version>${equalsverifier}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -46,7 +46,6 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
/**
* Base class for Spring Data MongoDB configuration using JavaConfig.
@@ -55,7 +54,6 @@ import com.mongodb.MongoClient;
* @author Oliver Gierke
* @author Thomas Darimont
* @author Ryan Tenney
* @author Christoph Strobl
*/
@Configuration
public abstract class AbstractMongoConfiguration {
@@ -72,10 +70,7 @@ public abstract class AbstractMongoConfiguration {
* returned by {@link #getDatabaseName()} later on effectively.
*
* @return
* @deprecated since 1.7. {@link MongoClient} should hold authentication data within
* {@link MongoClient#getCredentialsList()}
*/
@Deprecated
protected String getAuthenticationDatabaseName() {
return null;
}
@@ -134,10 +129,7 @@ public abstract class AbstractMongoConfiguration {
* be used.
*
* @return
* @deprecated since 1.7. {@link MongoClient} should hold authentication data within
* {@link MongoClient#getCredentialsList()}
*/
@Deprecated
protected UserCredentials getUserCredentials() {
return null;
}

View File

@@ -1,85 +0,0 @@
/*
* Copyright 2015 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.mongodb.config;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.config.BeanComponentDefinitionBuilder;
import org.springframework.data.config.ParsingUtils;
import org.springframework.data.mongodb.core.MongoClientFactoryBean;
import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
/**
* Parser for {@code mongo-client} definitions.
*
* @author Christoph Strobl
* @since 1.7
*/
public class MongoClientParser implements BeanDefinitionParser {
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
*/
public BeanDefinition parse(Element element, ParserContext parserContext) {
Object source = parserContext.extractSource(element);
String id = element.getAttribute("id");
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MongoClientFactoryBean.class);
ParsingUtils.setPropertyValue(builder, element, "port", "port");
ParsingUtils.setPropertyValue(builder, element, "host", "host");
ParsingUtils.setPropertyValue(builder, element, "credentials", "credentials");
MongoParsingUtils.parseMongoClientOptions(element, builder);
MongoParsingUtils.parseReplicaSet(element, builder);
String defaultedId = StringUtils.hasText(id) ? id : BeanNames.MONGO_BEAN_NAME;
parserContext.pushContainingComponent(new CompositeComponentDefinition("Mongo", source));
BeanComponentDefinition mongoComponent = helper.getComponent(builder, defaultedId);
parserContext.registerBeanComponent(mongoComponent);
BeanComponentDefinition serverAddressPropertyEditor = helper.getComponent(MongoParsingUtils
.getServerAddressPropertyEditorBuilder());
parserContext.registerBeanComponent(serverAddressPropertyEditor);
BeanComponentDefinition writeConcernEditor = helper.getComponent(MongoParsingUtils
.getWriteConcernPropertyEditorBuilder());
parserContext.registerBeanComponent(writeConcernEditor);
BeanComponentDefinition readPreferenceEditor = helper.getComponent(MongoParsingUtils
.getReadPreferencePropertyEditorBuilder());
parserContext.registerBeanComponent(readPreferenceEditor);
BeanComponentDefinition credentialsEditor = helper.getComponent(MongoParsingUtils
.getMongoCredentialPropertyEditor());
parserContext.registerBeanComponent(credentialsEditor);
parserContext.popAndRegisterContainingComponent();
return mongoComponent.getBeanDefinition();
}
}

View File

@@ -1,132 +0,0 @@
/*
* Copyright 2015 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.mongodb.config;
import java.beans.PropertyEditorSupport;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.springframework.util.StringUtils;
import com.mongodb.MongoCredential;
/**
* Parse a {@link String} to a Collection of {@link MongoCredential}.
*
* @author Christoph Strobl
* @since 1.7
*/
public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
private static final String AUTH_MECHANISM_KEY = "uri.authMechanism";
private static final String USERNAME_PASSWORD_DELIMINATOR = ":";
private static final String DATABASE_DELIMINATOR = "@";
private static final String OPTIONS_DELIMINATOR = "?";
private static final String OPTION_VALUE_DELIMINATOR = "&";
/*
* (non-Javadoc)
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
*/
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (!StringUtils.hasText(text)) {
return;
}
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
for (String credentialString : text.split(",")) {
if (!text.contains(USERNAME_PASSWORD_DELIMINATOR) || !text.contains(DATABASE_DELIMINATOR)) {
throw new IllegalArgumentException("Credentials need to be in format 'username:password@database'!");
}
String[] userNameAndPassword = extractUserNameAndPassword(credentialString);
String database = extractDB(credentialString);
Properties options = extractOptions(credentialString);
if (!options.isEmpty()) {
if (options.containsKey(AUTH_MECHANISM_KEY)) {
String authMechanism = options.getProperty(AUTH_MECHANISM_KEY);
if (MongoCredential.GSSAPI_MECHANISM.equals(authMechanism)) {
credentials.add(MongoCredential.createGSSAPICredential(userNameAndPassword[0]));
} else if (MongoCredential.MONGODB_CR_MECHANISM.equals(authMechanism)) {
credentials.add(MongoCredential.createMongoCRCredential(userNameAndPassword[0], database,
userNameAndPassword[1].toCharArray()));
} else if (MongoCredential.MONGODB_X509_MECHANISM.equals(authMechanism)) {
credentials.add(MongoCredential.createMongoX509Credential(userNameAndPassword[0]));
} else if (MongoCredential.PLAIN_MECHANISM.equals(authMechanism)) {
credentials.add(MongoCredential.createPlainCredential(userNameAndPassword[0], database,
userNameAndPassword[1].toCharArray()));
} else if (MongoCredential.SCRAM_SHA_1_MECHANISM.equals(authMechanism)) {
credentials.add(MongoCredential.createScramSha1Credential(userNameAndPassword[0], database,
userNameAndPassword[1].toCharArray()));
} else {
throw new IllegalArgumentException(String.format(
"Cannot create MongoCredentials for unknown auth mechanism '%s'!", authMechanism));
}
}
} else {
credentials.add(MongoCredential.createCredential(userNameAndPassword[0], database,
userNameAndPassword[1].toCharArray()));
}
}
setValue(credentials);
}
private static String[] extractUserNameAndPassword(String text) {
int dbSeperationIndex = text.lastIndexOf(DATABASE_DELIMINATOR);
String userNameAndPassword = text.substring(0, dbSeperationIndex);
return userNameAndPassword.split(USERNAME_PASSWORD_DELIMINATOR);
}
private static String extractDB(String text) {
int dbSeperationIndex = text.lastIndexOf(DATABASE_DELIMINATOR);
String tmp = text.substring(dbSeperationIndex + 1);
int optionsSeperationIndex = tmp.lastIndexOf(OPTIONS_DELIMINATOR);
return optionsSeperationIndex > -1 ? tmp.substring(0, optionsSeperationIndex) : tmp;
}
private static Properties extractOptions(String text) {
int optionsSeperationIndex = text.lastIndexOf(OPTIONS_DELIMINATOR);
int dbSeperationIndex = text.lastIndexOf(OPTIONS_DELIMINATOR);
if (optionsSeperationIndex == -1 || dbSeperationIndex > optionsSeperationIndex) {
return new Properties();
}
Properties properties = new Properties();
for (String option : text.substring(optionsSeperationIndex + 1).split(OPTION_VALUE_DELIMINATOR)) {
String[] optionArgs = option.split("=");
properties.put(optionArgs[0], optionArgs[1]);
}
return properties;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 by the original author(s).
* Copyright 2011-2014 by the original author(s).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,7 +34,6 @@ import org.springframework.util.StringUtils;
import org.w3c.dom.Element;
import com.mongodb.Mongo;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoURI;
/**
@@ -43,7 +42,6 @@ import com.mongodb.MongoURI;
* @author Jon Brisbin
* @author Oliver Gierke
* @author Thomas Darimont
* @author Christoph Strobl
*/
public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
@@ -66,28 +64,29 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
@Override
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
// Common setup
BeanDefinitionBuilder dbFactoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(SimpleMongoDbFactory.class);
setPropertyValue(dbFactoryBuilder, element, "write-concern", "writeConcern");
BeanDefinition mongoUri = getMongoUri(element);
if (mongoUri != null) {
if (element.getAttributes().getLength() >= 2 && !element.hasAttribute("write-concern")) {
parserContext.getReaderContext().error("Configure either Mongo URI or details individually!",
parserContext.extractSource(element));
}
dbFactoryBuilder.addConstructorArgValue(mongoUri);
return getSourceBeanDefinition(dbFactoryBuilder, parserContext, element);
}
Object source = parserContext.extractSource(element);
BeanComponentDefinitionBuilder helper = new BeanComponentDefinitionBuilder(element, parserContext);
String uri = element.getAttribute("uri");
String mongoRef = element.getAttribute("mongo-ref");
String dbname = element.getAttribute("dbname");
BeanDefinition userCredentials = getUserCredentialsBeanDefinition(element, parserContext);
// Common setup
BeanDefinitionBuilder dbFactoryBuilder = BeanDefinitionBuilder.genericBeanDefinition(SimpleMongoDbFactory.class);
setPropertyValue(dbFactoryBuilder, element, "write-concern", "writeConcern");
if (StringUtils.hasText(uri)) {
if (StringUtils.hasText(mongoRef) || StringUtils.hasText(dbname) || userCredentials != null) {
parserContext.getReaderContext().error("Configure either Mongo URI or details individually!", source);
}
dbFactoryBuilder.addConstructorArgValue(getMongoUri(uri));
return getSourceBeanDefinition(dbFactoryBuilder, parserContext, element);
}
// Defaulting
if (StringUtils.hasText(mongoRef)) {
dbFactoryBuilder.addConstructorArgReference(mongoRef);
@@ -148,24 +147,14 @@ public class MongoDbFactoryParser extends AbstractBeanDefinitionParser {
}
/**
* Creates a {@link BeanDefinition} for a {@link MongoURI} or {@link MongoClientURI} depending on configured
* attributes.
* Creates a {@link BeanDefinition} for a {@link MongoURI}.
*
* @param element must not be {@literal null}.
* @return {@literal null} in case no client-/uri defined.
* @param uri
* @return
*/
private BeanDefinition getMongoUri(Element element) {
private BeanDefinition getMongoUri(String uri) {
boolean hasClientUri = element.hasAttribute("client-uri");
if (!hasClientUri && !element.hasAttribute("uri")) {
return null;
}
Class<?> type = hasClientUri ? MongoClientURI.class : MongoURI.class;
String uri = hasClientUri ? element.getAttribute("client-uri") : element.getAttribute("uri");
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(type);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MongoURI.class);
builder.addConstructorArgValue(uri);
return builder.getBeanDefinition();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -22,7 +22,6 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
*
* @author Oliver Gierke
* @author Martin Baumgartner
* @author Christoph Strobl
*/
public class MongoNamespaceHandler extends NamespaceHandlerSupport {
@@ -34,7 +33,6 @@ public class MongoNamespaceHandler extends NamespaceHandlerSupport {
registerBeanDefinitionParser("mapping-converter", new MappingMongoConverterParser());
registerBeanDefinitionParser("mongo", new MongoParser());
registerBeanDefinitionParser("mongo-client", new MongoClientParser());
registerBeanDefinitionParser("db-factory", new MongoDbFactoryParser());
registerBeanDefinitionParser("jmx", new MongoJmxParser());
registerBeanDefinitionParser("auditing", new MongoAuditingBeanDefinitionParser());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -15,10 +15,14 @@
*/
package org.springframework.data.mongodb.config;
import java.util.Map;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.CustomEditorConfigurer;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.config.BeanComponentDefinitionBuilder;
@@ -32,7 +36,6 @@ import org.w3c.dom.Element;
*
* @author Mark Pollack
* @author Oliver Gierke
* @author Christoph Strobl
*/
public class MongoParser implements BeanDefinitionParser {
@@ -61,8 +64,7 @@ public class MongoParser implements BeanDefinitionParser {
BeanComponentDefinition mongoComponent = helper.getComponent(builder, defaultedId);
parserContext.registerBeanComponent(mongoComponent);
BeanComponentDefinition serverAddressPropertyEditor = helper.getComponent(MongoParsingUtils
.getServerAddressPropertyEditorBuilder());
BeanComponentDefinition serverAddressPropertyEditor = helper.getComponent(registerServerAddressPropertyEditor());
parserContext.registerBeanComponent(serverAddressPropertyEditor);
BeanComponentDefinition writeConcernPropertyEditor = helper.getComponent(MongoParsingUtils
.getWriteConcernPropertyEditorBuilder());
@@ -73,4 +75,19 @@ public class MongoParser implements BeanDefinitionParser {
return mongoComponent.getBeanDefinition();
}
/**
* One should only register one bean definition but want to have the convenience of using
* AbstractSingleBeanDefinitionParser but have the side effect of registering a 'default' property editor with the
* container.
*/
private BeanDefinitionBuilder registerServerAddressPropertyEditor() {
Map<String, String> customEditors = new ManagedMap<String, String>();
customEditors.put("com.mongodb.ServerAddress[]",
"org.springframework.data.mongodb.config.ServerAddressPropertyEditor");
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
builder.addPropertyValue("customEditors", customEditors);
return builder;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2013 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.
@@ -24,7 +24,6 @@ import org.springframework.beans.factory.config.CustomEditorConfigurer;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.data.mongodb.core.MongoClientOptionsFactoryBean;
import org.springframework.data.mongodb.core.MongoOptionsFactoryBean;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
@@ -34,13 +33,13 @@ import org.w3c.dom.Element;
*
* @author Mark Pollack
* @author Oliver Gierke
* @author Thomas Darimont
* @author Christoph Strobl
* @author Thomas Darimont
*/
@SuppressWarnings("deprecation")
abstract class MongoParsingUtils {
private MongoParsingUtils() {}
private MongoParsingUtils() {
}
/**
* Parses the mongo replica-set element.
@@ -55,14 +54,12 @@ abstract class MongoParsingUtils {
}
/**
* Parses the {@code mongo:options} sub-element. Populates the given attribute factory with the proper attributes.
* Parses the mongo:options sub-element. Populates the given attribute factory with the proper attributes.
*
* @return true if parsing actually occured, {@literal false} otherwise
* @return true if parsing actually occured, false otherwise
*/
static boolean parseMongoOptions(Element element, BeanDefinitionBuilder mongoBuilder) {
Element optionsElement = DomUtils.getChildElementByTagName(element, "options");
if (optionsElement == null) {
return false;
}
@@ -83,58 +80,13 @@ abstract class MongoParsingUtils {
setPropertyValue(optionsDefBuilder, optionsElement, "write-timeout", "writeTimeout");
setPropertyValue(optionsDefBuilder, optionsElement, "write-fsync", "writeFsync");
setPropertyValue(optionsDefBuilder, optionsElement, "slave-ok", "slaveOk");
setPropertyValue(optionsDefBuilder, optionsElement, "ssl", "ssl");
setPropertyReference(optionsDefBuilder, optionsElement, "ssl-socket-factory-ref", "sslSocketFactory");
setPropertyValue(optionsDefBuilder, optionsElement, "ssl", "ssl");
setPropertyReference(optionsDefBuilder, optionsElement, "ssl-socket-factory-ref", "sslSocketFactory");
mongoBuilder.addPropertyValue("mongoOptions", optionsDefBuilder.getBeanDefinition());
return true;
}
/**
* Parses the {@code mongo:client-options} sub-element. Populates the given attribute factory with the proper
* attributes.
*
* @param element must not be {@literal null}.
* @param mongoClientBuilder must not be {@literal null}.
* @return
* @since 1.7
*/
public static boolean parseMongoClientOptions(Element element, BeanDefinitionBuilder mongoClientBuilder) {
Element optionsElement = DomUtils.getChildElementByTagName(element, "client-options");
if (optionsElement == null) {
return false;
}
BeanDefinitionBuilder clientOptionsDefBuilder = BeanDefinitionBuilder
.genericBeanDefinition(MongoClientOptionsFactoryBean.class);
setPropertyValue(clientOptionsDefBuilder, optionsElement, "description", "description");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "min-connections-per-host", "minConnectionsPerHost");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "connections-per-host", "connectionsPerHost");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "threads-allowed-to-block-for-connection-multiplier",
"threadsAllowedToBlockForConnectionMultiplier");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-wait-time", "maxWaitTime");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-connection-idle-time", "maxConnectionIdleTime");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "max-connection-life-time", "maxConnectionLifeTime");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "connect-timeout", "connectTimeout");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "socket-timeout", "socketTimeout");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "socket-keep-alive", "socketKeepAlive");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "read-preference", "readPreference");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "write-concern", "writeConcern");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-frequency", "heartbeatFrequency");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "min-heartbeat-frequency", "minHeartbeatFrequency");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-connect-timeout", "heartbeatConnectTimeout");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-socket-timeout", "heartbeatSocketTimeout");
setPropertyValue(clientOptionsDefBuilder, optionsElement, "ssl", "ssl");
setPropertyReference(clientOptionsDefBuilder, optionsElement, "ssl-socket-factory-ref", "sslSocketFactory");
mongoClientBuilder.addPropertyValue("mongoClientOptions", clientOptionsDefBuilder.getBeanDefinition());
return true;
}
/**
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
* {@link WriteConcernPropertyEditor}.
@@ -151,56 +103,4 @@ abstract class MongoParsingUtils {
return builder;
}
/**
* One should only register one bean definition but want to have the convenience of using
* AbstractSingleBeanDefinitionParser but have the side effect of registering a 'default' property editor with the
* container.
*/
static BeanDefinitionBuilder getServerAddressPropertyEditorBuilder() {
Map<String, String> customEditors = new ManagedMap<String, String>();
customEditors.put("com.mongodb.ServerAddress[]",
"org.springframework.data.mongodb.config.ServerAddressPropertyEditor");
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
builder.addPropertyValue("customEditors", customEditors);
return builder;
}
/**
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
* {@link ReadPreferencePropertyEditor}.
*
* @return
* @since 1.7
*/
static BeanDefinitionBuilder getReadPreferencePropertyEditorBuilder() {
Map<String, Class<?>> customEditors = new ManagedMap<String, Class<?>>();
customEditors.put("com.mongodb.ReadPreference", ReadPreferencePropertyEditor.class);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
builder.addPropertyValue("customEditors", customEditors);
return builder;
}
/**
* Returns the {@link BeanDefinitionBuilder} to build a {@link BeanDefinition} for a
* {@link MongoCredentialPropertyEditor}.
*
* @return
* @since 1.7
*/
static BeanDefinitionBuilder getMongoCredentialPropertyEditor() {
Map<String, Class<?>> customEditors = new ManagedMap<String, Class<?>>();
customEditors.put("com.mongodb.MongoCredential[]", MongoCredentialPropertyEditor.class);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(CustomEditorConfigurer.class);
builder.addPropertyValue("customEditors", customEditors);
return builder;
}
}

View File

@@ -1,66 +0,0 @@
/*
* Copyright 2015 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.mongodb.config;
import java.beans.PropertyEditorSupport;
import com.mongodb.ReadPreference;
/**
* Parse a {@link String} to a {@link ReadPreference}.
*
* @author Christoph Strobl
* @since 1.7
*/
public class ReadPreferencePropertyEditor extends PropertyEditorSupport {
/*
* (non-Javadoc)
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
*/
@Override
public void setAsText(String readPreferenceString) throws IllegalArgumentException {
if (readPreferenceString == null) {
return;
}
ReadPreference preference = null;
try {
preference = ReadPreference.valueOf(readPreferenceString);
} catch (IllegalArgumentException ex) {
// ignore this one and try to map it differently
}
if (preference != null) {
setValue(preference);
} else if ("PRIMARY".equalsIgnoreCase(readPreferenceString)) {
setValue(ReadPreference.primary());
} else if ("PRIMARY_PREFERRED".equalsIgnoreCase(readPreferenceString)) {
setValue(ReadPreference.primaryPreferred());
} else if ("SECONDARY".equalsIgnoreCase(readPreferenceString)) {
setValue(ReadPreference.secondary());
} else if ("SECONDARY_PREFERRED".equalsIgnoreCase(readPreferenceString)) {
setValue(ReadPreference.secondaryPreferred());
} else if ("NEAREST".equalsIgnoreCase(readPreferenceString)) {
setValue(ReadPreference.nearest());
} else {
throw new IllegalArgumentException(String.format("Cannot find matching ReadPreference for %s",
readPreferenceString));
}
}
}

View File

@@ -25,7 +25,7 @@ import com.mongodb.DBCursor;
interface CursorPreparer {
/**
* Prepare the given cursor (apply limits, skips and so on). Returns th eprepared cursor.
* Prepare the given cursor (apply limits, skips and so on). Returns the prepared cursor.
*
* @param cursor
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -73,9 +73,9 @@ public class DefaultIndexOperations implements IndexOperations {
public Object doInCollection(DBCollection collection) throws MongoException, DataAccessException {
DBObject indexOptions = indexDefinition.getIndexOptions();
if (indexOptions != null) {
collection.createIndex(indexDefinition.getIndexKeys(), indexOptions);
collection.ensureIndex(indexDefinition.getIndexKeys(), indexOptions);
} else {
collection.createIndex(indexDefinition.getIndexKeys());
collection.ensureIndex(indexDefinition.getIndexKeys());
}
return null;
}
@@ -108,12 +108,10 @@ public class DefaultIndexOperations implements IndexOperations {
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.IndexOperations#resetIndexCache()
*/
@Deprecated
public void resetIndexCache() {
mongoOperations.execute(collectionName, new CollectionCallback<Void>() {
public Void doInCollection(DBCollection collection) throws MongoException, DataAccessException {
ReflectiveDBCollectionInvoker.resetIndexCache(collection);
collection.resetIndexCache();
return null;
}
});

View File

@@ -1,188 +0,0 @@
/*
* Copyright 2014-2015 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.mongodb.core;
import static java.util.UUID.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.query.Query.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bson.types.ObjectId;
import org.springframework.dao.DataAccessException;
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import com.mongodb.DB;
import com.mongodb.MongoException;
/**
* Default implementation of {@link ScriptOperations} capable of saving and executing {@link ServerSideJavaScript}.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
class DefaultScriptOperations implements ScriptOperations {
private static final String SCRIPT_COLLECTION_NAME = "system.js";
private static final String SCRIPT_NAME_PREFIX = "func_";
private final MongoOperations mongoOperations;
/**
* Creates new {@link DefaultScriptOperations} using given {@link MongoOperations}.
*
* @param mongoOperations must not be {@literal null}.
*/
public DefaultScriptOperations(MongoOperations mongoOperations) {
Assert.notNull(mongoOperations, "MongoOperations must not be null!");
this.mongoOperations = mongoOperations;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ScriptOperations#register(org.springframework.data.mongodb.core.script.ExecutableMongoScript)
*/
@Override
public NamedMongoScript register(ExecutableMongoScript script) {
return register(new NamedMongoScript(generateScriptName(), script));
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ScriptOperations#register(org.springframework.data.mongodb.core.script.NamedMongoScript)
*/
@Override
public NamedMongoScript register(NamedMongoScript script) {
Assert.notNull(script, "Script must not be null!");
mongoOperations.save(script, SCRIPT_COLLECTION_NAME);
return script;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ScriptOperations#execute(org.springframework.data.mongodb.core.script.ExecutableMongoScript, java.lang.Object[])
*/
@Override
public Object execute(final ExecutableMongoScript script, final Object... args) {
Assert.notNull(script, "Script must not be null!");
return mongoOperations.execute(new DbCallback<Object>() {
@Override
public Object doInDB(DB db) throws MongoException, DataAccessException {
return db.eval(script.getCode(), convertScriptArgs(args));
}
});
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ScriptOperations#call(java.lang.String, java.lang.Object[])
*/
@Override
public Object call(final String scriptName, final Object... args) {
Assert.hasText(scriptName, "ScriptName must not be null or empty!");
return mongoOperations.execute(new DbCallback<Object>() {
@Override
public Object doInDB(DB db) throws MongoException, DataAccessException {
return db.eval(String.format("%s(%s)", scriptName, convertAndJoinScriptArgs(args)));
}
});
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ScriptOperations#exists(java.lang.String)
*/
@Override
public boolean exists(String scriptName) {
Assert.hasText(scriptName, "ScriptName must not be null or empty!");
return mongoOperations.exists(query(where("name").is(scriptName)), NamedMongoScript.class, SCRIPT_COLLECTION_NAME);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ScriptOperations#getScriptNames()
*/
@Override
public Set<String> getScriptNames() {
List<NamedMongoScript> scripts = mongoOperations.findAll(NamedMongoScript.class, SCRIPT_COLLECTION_NAME);
if (CollectionUtils.isEmpty(scripts)) {
return Collections.emptySet();
}
Set<String> scriptNames = new HashSet<String>();
for (NamedMongoScript script : scripts) {
scriptNames.add(script.getName());
}
return scriptNames;
}
private Object[] convertScriptArgs(Object... args) {
if (ObjectUtils.isEmpty(args)) {
return args;
}
List<Object> convertedValues = new ArrayList<Object>(args.length);
for (Object arg : args) {
convertedValues.add(arg instanceof String ? String.format("'%s'", arg) : this.mongoOperations.getConverter()
.convertToMongoType(arg));
}
return convertedValues.toArray();
}
private String convertAndJoinScriptArgs(Object... args) {
return ObjectUtils.isEmpty(args) ? "" : StringUtils.arrayToCommaDelimitedString(convertScriptArgs(args));
}
/**
* Generate a valid name for the {@literal JavaScript}. MongoDB requires an id of type String for scripts. Calling
* scripts having {@link ObjectId} as id fails. Therefore we create a random UUID without {@code -} (as this won't
* work) an prefix the result with {@link #SCRIPT_NAME_PREFIX}.
*
* @return
*/
private static String generateScriptName() {
return SCRIPT_NAME_PREFIX + randomUUID().toString().replaceAll("-", "");
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright 2015 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.mongodb.core;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.core.geo.GeoJsonModule;
import org.springframework.data.web.config.SpringDataWebConfigurationMixin;
/**
* Configuration class to expose {@link GeoJsonModule} as a Spring bean.
*
* @author Oliver Gierke
*/
@SpringDataWebConfigurationMixin
public class GeoJsonConfiguration {
@Bean
public GeoJsonModule geoJsonModule() {
return new GeoJsonModule();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011 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.
@@ -20,12 +20,12 @@ import java.util.List;
import org.springframework.data.mongodb.core.index.IndexDefinition;
import org.springframework.data.mongodb.core.index.IndexInfo;
/**
* Index operations on a collection.
*
* @author Mark Pollack
* @author Oliver Gierke
* @author Christoph Strobl
*/
public interface IndexOperations {
@@ -51,11 +51,7 @@ public interface IndexOperations {
/**
* Clears all indices that have not yet been applied to this collection.
*
* @deprecated since 1.7. The MongoDB Java driver version 3.0 does no longer support reseting the index cache.
* @throws {@link UnsupportedOperationException} when used with MongoDB Java driver version 3.0.
*/
@Deprecated
void resetIndexCache();
/**

View File

@@ -49,7 +49,7 @@ public class MongoAction {
* @param collectionName the collection name, must not be {@literal null} or empty.
* @param entityType the POJO that is being operated against
* @param document the converted DBObject from the POJO or Spring Update object
* @param query the converted DBOjbect from the Spring Query object
* @param query the converted DBObject from the Spring Query object
*/
public MongoAction(WriteConcern defaultWriteConcern, MongoActionOperation mongoActionOperation,
String collectionName, Class<?> entityType, DBObject document, DBObject query) {

View File

@@ -1,189 +0,0 @@
/*
* Copyright 2015 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.mongodb.core;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
/**
* Convenient factory for configuring MongoDB.
*
* @author Christoph Strobl
* @since 1.7
*/
public class MongoClientFactoryBean extends AbstractFactoryBean<Mongo> implements PersistenceExceptionTranslator {
private static final PersistenceExceptionTranslator DEFAULT_EXCEPTION_TRANSLATOR = new MongoExceptionTranslator();
private MongoClientOptions mongoClientOptions;
private String host;
private Integer port;
private List<ServerAddress> replicaSetSeeds;
private List<MongoCredential> credentials;
private PersistenceExceptionTranslator exceptionTranslator = DEFAULT_EXCEPTION_TRANSLATOR;
/**
* Set the {@link MongoClientOptions} to be used when creating {@link MongoClient}.
*
* @param mongoClientOptions
*/
public void setMongoClientOptions(MongoClientOptions mongoClientOptions) {
this.mongoClientOptions = mongoClientOptions;
}
/**
* Set the list of credentials to be used when creating {@link MongoClient}.
*
* @param credentials can be {@literal null}.
*/
public void setCredentials(MongoCredential[] credentials) {
this.credentials = filterNonNullElementsAsList(credentials);
}
/**
* Set the list of {@link ServerAddress} to build up a replica set for.
*
* @param replicaSetSeeds can be {@literal null}.
*/
public void setReplicaSetSeeds(ServerAddress[] replicaSetSeeds) {
this.replicaSetSeeds = filterNonNullElementsAsList(replicaSetSeeds);
}
/**
* Configures the host to connect to.
*
* @param host
*/
public void setHost(String host) {
this.host = host;
}
/**
* Configures the port to connect to.
*
* @param port
*/
public void setPort(int port) {
this.port = port;
}
/**
* Configures the {@link PersistenceExceptionTranslator} to use.
*
* @param exceptionTranslator
*/
public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) {
this.exceptionTranslator = exceptionTranslator == null ? DEFAULT_EXCEPTION_TRANSLATOR : exceptionTranslator;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public Class<? extends Mongo> getObjectType() {
return Mongo.class;
}
/*
* (non-Javadoc)
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
*/
public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
return exceptionTranslator.translateExceptionIfPossible(ex);
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
*/
@Override
protected Mongo createInstance() throws Exception {
if (mongoClientOptions == null) {
mongoClientOptions = MongoClientOptions.builder().build();
}
if (credentials == null) {
credentials = Collections.emptyList();
}
return createMongoClient();
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.config.AbstractFactoryBean#destroyInstance(java.lang.Object)
*/
@Override
protected void destroyInstance(Mongo instance) throws Exception {
instance.close();
}
private MongoClient createMongoClient() throws UnknownHostException {
if (!CollectionUtils.isEmpty(replicaSetSeeds)) {
return new MongoClient(replicaSetSeeds, credentials, mongoClientOptions);
}
return new MongoClient(createConfiguredOrDefaultServerAddress(), credentials, mongoClientOptions);
}
private ServerAddress createConfiguredOrDefaultServerAddress() throws UnknownHostException {
ServerAddress defaultAddress = new ServerAddress();
return new ServerAddress(StringUtils.hasText(host) ? host : defaultAddress.getHost(),
port != null ? port.intValue() : defaultAddress.getPort());
}
/**
* Returns the given array as {@link List} with all {@literal null} elements removed.
*
* @param elements the elements to filter <T>, can be {@literal null}.
* @return a new unmodifiable {@link List#} from the given elements without {@literal null}s.
*/
private static <T> List<T> filterNonNullElementsAsList(T[] elements) {
if (elements == null) {
return Collections.emptyList();
}
List<T> candidateElements = new ArrayList<T>();
for (T element : elements) {
if (element != null) {
candidateElements.add(element);
}
}
return Collections.unmodifiableList(candidateElements);
}
}

View File

@@ -1,295 +0,0 @@
/*
* Copyright 2015 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.mongodb.core;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.data.mongodb.MongoDbFactory;
import com.mongodb.DBDecoderFactory;
import com.mongodb.DBEncoderFactory;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.ReadPreference;
import com.mongodb.WriteConcern;
/**
* A factory bean for construction of a {@link MongoClientOptions} instance.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
public class MongoClientOptionsFactoryBean extends AbstractFactoryBean<MongoClientOptions> {
private static final MongoClientOptions DEFAULT_MONGO_OPTIONS = MongoClientOptions.builder().build();
private String description = DEFAULT_MONGO_OPTIONS.getDescription();
private int minConnectionsPerHost = DEFAULT_MONGO_OPTIONS.getMinConnectionsPerHost();
private int connectionsPerHost = DEFAULT_MONGO_OPTIONS.getConnectionsPerHost();
private int threadsAllowedToBlockForConnectionMultiplier = DEFAULT_MONGO_OPTIONS
.getThreadsAllowedToBlockForConnectionMultiplier();
private int maxWaitTime = DEFAULT_MONGO_OPTIONS.getMaxWaitTime();
private int maxConnectionIdleTime = DEFAULT_MONGO_OPTIONS.getMaxConnectionIdleTime();
private int maxConnectionLifeTime = DEFAULT_MONGO_OPTIONS.getMaxConnectionLifeTime();
private int connectTimeout = DEFAULT_MONGO_OPTIONS.getConnectTimeout();
private int socketTimeout = DEFAULT_MONGO_OPTIONS.getSocketTimeout();
private boolean socketKeepAlive = DEFAULT_MONGO_OPTIONS.isSocketKeepAlive();
private ReadPreference readPreference = DEFAULT_MONGO_OPTIONS.getReadPreference();
private DBDecoderFactory dbDecoderFactory = DEFAULT_MONGO_OPTIONS.getDbDecoderFactory();
private DBEncoderFactory dbEncoderFactory = DEFAULT_MONGO_OPTIONS.getDbEncoderFactory();
private WriteConcern writeConcern = DEFAULT_MONGO_OPTIONS.getWriteConcern();
private SocketFactory socketFactory = DEFAULT_MONGO_OPTIONS.getSocketFactory();
private boolean cursorFinalizerEnabled = DEFAULT_MONGO_OPTIONS.isCursorFinalizerEnabled();
private boolean alwaysUseMBeans = DEFAULT_MONGO_OPTIONS.isAlwaysUseMBeans();
private int heartbeatFrequency = DEFAULT_MONGO_OPTIONS.getHeartbeatFrequency();
private int minHeartbeatFrequency = DEFAULT_MONGO_OPTIONS.getMinHeartbeatFrequency();
private int heartbeatConnectTimeout = DEFAULT_MONGO_OPTIONS.getHeartbeatConnectTimeout();
private int heartbeatSocketTimeout = DEFAULT_MONGO_OPTIONS.getHeartbeatSocketTimeout();
private String requiredReplicaSetName = DEFAULT_MONGO_OPTIONS.getRequiredReplicaSetName();
private boolean ssl;
private SSLSocketFactory sslSocketFactory;
/**
* Set the {@link MongoClient} description.
*
* @param description
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Set the minimum number of connections per host.
*
* @param minConnectionsPerHost
*/
public void setMinConnectionsPerHost(int minConnectionsPerHost) {
this.minConnectionsPerHost = minConnectionsPerHost;
}
/**
* Set the number of connections allowed per host. Will block if run out. Default is 10. System property
* {@code MONGO.POOLSIZE} can override
*
* @param connectionsPerHost
*/
public void setConnectionsPerHost(int connectionsPerHost) {
this.connectionsPerHost = connectionsPerHost;
}
/**
* Set the multiplier for connectionsPerHost for # of threads that can block. Default is 5. If connectionsPerHost is
* 10, and threadsAllowedToBlockForConnectionMultiplier is 5, then 50 threads can block more than that and an
* exception will be thrown.
*
* @param threadsAllowedToBlockForConnectionMultiplier
*/
public void setThreadsAllowedToBlockForConnectionMultiplier(int threadsAllowedToBlockForConnectionMultiplier) {
this.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
}
/**
* Set the max wait time of a blocking thread for a connection. Default is 12000 ms (2 minutes)
*
* @param maxWaitTime
*/
public void setMaxWaitTime(int maxWaitTime) {
this.maxWaitTime = maxWaitTime;
}
/**
* The maximum idle time for a pooled connection.
*
* @param maxConnectionIdleTime
*/
public void setMaxConnectionIdleTime(int maxConnectionIdleTime) {
this.maxConnectionIdleTime = maxConnectionIdleTime;
}
/**
* Set the maximum life time for a pooled connection.
*
* @param maxConnectionLifeTime
*/
public void setMaxConnectionLifeTime(int maxConnectionLifeTime) {
this.maxConnectionLifeTime = maxConnectionLifeTime;
}
/**
* Set the connect timeout in milliseconds. 0 is default and infinite.
*
* @param connectTimeout
*/
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
/**
* Set the socket timeout. 0 is default and infinite.
*
* @param socketTimeout
*/
public void setSocketTimeout(int socketTimeout) {
this.socketTimeout = socketTimeout;
}
/**
* Set the keep alive flag, controls whether or not to have socket keep alive timeout. Defaults to false.
*
* @param socketKeepAlive
*/
public void setSocketKeepAlive(boolean socketKeepAlive) {
this.socketKeepAlive = socketKeepAlive;
}
/**
* Set the {@link ReadPreference}.
*
* @param readPreference
*/
public void setReadPreference(ReadPreference readPreference) {
this.readPreference = readPreference;
}
/**
* Set the {@link WriteConcern} that will be the default value used when asking the {@link MongoDbFactory} for a DB
* object.
*
* @param writeConcern
*/
public void setWriteConcern(WriteConcern writeConcern) {
this.writeConcern = writeConcern;
}
/**
* @param socketFactory
*/
public void setSocketFactory(SocketFactory socketFactory) {
this.socketFactory = socketFactory;
}
/**
* Set the frequency that the driver will attempt to determine the current state of each server in the cluster.
*
* @param heartbeatFrequency
*/
public void setHeartbeatFrequency(int heartbeatFrequency) {
this.heartbeatFrequency = heartbeatFrequency;
}
/**
* In the event that the driver has to frequently re-check a server's availability, it will wait at least this long
* since the previous check to avoid wasted effort.
*
* @param minHeartbeatFrequency
*/
public void setMinHeartbeatFrequency(int minHeartbeatFrequency) {
this.minHeartbeatFrequency = minHeartbeatFrequency;
}
/**
* Set the connect timeout for connections used for the cluster heartbeat.
*
* @param heartbeatConnectTimeout
*/
public void setHeartbeatConnectTimeout(int heartbeatConnectTimeout) {
this.heartbeatConnectTimeout = heartbeatConnectTimeout;
}
/**
* Set the socket timeout for connections used for the cluster heartbeat.
*
* @param heartbeatSocketTimeout
*/
public void setHeartbeatSocketTimeout(int heartbeatSocketTimeout) {
this.heartbeatSocketTimeout = heartbeatSocketTimeout;
}
/**
* Configures the name of the replica set.
*
* @param requiredReplicaSetName
*/
public void setRequiredReplicaSetName(String requiredReplicaSetName) {
this.requiredReplicaSetName = requiredReplicaSetName;
}
/**
* This controls if the driver should us an SSL connection. Defaults to |@literal false}.
*
* @param ssl
*/
public void setSsl(boolean ssl) {
this.ssl = ssl;
}
/**
* Set the {@link SSLSocketFactory} to use for the {@literal SSL} connection. If none is configured here,
* {@link SSLSocketFactory#getDefault()} will be used.
*
* @param sslSocketFactory
*/
public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
this.sslSocketFactory = sslSocketFactory;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
*/
@Override
protected MongoClientOptions createInstance() throws Exception {
SocketFactory socketFactoryToUse = ssl ? (sslSocketFactory != null ? sslSocketFactory : SSLSocketFactory
.getDefault()) : this.socketFactory;
return MongoClientOptions.builder() //
.alwaysUseMBeans(this.alwaysUseMBeans) //
.connectionsPerHost(this.connectionsPerHost) //
.connectTimeout(connectTimeout) //
.cursorFinalizerEnabled(cursorFinalizerEnabled) //
.dbDecoderFactory(dbDecoderFactory) //
.dbEncoderFactory(dbEncoderFactory) //
.description(description) //
.heartbeatConnectTimeout(heartbeatConnectTimeout) //
.heartbeatFrequency(heartbeatFrequency) //
.heartbeatSocketTimeout(heartbeatSocketTimeout) //
.maxConnectionIdleTime(maxConnectionIdleTime) //
.maxConnectionLifeTime(maxConnectionLifeTime) //
.maxWaitTime(maxWaitTime) //
.minConnectionsPerHost(minConnectionsPerHost) //
.minHeartbeatFrequency(minHeartbeatFrequency) //
.readPreference(readPreference) //
.requiredReplicaSetName(requiredReplicaSetName) //
.socketFactory(socketFactoryToUse) //
.socketKeepAlive(socketKeepAlive) //
.socketTimeout(socketTimeout) //
.threadsAllowedToBlockForConnectionMultiplier(threadsAllowedToBlockForConnectionMultiplier) //
.writeConcern(writeConcern).build();
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
public Class<?> getObjectType() {
return MongoClientOptions.class;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2013 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.
@@ -18,13 +18,12 @@ package org.springframework.data.mongodb.core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.mongodb.util.MongoClientVersion;
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
import com.mongodb.DB;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
/**
* Helper class featuring helper methods for internal MongoDb classes. Mainly intended for internal use within the
@@ -35,7 +34,6 @@ import com.mongodb.MongoClient;
* @author Oliver Gierke
* @author Randy Watler
* @author Thomas Darimont
* @author Christoph Strobl
* @since 1.0
*/
public abstract class MongoDbUtils {
@@ -45,7 +43,9 @@ public abstract class MongoDbUtils {
/**
* Private constructor to prevent instantiation.
*/
private MongoDbUtils() {}
private MongoDbUtils() {
}
/**
* Obtains a {@link DB} connection for the given {@link Mongo} instance and database name
@@ -65,24 +65,11 @@ public abstract class MongoDbUtils {
* @param databaseName the database name, must not be {@literal null} or empty.
* @param credentials the credentials to use, must not be {@literal null}.
* @return the {@link DB} connection
* @deprecated since 1.7. The {@link MongoClient} itself should hold credentials within
* {@link MongoClient#getCredentialsList()}.
*/
@Deprecated
public static DB getDB(Mongo mongo, String databaseName, UserCredentials credentials) {
return getDB(mongo, databaseName, credentials, databaseName);
}
/**
* @param mongo
* @param databaseName
* @param credentials
* @param authenticationDatabaseName
* @return
* @deprecated since 1.7. The {@link MongoClient} itself should hold credentials within
* {@link MongoClient#getCredentialsList()}.
*/
@Deprecated
public static DB getDB(Mongo mongo, String databaseName, UserCredentials credentials,
String authenticationDatabaseName) {
@@ -122,9 +109,22 @@ public abstract class MongoDbUtils {
LOGGER.debug("Getting Mongo Database name=[{}]", databaseName);
DB db = mongo.getDB(databaseName);
boolean credentialsGiven = credentials.hasUsername() && credentials.hasPassword();
if (!(mongo instanceof MongoClient) && requiresAuthDbAuthentication(credentials)) {
ReflectiveDbInvoker.authenticate(mongo, db, credentials, authenticationDatabaseName);
DB authDb = databaseName.equals(authenticationDatabaseName) ? db : mongo.getDB(authenticationDatabaseName);
synchronized (authDb) {
if (credentialsGiven && !authDb.isAuthenticated()) {
String username = credentials.getUsername();
String password = credentials.hasPassword() ? credentials.getPassword() : null;
if (!authDb.authenticate(username, password == null ? null : password.toCharArray())) {
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName + "], "
+ credentials.toString(), databaseName, credentials);
}
}
}
// TX sync active, bind new database to thread
@@ -181,36 +181,16 @@ public abstract class MongoDbUtils {
* Perform actual closing of the Mongo DB object, catching and logging any cleanup exceptions thrown.
*
* @param db the DB to close (may be <code>null</code>)
* @deprecated since 1.7. The main use case for this method is to ensure that applications can read their own
* unacknowledged writes, but this is no longer so prevalent since the MongoDB Java driver version 3
* started defaulting to acknowledged writes.
*/
@Deprecated
public static void closeDB(DB db) {
if (db != null) {
LOGGER.debug("Closing Mongo DB object");
try {
ReflectiveDbInvoker.requestDone(db);
db.requestDone();
} catch (Throwable ex) {
LOGGER.debug("Unexpected exception on closing Mongo DB object", ex);
}
}
}
/**
* Check if credentials present. In case we're using a monog-java-driver version 3 or above we do not have the need
* for authentication as the auth data has to be provied within the MongoClient
*
* @param credentials
* @return
*/
private static boolean requiresAuthDbAuthentication(UserCredentials credentials) {
if (credentials == null || !credentials.hasUsername()) {
return false;
}
return !MongoClientVersion.isMongo3Driver();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2013 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.
@@ -15,21 +15,23 @@
*/
package org.springframework.data.mongodb.core;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.UncategorizedMongoDbException;
import org.springframework.util.ClassUtils;
import com.mongodb.MongoCursorNotFoundException;
import com.mongodb.MongoException;
import com.mongodb.MongoException.CursorNotFound;
import com.mongodb.MongoException.DuplicateKey;
import com.mongodb.MongoException.Network;
import com.mongodb.MongoInternalException;
import com.mongodb.MongoServerSelectionException;
import com.mongodb.MongoSocketException;
import com.mongodb.MongoTimeoutException;
/**
* Simple {@link PersistenceExceptionTranslator} for Mongo. Convert the given runtime exception to an appropriate
@@ -38,23 +40,9 @@ import com.mongodb.MongoException;
*
* @author Oliver Gierke
* @author Michal Vich
* @author Christoph Strobl
*/
public class MongoExceptionTranslator implements PersistenceExceptionTranslator {
private static final Set<String> DULICATE_KEY_EXCEPTIONS = new HashSet<String>(Arrays.asList(
"MongoException.DuplicateKey", "DuplicateKeyException"));
private static final Set<String> RESOURCE_FAILURE_EXCEPTIONS = new HashSet<String>(Arrays.asList(
"MongoException.Network", "MongoSocketException", "MongoException.CursorNotFound",
"MongoCursorNotFoundException", "MongoServerSelectionException", "MongoTimeoutException"));
private static final Set<String> RESOURCE_USAGE_EXCEPTIONS = new HashSet<String>(
Arrays.asList("MongoInternalException"));
private static final Set<String> DATA_INTEGRETY_EXCEPTIONS = new HashSet<String>(
Arrays.asList("WriteConcernException"));
/*
* (non-Javadoc)
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
@@ -63,22 +51,28 @@ public class MongoExceptionTranslator implements PersistenceExceptionTranslator
// Check for well-known MongoException subclasses.
String exception = ClassUtils.getShortName(ClassUtils.getUserClass(ex.getClass()));
if (DULICATE_KEY_EXCEPTIONS.contains(exception)) {
if (ex instanceof DuplicateKey || ex instanceof DuplicateKeyException) {
return new DuplicateKeyException(ex.getMessage(), ex);
}
if (RESOURCE_FAILURE_EXCEPTIONS.contains(exception)) {
if (ex instanceof Network || ex instanceof MongoSocketException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (RESOURCE_USAGE_EXCEPTIONS.contains(exception)) {
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
if (ex instanceof CursorNotFound || ex instanceof MongoCursorNotFoundException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (DATA_INTEGRETY_EXCEPTIONS.contains(exception)) {
return new DataIntegrityViolationException(ex.getMessage(), ex);
if (ex instanceof MongoServerSelectionException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof MongoTimeoutException) {
return new DataAccessResourceFailureException(ex.getMessage(), ex);
}
if (ex instanceof MongoInternalException) {
return new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
}
// All other MongoExceptions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2013 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.
@@ -20,7 +20,9 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
@@ -38,14 +40,12 @@ import com.mongodb.WriteConcern;
* @author Graeme Rocher
* @author Oliver Gierke
* @author Thomas Darimont
* @author Christoph Strobl
* @since 1.0
* @deprecated since 1.7. Please use {@link MongoClientFactoryBean} instead.
*/
@Deprecated
public class MongoFactoryBean extends AbstractFactoryBean<Mongo> implements PersistenceExceptionTranslator {
public class MongoFactoryBean implements FactoryBean<Mongo>, InitializingBean, DisposableBean,
PersistenceExceptionTranslator {
private static final PersistenceExceptionTranslator DEFAULT_EXCEPTION_TRANSLATOR = new MongoExceptionTranslator();
private Mongo mongo;
private MongoOptions mongoOptions;
private String host;
@@ -53,11 +53,9 @@ public class MongoFactoryBean extends AbstractFactoryBean<Mongo> implements Pers
private WriteConcern writeConcern;
private List<ServerAddress> replicaSetSeeds;
private List<ServerAddress> replicaPair;
private PersistenceExceptionTranslator exceptionTranslator = DEFAULT_EXCEPTION_TRANSLATOR;
/**
* @param mongoOptions
*/
private PersistenceExceptionTranslator exceptionTranslator = new MongoExceptionTranslator();
public void setMongoOptions(MongoOptions mongoOptions) {
this.mongoOptions = mongoOptions;
}
@@ -68,6 +66,7 @@ public class MongoFactoryBean extends AbstractFactoryBean<Mongo> implements Pers
/**
* @deprecated use {@link #setReplicaSetSeeds(ServerAddress[])} instead
*
* @param replicaPair
*/
@Deprecated
@@ -76,19 +75,30 @@ public class MongoFactoryBean extends AbstractFactoryBean<Mongo> implements Pers
}
/**
* Configures the host to connect to.
*
* @param host
* @param elements the elements to filter <T>
* @return a new unmodifiable {@link List#} from the given elements without nulls
*/
private <T> List<T> filterNonNullElementsAsList(T[] elements) {
if (elements == null) {
return Collections.emptyList();
}
List<T> candidateElements = new ArrayList<T>();
for (T element : elements) {
if (element != null) {
candidateElements.add(element);
}
}
return Collections.unmodifiableList(candidateElements);
}
public void setHost(String host) {
this.host = host;
}
/**
* Configures the port to connect to.
*
* @param port
*/
public void setPort(int port) {
this.port = port;
}
@@ -102,13 +112,12 @@ public class MongoFactoryBean extends AbstractFactoryBean<Mongo> implements Pers
this.writeConcern = writeConcern;
}
/**
* Configures the {@link PersistenceExceptionTranslator} to use.
*
* @param exceptionTranslator can be {@literal null}.
*/
public void setExceptionTranslator(PersistenceExceptionTranslator exceptionTranslator) {
this.exceptionTranslator = exceptionTranslator == null ? DEFAULT_EXCEPTION_TRANSLATOR : exceptionTranslator;
this.exceptionTranslator = exceptionTranslator;
}
public Mongo getObject() throws Exception {
return mongo;
}
/*
@@ -119,6 +128,14 @@ public class MongoFactoryBean extends AbstractFactoryBean<Mongo> implements Pers
return Mongo.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
public boolean isSingleton() {
return true;
}
/*
* (non-Javadoc)
* @see org.springframework.dao.support.PersistenceExceptionTranslator#translateExceptionIfPossible(java.lang.RuntimeException)
@@ -129,10 +146,10 @@ public class MongoFactoryBean extends AbstractFactoryBean<Mongo> implements Pers
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
protected Mongo createInstance() throws Exception {
@SuppressWarnings("deprecation")
public void afterPropertiesSet() throws Exception {
Mongo mongo;
ServerAddress defaultOptions = new ServerAddress();
@@ -158,42 +175,18 @@ public class MongoFactoryBean extends AbstractFactoryBean<Mongo> implements Pers
mongo.setWriteConcern(writeConcern);
}
return mongo;
this.mongo = mongo;
}
private boolean isNullOrEmpty(Collection<?> elements) {
return elements == null || elements.isEmpty();
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.config.AbstractFactoryBean#destroyInstance(java.lang.Object)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
@Override
protected void destroyInstance(Mongo mongo) throws Exception {
mongo.close();
}
private static boolean isNullOrEmpty(Collection<?> elements) {
return elements == null || elements.isEmpty();
}
/**
* Returns the given array as {@link List} with all {@literal null} elements removed.
*
* @param elements the elements to filter <T>
* @return a new unmodifiable {@link List#} from the given elements without nulls
*/
private static <T> List<T> filterNonNullElementsAsList(T[] elements) {
if (elements == null) {
return Collections.emptyList();
}
List<T> candidateElements = new ArrayList<T>();
for (T element : elements) {
if (element != null) {
candidateElements.add(element);
}
}
return Collections.unmodifiableList(candidateElements);
public void destroy() throws Exception {
this.mongo.close();
}
}

View File

@@ -33,14 +33,10 @@ import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.util.CloseableIterator;
import com.mongodb.CommandResult;
import com.mongodb.Cursor;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.ReadPreference;
import com.mongodb.WriteResult;
/**
@@ -89,23 +85,9 @@ public interface MongoOperations {
*
* @param command a MongoDB command
* @param options query options to use
* @deprecated since 1.7. Please use {@link #executeCommand(DBObject, ReadPreference)}, as the MongoDB Java driver
* version 3 no longer supports this operation.
*/
@Deprecated
CommandResult executeCommand(DBObject command, int options);
/**
* Execute a MongoDB command. Any errors that result from executing this command will be converted into Spring's data
* access exception hierarchy.
*
* @param command a MongoDB command, must not be {@literal null}.
* @param readPreference read preferences to use, can be {@literal null}.
* @return
* @since 1.7
*/
CommandResult executeCommand(DBObject command, ReadPreference readPreference);
/**
* Execute a MongoDB query and iterate over the query results on a per-document basis with a DocumentCallbackHandler.
*
@@ -161,26 +143,9 @@ public interface MongoOperations {
* @param <T> return type
* @param action callback that specified the MongoDB actions to perform on the DB instance
* @return a result object returned by the action or <tt>null</tt>
* @deprecated since 1.7 as the MongoDB Java driver version 3 does not longer support request boundaries via
* {@link DB#requestStart()} and {@link DB#requestDone()}.
*/
@Deprecated
<T> T executeInSession(DbCallback<T> action);
/**
* Executes the given {@link Query} on the entity collection of the specified {@code entityType} backed by a Mongo DB
* {@link Cursor}.
* <p>
* Returns a {@link CloseableIterator} that wraps the a Mongo DB {@link Cursor} that needs to be closed.
*
* @param <T> element return type
* @param query
* @param entityType
* @return
* @since 1.7
*/
<T> CloseableIterator<T> stream(Query query, Class<T> entityType);
/**
* Create an uncapped collection with a name based on the provided entity class.
*
@@ -284,14 +249,6 @@ public interface MongoOperations {
*/
IndexOperations indexOps(Class<?> entityClass);
/**
* Returns the {@link ScriptOperations} that can be performed on {@link com.mongodb.DB} level.
*
* @return
* @since 1.7
*/
ScriptOperations scriptOps();
/**
* Query for a list of objects of type T from the collection used by the entity class.
* <p/>
@@ -1002,5 +959,4 @@ public interface MongoOperations {
* @return
*/
MongoConverter getConverter();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2014 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.
@@ -17,48 +17,41 @@ package org.springframework.data.mongodb.core;
import javax.net.ssl.SSLSocketFactory;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.data.mongodb.util.MongoClientVersion;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import com.mongodb.MongoOptions;
/**
* A factory bean for construction of a {@link MongoOptions} instance. In case used with MongoDB Java driver version 3
* porperties not suppprted by the driver will be ignored.
*
* A factory bean for construction of a {@link MongoOptions} instance.
*
* @author Graeme Rocher
* @author Mark Pollack
* @author Mike Saavedra
* @author Thomas Darimont
* @author Christoph Strobl
* @deprecated since 1.7. Please use {@link MongoClientOptionsFactoryBean} instead.
*/
@Deprecated
public class MongoOptionsFactoryBean extends AbstractFactoryBean<MongoOptions> {
@SuppressWarnings("deprecation")
public class MongoOptionsFactoryBean implements FactoryBean<MongoOptions>, InitializingBean {
private static final MongoOptions DEFAULT_MONGO_OPTIONS = new MongoOptions();
private int connectionsPerHost = DEFAULT_MONGO_OPTIONS.getConnectionsPerHost();
private int threadsAllowedToBlockForConnectionMultiplier = DEFAULT_MONGO_OPTIONS
.getThreadsAllowedToBlockForConnectionMultiplier();
private int maxWaitTime = DEFAULT_MONGO_OPTIONS.getMaxWaitTime();
private int connectTimeout = DEFAULT_MONGO_OPTIONS.getConnectTimeout();
private int socketTimeout = DEFAULT_MONGO_OPTIONS.getSocketTimeout();
private boolean socketKeepAlive = DEFAULT_MONGO_OPTIONS.isSocketKeepAlive();
private int writeNumber = DEFAULT_MONGO_OPTIONS.getW();
private int writeTimeout = DEFAULT_MONGO_OPTIONS.getWtimeout();
private boolean writeFsync = DEFAULT_MONGO_OPTIONS.isFsync();
private boolean autoConnectRetry = !MongoClientVersion.isMongo3Driver() ? ReflectiveMongoOptionsInvoker
.getAutoConnectRetry(DEFAULT_MONGO_OPTIONS) : false;
private long maxAutoConnectRetryTime = !MongoClientVersion.isMongo3Driver() ? ReflectiveMongoOptionsInvoker
.getMaxAutoConnectRetryTime(DEFAULT_MONGO_OPTIONS) : -1;
private boolean slaveOk = !MongoClientVersion.isMongo3Driver() ? ReflectiveMongoOptionsInvoker
.getSlaveOk(DEFAULT_MONGO_OPTIONS) : false;
private int connectionsPerHost = DEFAULT_MONGO_OPTIONS.connectionsPerHost;
private int threadsAllowedToBlockForConnectionMultiplier = DEFAULT_MONGO_OPTIONS.threadsAllowedToBlockForConnectionMultiplier;
private int maxWaitTime = DEFAULT_MONGO_OPTIONS.maxWaitTime;
private int connectTimeout = DEFAULT_MONGO_OPTIONS.connectTimeout;
private int socketTimeout = DEFAULT_MONGO_OPTIONS.socketTimeout;
private boolean socketKeepAlive = DEFAULT_MONGO_OPTIONS.socketKeepAlive;
private boolean autoConnectRetry = DEFAULT_MONGO_OPTIONS.autoConnectRetry;
private long maxAutoConnectRetryTime = DEFAULT_MONGO_OPTIONS.maxAutoConnectRetryTime;
private int writeNumber = DEFAULT_MONGO_OPTIONS.w;
private int writeTimeout = DEFAULT_MONGO_OPTIONS.wtimeout;
private boolean writeFsync = DEFAULT_MONGO_OPTIONS.fsync;
private boolean slaveOk = DEFAULT_MONGO_OPTIONS.slaveOk;
private boolean ssl;
private SSLSocketFactory sslSocketFactory;
private MongoOptions options;
/**
* Configures the maximum number of connections allowed per host until we will block.
*
@@ -151,10 +144,7 @@ public class MongoOptionsFactoryBean extends AbstractFactoryBean<MongoOptions> {
/**
* Configures whether or not the system retries automatically on a failed connect. This defaults to {@literal false}.
*
* @deprecated since 1.7.
*/
@Deprecated
public void setAutoConnectRetry(boolean autoConnectRetry) {
this.autoConnectRetry = autoConnectRetry;
}
@@ -164,9 +154,7 @@ public class MongoOptionsFactoryBean extends AbstractFactoryBean<MongoOptions> {
* defaults to {@literal 0}, which means to use the default {@literal 15s} if {@link #autoConnectRetry} is on.
*
* @param maxAutoConnectRetryTime the maxAutoConnectRetryTime to set
* @deprecated since 1.7
*/
@Deprecated
public void setMaxAutoConnectRetryTime(long maxAutoConnectRetryTime) {
this.maxAutoConnectRetryTime = maxAutoConnectRetryTime;
}
@@ -175,9 +163,7 @@ public class MongoOptionsFactoryBean extends AbstractFactoryBean<MongoOptions> {
* Specifies if the driver is allowed to read from secondaries or slaves. Defaults to {@literal false}.
*
* @param slaveOk true if the driver should read from secondaries or slaves.
* @deprecated since 1.7
*/
@Deprecated
public void setSlaveOk(boolean slaveOk) {
this.slaveOk = slaveOk;
}
@@ -208,41 +194,40 @@ public class MongoOptionsFactoryBean extends AbstractFactoryBean<MongoOptions> {
this.sslSocketFactory = sslSocketFactory;
}
/*
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
protected MongoOptions createInstance() throws Exception {
if (MongoClientVersion.isMongo3Driver()) {
throw new IllegalArgumentException(
String
.format("Usage of 'mongo-options' is no longer supported for MongoDB Java driver version 3 and above. Please use 'mongo-client-options' and refer to chapter 'MongoDB 3.0 Support' for details."));
}
public void afterPropertiesSet() {
MongoOptions options = new MongoOptions();
options.setConnectionsPerHost(connectionsPerHost);
options.setThreadsAllowedToBlockForConnectionMultiplier(threadsAllowedToBlockForConnectionMultiplier);
options.setMaxWaitTime(maxWaitTime);
options.setConnectTimeout(connectTimeout);
options.setSocketTimeout(socketTimeout);
options.setSocketKeepAlive(socketKeepAlive);
options.setW(writeNumber);
options.setWtimeout(writeTimeout);
options.setFsync(writeFsync);
options.connectionsPerHost = connectionsPerHost;
options.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
options.maxWaitTime = maxWaitTime;
options.connectTimeout = connectTimeout;
options.socketTimeout = socketTimeout;
options.socketKeepAlive = socketKeepAlive;
options.autoConnectRetry = autoConnectRetry;
options.maxAutoConnectRetryTime = maxAutoConnectRetryTime;
options.slaveOk = slaveOk;
options.w = writeNumber;
options.wtimeout = writeTimeout;
options.fsync = writeFsync;
if (ssl) {
options.setSocketFactory(sslSocketFactory != null ? sslSocketFactory : SSLSocketFactory.getDefault());
}
ReflectiveMongoOptionsInvoker.setAutoConnectRetry(options, autoConnectRetry);
ReflectiveMongoOptionsInvoker.setMaxAutoConnectRetryTime(options, maxAutoConnectRetryTime);
ReflectiveMongoOptionsInvoker.setSlaveOk(options, slaveOk);
this.options = options;
}
return options;
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
public MongoOptions getObject() {
return this.options;
}
/*
@@ -252,4 +237,12 @@ public class MongoOptionsFactoryBean extends AbstractFactoryBean<MongoOptions> {
public Class<?> getObjectType() {
return MongoOptions.class;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
public boolean isSingleton() {
return true;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2014 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.
@@ -55,9 +55,8 @@ import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Metric;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
import org.springframework.data.mapping.model.BeanWrapper;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
@@ -95,19 +94,14 @@ import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.util.MongoClientVersion;
import org.springframework.data.util.CloseableIterator;
import org.springframework.jca.cci.core.ConnectionCallback;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.Bytes;
import com.mongodb.CommandResult;
import com.mongodb.Cursor;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
@@ -136,7 +130,6 @@ import com.mongodb.util.JSONParseException;
* @author Thomas Darimont
* @author Chuong Ngo
* @author Christoph Strobl
* @author Doménique Tilleuil
*/
@SuppressWarnings("deprecation")
public class MongoTemplate implements MongoOperations, ApplicationContextAware {
@@ -318,33 +311,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
return this.mongoConverter;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#executeAsStream(org.springframework.data.mongodb.core.query.Query, java.lang.Class)
*/
@Override
public <T> CloseableIterator<T> stream(final Query query, final Class<T> entityType) {
return execute(entityType, new CollectionCallback<CloseableIterator<T>>() {
@Override
public CloseableIterator<T> doInCollection(DBCollection collection) throws MongoException, DataAccessException {
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(entityType);
DBObject mappedFields = queryMapper.getMappedFields(query.getFieldsObject(), persistentEntity);
DBObject mappedQuery = queryMapper.getMappedObject(query.getQueryObject(), persistentEntity);
DBCursor cursor = collection.find(mappedQuery, mappedFields);
QueryCursorPreparer cursorPreparer = new QueryCursorPreparer(query, entityType);
ReadDbObjectCallback<T> readCallback = new ReadDbObjectCallback<T>(mongoConverter, entityType);
return new CloseableIterableCusorAdapter<T>(cursorPreparer.prepare(cursor), exceptionTranslator, readCallback);
}
});
}
public String getCollectionName(Class<?> entityClass) {
return this.determineCollectionName(entityClass);
}
@@ -365,32 +331,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
return result;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#executeCommand(com.mongodb.DBObject, int)
*/
@Deprecated
public CommandResult executeCommand(final DBObject command, final int options) {
return executeCommand(command, (options & Bytes.QUERYOPTION_SLAVEOK) != 0 ? ReadPreference.secondaryPreferred()
: ReadPreference.primary());
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#executeCommand(com.mongodb.DBObject, com.mongodb.ReadPreference)
*/
public CommandResult executeCommand(final DBObject command, final ReadPreference readPreference) {
Assert.notNull(command, "Command must not be null!");
CommandResult result = execute(new DbCallback<CommandResult>() {
public CommandResult doInDB(DB db) throws MongoException, DataAccessException {
return db.command(command, readPreference);
return readPreference != null ? db.command(command, readPreference) : db.command(command);
}
});
logCommandExecutionError(command, result);
return result;
}
@@ -464,20 +413,14 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
}
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#executeInSession(org.springframework.data.mongodb.core.DbCallback)
*/
@Deprecated
public <T> T executeInSession(final DbCallback<T> action) {
return execute(new DbCallback<T>() {
public T doInDB(DB db) throws MongoException, DataAccessException {
try {
ReflectiveDbInvoker.requestStart(db);
db.requestStart();
return action.doInDB(db);
} finally {
ReflectiveDbInvoker.requestDone(db);
db.requestDone();
}
}
});
@@ -543,15 +486,6 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
return new DefaultIndexOperations(this, determineCollectionName(entityClass));
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.MongoOperations#scriptOps()
*/
@Override
public ScriptOperations scriptOps() {
return new DefaultScriptOperations(this);
}
// Find methods that take a Query to express the query and that return a single object.
public <T> T findOne(Query query, Class<T> entityClass) {
@@ -632,7 +566,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
BasicDBObject command = new BasicDBObject("geoNear", collection);
command.putAll(near.toDBObject());
CommandResult commandResult = executeCommand(command);
CommandResult commandResult = executeCommand(command, getDb().getOptions());
List<Object> results = (List<Object>) commandResult.get("results");
results = results == null ? Collections.emptyList() : results;
@@ -764,23 +698,13 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
/**
* Prepare the WriteConcern before any processing is done using it. This allows a convenient way to apply custom
* settings in sub-classes. <br />
* In case of using MongoDB Java driver version 3 the returned {@link WriteConcern} will be defaulted to
* {@link WriteConcern#ACKNOWLEDGED} when {@link WriteResultChecking} is set to {@link WriteResultChecking#EXCEPTION}.
* settings in sub-classes.
*
* @param writeConcern any WriteConcern already configured or null
* @return The prepared WriteConcern or null
*/
protected WriteConcern prepareWriteConcern(MongoAction mongoAction) {
WriteConcern wc = writeConcernResolver.resolve(mongoAction);
if (MongoClientVersion.isMongo3Driver()
&& ObjectUtils.nullSafeEquals(WriteResultChecking.EXCEPTION, writeResultChecking)
&& (wc == null || wc.getW() < 1)) {
return WriteConcern.ACKNOWLEDGED;
}
return wc;
return writeConcernResolver.resolve(mongoAction);
}
protected <T> void doInsert(String collectionName, T objectToSave, MongoWriter<T> writer) {
@@ -825,9 +749,8 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
MongoPersistentEntity<?> mongoPersistentEntity = getPersistentEntity(entity.getClass());
if (mongoPersistentEntity != null && mongoPersistentEntity.hasVersionProperty()) {
ConvertingPropertyAccessor accessor = new ConvertingPropertyAccessor(
mongoPersistentEntity.getPropertyAccessor(entity), mongoConverter.getConversionService());
accessor.setProperty(mongoPersistentEntity.getVersionProperty(), 0);
BeanWrapper<Object> wrapper = BeanWrapper.create(entity, this.mongoConverter.getConversionService());
wrapper.setProperty(mongoPersistentEntity.getVersionProperty(), 0);
}
}
@@ -926,14 +849,11 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
private <T> void doSaveVersioned(T objectToSave, MongoPersistentEntity<?> entity, String collectionName) {
ConvertingPropertyAccessor convertingAccessor = new ConvertingPropertyAccessor(
entity.getPropertyAccessor(objectToSave), mongoConverter.getConversionService());
BeanWrapper<T> beanWrapper = BeanWrapper.create(objectToSave, this.mongoConverter.getConversionService());
MongoPersistentProperty idProperty = entity.getIdProperty();
MongoPersistentProperty versionProperty = entity.getVersionProperty();
Object version = convertingAccessor.getProperty(versionProperty);
Number versionNumber = convertingAccessor.getProperty(versionProperty, Number.class);
Number version = beanWrapper.getProperty(versionProperty, Number.class);
// Fresh instance -> initialize version property
if (version == null) {
@@ -943,11 +863,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
assertUpdateableIdIfNotSet(objectToSave);
// Create query for entity with the id and old version
Object id = convertingAccessor.getProperty(idProperty);
Object id = beanWrapper.getProperty(idProperty);
Query query = new Query(Criteria.where(idProperty.getName()).is(id).and(versionProperty.getName()).is(version));
// Bump version number
convertingAccessor.setProperty(versionProperty, versionNumber.longValue() + 1);
Number number = beanWrapper.getProperty(versionProperty, Number.class);
beanWrapper.setProperty(versionProperty, number.longValue() + 1);
BasicDBObject dbObject = new BasicDBObject();
@@ -1107,8 +1028,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
: collection.update(queryObj, updateObj, upsert, multi, writeConcernToUse);
if (entity != null && entity.hasVersionProperty() && !multi) {
if (ReflectiveWriteResultInvoker.wasAcknowledged(writeResult) && writeResult.getN() == 0
&& dbObjectContainsVersionProperty(queryObj, entity)) {
if (writeResult.getN() == 0 && dbObjectContainsVersionProperty(queryObj, entity)) {
throw new OptimisticLockingFailureException("Optimistic lock exception on saving entity: "
+ updateObj.toMap().toString() + " to collection " + collectionName);
}
@@ -1179,11 +1099,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(objectType);
MongoPersistentProperty idProp = entity == null ? null : entity.getIdProperty();
if (idProp == null || entity == null) {
if (idProp == null) {
throw new MappingException("No id property found for object of type " + objectType);
}
Object idValue = entity.getPropertyAccessor(object).getProperty(idProp);
Object idValue = BeanWrapper.create(object, mongoConverter.getConversionService())
.getProperty(idProp, Object.class);
return Collections.singletonMap(idProp.getFieldName(), idValue).entrySet().iterator().next();
}
@@ -1227,11 +1148,12 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(entity.getClass());
MongoPersistentProperty idProperty = persistentEntity == null ? null : persistentEntity.getIdProperty();
if (idProperty == null || persistentEntity == null) {
if (idProperty == null) {
return;
}
Object idValue = persistentEntity.getPropertyAccessor(entity).getProperty(idProperty);
ConversionService service = mongoConverter.getConversionService();
Object idValue = BeanWrapper.create(entity, service).getProperty(idProperty, Object.class);
if (idValue == null && !MongoSimpleTypes.AUTOGENERATED_ID_TYPES.contains(idProperty.getType())) {
throw new InvalidDataAccessApiUsageException(String.format(
@@ -1324,24 +1246,25 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
String mapFunc = replaceWithResourceIfNecessary(mapFunction);
String reduceFunc = replaceWithResourceIfNecessary(reduceFunction);
DBCollection inputCollection = getCollection(inputCollectionName);
MapReduceCommand command = new MapReduceCommand(inputCollection, mapFunc, reduceFunc,
mapReduceOptions.getOutputCollection(), mapReduceOptions.getOutputType(), query == null
|| query.getQueryObject() == null ? null : queryMapper.getMappedObject(query.getQueryObject(), null));
mapReduceOptions.getOutputCollection(), mapReduceOptions.getOutputType(), null);
copyMapReduceOptionsToCommand(query, mapReduceOptions, command);
DBObject commandObject = copyQuery(query, copyMapReduceOptions(mapReduceOptions, command));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Executing MapReduce on collection [" + command.getInput() + "], mapFunction [" + mapFunc
+ "], reduceFunction [" + reduceFunc + "]");
}
MapReduceOutput mapReduceOutput = inputCollection.mapReduce(command);
CommandResult commandResult = command.getOutputType() == MapReduceCommand.OutputType.INLINE ? executeCommand(
commandObject, getDb().getOptions()) : executeCommand(commandObject);
handleCommandError(commandResult, commandObject);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("MapReduce command result = [{}]", serializeToJsonSafely(mapReduceOutput.results()));
LOGGER.debug("MapReduce command result = [{}]", serializeToJsonSafely(commandObject));
}
MapReduceOutput mapReduceOutput = new MapReduceOutput(inputCollection, commandObject, commandResult);
List<T> mappedResults = new ArrayList<T>();
DbObjectCallback<T> callback = new ReadDbObjectCallback<T>(mongoConverter, entityClass);
@@ -1349,7 +1272,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
mappedResults.add(callback.doWith(dbObject));
}
return new MapReduceResults<T>(mappedResults, mapReduceOutput);
return new MapReduceResults<T>(mappedResults, commandResult);
}
public <T> GroupByResults<T> group(String inputCollectionName, GroupBy groupBy, Class<T> entityClass) {
@@ -1503,7 +1426,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
LOGGER.debug("Executing aggregation: {}", serializeToJsonSafely(command));
}
CommandResult commandResult = executeCommand(command);
CommandResult commandResult = executeCommand(command, getDb().getOptions());
handleCommandError(commandResult, command);
return new AggregationResults<O>(returnPotentiallyMappedResults(outputType, commandResult), commandResult);
@@ -1556,40 +1479,51 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
return func;
}
private void copyMapReduceOptionsToCommand(Query query, MapReduceOptions mapReduceOptions,
MapReduceCommand mapReduceCommand) {
private DBObject copyQuery(Query query, DBObject copyMapReduceOptions) {
if (query != null) {
if (query.getSkip() != 0 || query.getFieldsObject() != null) {
throw new InvalidDataAccessApiUsageException(
"Can not use skip or field specification with map reduce operations");
}
if (query.getQueryObject() != null) {
copyMapReduceOptions.put("query", queryMapper.getMappedObject(query.getQueryObject(), null));
}
if (query.getLimit() > 0) {
mapReduceCommand.setLimit(query.getLimit());
copyMapReduceOptions.put("limit", query.getLimit());
}
if (query.getSortObject() != null) {
mapReduceCommand.setSort(queryMapper.getMappedObject(query.getSortObject(), null));
copyMapReduceOptions.put("sort", queryMapper.getMappedObject(query.getSortObject(), null));
}
}
return copyMapReduceOptions;
}
private DBObject copyMapReduceOptions(MapReduceOptions mapReduceOptions, MapReduceCommand command) {
if (mapReduceOptions.getJavaScriptMode() != null) {
mapReduceCommand.setJsMode(true);
command.addExtraOption("jsMode", true);
}
if (!mapReduceOptions.getExtraOptions().isEmpty()) {
for (Map.Entry<String, Object> entry : mapReduceOptions.getExtraOptions().entrySet()) {
ReflectiveMapReduceInvoker.addExtraOption(mapReduceCommand, entry.getKey(), entry.getValue());
command.addExtraOption(entry.getKey(), entry.getValue());
}
}
if (mapReduceOptions.getFinalizeFunction() != null) {
mapReduceCommand.setFinalize(this.replaceWithResourceIfNecessary(mapReduceOptions.getFinalizeFunction()));
command.setFinalize(this.replaceWithResourceIfNecessary(mapReduceOptions.getFinalizeFunction()));
}
if (mapReduceOptions.getOutputDatabase() != null) {
mapReduceCommand.setOutputDB(mapReduceOptions.getOutputDatabase());
command.setOutputDB(mapReduceOptions.getOutputDatabase());
}
if (!mapReduceOptions.getScopeVariables().isEmpty()) {
mapReduceCommand.setScope(mapReduceOptions.getScopeVariables());
command.setScope(mapReduceOptions.getScopeVariables());
}
DBObject commandObject = command.toDBObject();
DBObject outObject = (DBObject) commandObject.get("out");
if (mapReduceOptions.getOutputSharded() != null) {
outObject.put("sharded", mapReduceOptions.getOutputSharded());
}
return commandObject;
}
public Set<String> getCollectionNames() {
@@ -1796,14 +1730,15 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
}
ConversionService conversionService = mongoConverter.getConversionService();
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(savedObject.getClass());
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(savedObject);
BeanWrapper<Object> wrapper = BeanWrapper.create(savedObject, conversionService);
if (accessor.getProperty(idProp) != null) {
Object idValue = wrapper.getProperty(idProp, idProp.getType());
if (idValue != null) {
return;
}
new ConvertingPropertyAccessor(accessor, conversionService).setProperty(idProp, id);
wrapper.setProperty(idProp, id);
}
private DBCollection getAndPrepareCollection(DB db, String collectionName) {
@@ -1970,7 +1905,7 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
return;
}
String error = ReflectiveWriteResultInvoker.getError(writeResult);
String error = writeResult.getError();
if (error == null) {
return;
@@ -2167,10 +2102,9 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
* Simple internal callback to allow operations on a {@link DBObject}.
*
* @author Oliver Gierke
* @author Thomas Darimont
*/
static interface DbObjectCallback<T> {
private interface DbObjectCallback<T> {
T doWith(DBObject object);
}
@@ -2333,76 +2267,4 @@ public class MongoTemplate implements MongoOperations, ApplicationContextAware {
}
}
/**
* A {@link CloseableIterator} that is backed by a MongoDB {@link Cursor}.
*
* @since 1.7
* @author Thomas Darimont
*/
static class CloseableIterableCusorAdapter<T> implements CloseableIterator<T> {
private volatile Cursor cursor;
private PersistenceExceptionTranslator exceptionTranslator;
private DbObjectCallback<T> objectReadCallback;
/**
* Creates a new {@link CloseableIterableCusorAdapter} backed by the given {@link Cursor}.
*
* @param cursor
* @param exceptionTranslator
* @param objectReadCallback
*/
public CloseableIterableCusorAdapter(Cursor cursor, PersistenceExceptionTranslator exceptionTranslator,
DbObjectCallback<T> objectReadCallback) {
this.cursor = cursor;
this.exceptionTranslator = exceptionTranslator;
this.objectReadCallback = objectReadCallback;
}
@Override
public boolean hasNext() {
if (cursor == null) {
return false;
}
try {
return cursor.hasNext();
} catch (RuntimeException ex) {
throw exceptionTranslator.translateExceptionIfPossible(ex);
}
}
@Override
public T next() {
if (cursor == null) {
return null;
}
try {
DBObject item = cursor.next();
T converted = objectReadCallback.doWith(item);
return converted;
} catch (RuntimeException ex) {
throw exceptionTranslator.translateExceptionIfPossible(ex);
}
}
@Override
public void close() {
Cursor c = cursor;
try {
c.close();
} catch (RuntimeException ex) {
throw exceptionTranslator.translateExceptionIfPossible(ex);
} finally {
cursor = null;
exceptionTranslator = null;
objectReadCallback = null;
}
}
}
}

View File

@@ -1,109 +0,0 @@
/*
* Copyright 2015 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.mongodb.core;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.springframework.data.mongodb.util.MongoClientVersion;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
/**
* {@link ReflectiveDBCollectionInvoker} provides reflective access to {@link DBCollection} API that is not consistently
* available for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
class ReflectiveDBCollectionInvoker {
private static final Method GEN_INDEX_NAME_METHOD;
private static final Method RESET_INDEX_CHACHE_METHOD;
static {
GEN_INDEX_NAME_METHOD = findMethod(DBCollection.class, "genIndexName", DBObject.class);
RESET_INDEX_CHACHE_METHOD = findMethod(DBCollection.class, "resetIndexCache");
}
private ReflectiveDBCollectionInvoker() {}
/**
* Convenience method to generate an index name from the set of fields it is over. Will fall back to a MongoDB Java
* driver version 2 compatible way of generating index name in case of {@link MongoClientVersion#isMongo3Driver()}.
*
* @param keys the names of the fields used in this index
* @return
*/
public static String generateIndexName(DBObject keys) {
if (isMongo3Driver()) {
return genIndexName(keys);
}
return (String) invokeMethod(GEN_INDEX_NAME_METHOD, null, keys);
}
/**
* In case of MongoDB Java driver version 2 all indices that have not yet been applied to this collection will be
* cleared. Since this method is not available for the MongoDB Java driver version 3 the operation will throw
* {@link UnsupportedOperationException}.
*
* @param dbCollection
* @throws UnsupportedOperationException
*/
public static void resetIndexCache(DBCollection dbCollection) {
if (isMongo3Driver()) {
throw new UnsupportedOperationException("The mongo java driver 3 does no loger support resetIndexCache!");
}
invokeMethod(RESET_INDEX_CHACHE_METHOD, dbCollection);
}
/**
* Borrowed from MongoDB Java driver version 2. See <a
* href="http://github.com/mongodb/mongo-java-driver/blob/r2.13.0/src/main/com/mongodb/DBCollection.java#L754"
* >http://github.com/mongodb/mongo-java-driver/blob/r2.13.0/src/main/com/mongodb/DBCollection.java#L754</a>
*
* @param keys
* @return
*/
private static String genIndexName(DBObject keys) {
StringBuilder name = new StringBuilder();
for (String s : keys.keySet()) {
if (name.length() > 0) {
name.append('_');
}
name.append(s).append('_');
Object val = keys.get(s);
if (val instanceof Number || val instanceof String) {
name.append(val.toString().replace(' ', '_'));
}
}
return name.toString();
}
}

View File

@@ -1,134 +0,0 @@
/*
* Copyright 2015 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.mongodb.core;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.mongodb.CannotGetMongoDbConnectionException;
import org.springframework.data.mongodb.util.MongoClientVersion;
import com.mongodb.DB;
import com.mongodb.Mongo;
/**
* {@link ReflectiveDbInvoker} provides reflective access to {@link DB} API that is not consistently available for
* various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
final class ReflectiveDbInvoker {
private static final Method DB_IS_AUTHENTICATED_METHOD;
private static final Method DB_AUTHENTICATE_METHOD;
private static final Method DB_REQUEST_DONE_METHOD;
private static final Method DB_ADD_USER_METHOD;
private static final Method DB_REQUEST_START_METHOD;
static {
DB_IS_AUTHENTICATED_METHOD = findMethod(DB.class, "isAuthenticated");
DB_AUTHENTICATE_METHOD = findMethod(DB.class, "authenticate", String.class, char[].class);
DB_REQUEST_DONE_METHOD = findMethod(DB.class, "requestDone");
DB_ADD_USER_METHOD = findMethod(DB.class, "addUser", String.class, char[].class);
DB_REQUEST_START_METHOD = findMethod(DB.class, "requestStart");
}
private ReflectiveDbInvoker() {}
/**
* Authenticate against database using provided credentials in case of a MongoDB Java driver version 2.
*
* @param mongo must not be {@literal null}.
* @param db must not be {@literal null}.
* @param credentials must not be {@literal null}.
* @param authenticationDatabaseName
*/
public static void authenticate(Mongo mongo, DB db, UserCredentials credentials, String authenticationDatabaseName) {
String databaseName = db.getName();
DB authDb = databaseName.equals(authenticationDatabaseName) ? db : mongo.getDB(authenticationDatabaseName);
synchronized (authDb) {
Boolean isAuthenticated = (Boolean) invokeMethod(DB_IS_AUTHENTICATED_METHOD, authDb);
if (!isAuthenticated) {
String username = credentials.getUsername();
String password = credentials.hasPassword() ? credentials.getPassword() : null;
Boolean authenticated = (Boolean) invokeMethod(DB_AUTHENTICATE_METHOD, authDb, username,
password == null ? null : password.toCharArray());
if (!authenticated) {
throw new CannotGetMongoDbConnectionException("Failed to authenticate to database [" + databaseName + "], "
+ credentials.toString(), databaseName, credentials);
}
}
}
}
/**
* Starts a new 'consistent request' in case of MongoDB Java driver version 2. Will do nothing for MongoDB Java driver
* version 3 since the operation is no longer available.
*
* @param db
*/
public static void requestStart(DB db) {
if (isMongo3Driver()) {
return;
}
invokeMethod(DB_REQUEST_START_METHOD, db);
}
/**
* Ends the current 'consistent request'. a new 'consistent request' in case of MongoDB Java driver version 2. Will do
* nothing for MongoDB Java driver version 3 since the operation is no longer available
*
* @param db
*/
public static void requestDone(DB db) {
if (MongoClientVersion.isMongo3Driver()) {
return;
}
invokeMethod(DB_REQUEST_DONE_METHOD, db);
}
/**
* @param db
* @param username
* @param password
* @throws UnsupportedOperationException
*/
public static void addUser(DB db, String username, char[] password) {
if (isMongo3Driver()) {
throw new UnsupportedOperationException(
"Please use DB.command(…) to call either the createUser or updateUser command!");
}
invokeMethod(DB_ADD_USER_METHOD, db, username, password);
}
}

View File

@@ -1,62 +0,0 @@
/*
* Copyright 2015 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.mongodb.core;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.springframework.util.Assert;
import com.mongodb.MapReduceCommand;
/**
* {@link ReflectiveMapReduceInvoker} provides reflective access to {@link MapReduceCommand} API that is not
* consistently available for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
final class ReflectiveMapReduceInvoker {
private static final Method ADD_EXTRA_OPTION_METHOD;
static {
ADD_EXTRA_OPTION_METHOD = findMethod(MapReduceCommand.class, "addExtraOption", String.class, Object.class);
}
private ReflectiveMapReduceInvoker() {}
/**
* Sets the extra option for MongoDB Java driver version 2. Will do nothing for MongoDB Java driver version 2.
*
* @param cmd can be {@literal null} for MongoDB Java driver version 2.
* @param key
* @param value
*/
public static void addExtraOption(MapReduceCommand cmd, String key, Object value) {
if (isMongo3Driver()) {
return;
}
Assert.notNull(cmd, "MapReduceCommand must not be null!");
invokeMethod(ADD_EXTRA_OPTION_METHOD, cmd, key, value);
}
}

View File

@@ -1,158 +0,0 @@
/*
* Copyright 2015 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.mongodb.core;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.util.ReflectionUtils;
import com.mongodb.MongoOptions;
/**
* {@link ReflectiveMongoOptionsInvoker} provides reflective access to {@link MongoOptions} API that is not consistently
* available for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
@SuppressWarnings("deprecation")
class ReflectiveMongoOptionsInvoker {
private static final Method GET_AUTO_CONNECT_RETRY_METHOD;
private static final Method SET_AUTO_CONNECT_RETRY_METHOD;
private static final Method GET_MAX_AUTO_CONNECT_RETRY_TIME_METHOD;
private static final Method SET_MAX_AUTO_CONNECT_RETRY_TIME_METHOD;
static {
SET_AUTO_CONNECT_RETRY_METHOD = ReflectionUtils
.findMethod(MongoOptions.class, "setAutoConnectRetry", boolean.class);
GET_AUTO_CONNECT_RETRY_METHOD = ReflectionUtils.findMethod(MongoOptions.class, "isAutoConnectRetry");
SET_MAX_AUTO_CONNECT_RETRY_TIME_METHOD = ReflectionUtils.findMethod(MongoOptions.class,
"setMaxAutoConnectRetryTime", long.class);
GET_MAX_AUTO_CONNECT_RETRY_TIME_METHOD = ReflectionUtils.findMethod(MongoOptions.class,
"getMaxAutoConnectRetryTime");
}
private ReflectiveMongoOptionsInvoker() {}
/**
* Sets the retry connection flag for MongoDB Java driver version 2. Will do nothing for MongoDB Java driver version 3
* since the method has been removed.
*
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @param autoConnectRetry
*/
public static void setAutoConnectRetry(MongoOptions options, boolean autoConnectRetry) {
if (isMongo3Driver()) {
return;
}
invokeMethod(SET_AUTO_CONNECT_RETRY_METHOD, options, autoConnectRetry);
}
/**
* Sets the maxAutoConnectRetryTime attribute for MongoDB Java driver version 2. Will do nothing for MongoDB Java
* driver version 3 since the method has been removed.
*
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @param maxAutoConnectRetryTime
*/
public static void setMaxAutoConnectRetryTime(MongoOptions options, long maxAutoConnectRetryTime) {
if (isMongo3Driver()) {
return;
}
invokeMethod(SET_MAX_AUTO_CONNECT_RETRY_TIME_METHOD, options, maxAutoConnectRetryTime);
}
/**
* Sets the slaveOk attribute for MongoDB Java driver version 2. Will do nothing for MongoDB Java driver version 3
* since the method has been removed.
*
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @param slaveOk
*/
public static void setSlaveOk(MongoOptions options, boolean slaveOk) {
if (isMongo3Driver()) {
return;
}
new DirectFieldAccessor(options).setPropertyValue("slaveOk", slaveOk);
}
/**
* Gets the slaveOk attribute for MongoDB Java driver version 2. Throws {@link UnsupportedOperationException} for
* MongoDB Java driver version 3 since the method has been removed.
*
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @return
* @throws UnsupportedOperationException
*/
public static boolean getSlaveOk(MongoOptions options) {
if (isMongo3Driver()) {
throw new UnsupportedOperationException(
"Cannot get value for autoConnectRetry which has been removed in MongoDB Java driver version 3.");
}
return ((Boolean) new DirectFieldAccessor(options).getPropertyValue("slaveOk")).booleanValue();
}
/**
* Gets the autoConnectRetry attribute for MongoDB Java driver version 2. Throws {@link UnsupportedOperationException}
* for MongoDB Java driver version 3 since the method has been removed.
*
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @return
* @throws UnsupportedOperationException
*/
public static boolean getAutoConnectRetry(MongoOptions options) {
if (isMongo3Driver()) {
throw new UnsupportedOperationException(
"Cannot get value for autoConnectRetry which has been removed in MongoDB Java driver version 3.");
}
return ((Boolean) invokeMethod(GET_AUTO_CONNECT_RETRY_METHOD, options)).booleanValue();
}
/**
* Gets the maxAutoConnectRetryTime attribute for MongoDB Java driver version 2. Throws
* {@link UnsupportedOperationException} for MongoDB Java driver version 3 since the method has been removed.
*
* @param options can be {@literal null} for MongoDB Java driver version 3.
* @return
* @throws UnsupportedOperationException
*/
public static long getMaxAutoConnectRetryTime(MongoOptions options) {
if (isMongo3Driver()) {
throw new UnsupportedOperationException(
"Cannot get value for maxAutoConnectRetryTime which has been removed in MongoDB Java driver version 3.");
}
return ((Long) invokeMethod(GET_MAX_AUTO_CONNECT_RETRY_TIME_METHOD, options)).longValue();
}
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright 2015 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.mongodb.core;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import org.springframework.beans.DirectFieldAccessor;
import com.mongodb.WriteConcern;
/**
* {@link ReflectiveWriteConcernInvoker} provides reflective access to {@link WriteConcern} API that is not consistently
* available for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
class ReflectiveWriteConcernInvoker {
private static final WriteConcern NONE_OR_UNACKNOWLEDGED;
static {
NONE_OR_UNACKNOWLEDGED = isMongo3Driver() ? WriteConcern.UNACKNOWLEDGED : (WriteConcern) new DirectFieldAccessor(
new WriteConcern()).getPropertyValue("NONE");
}
/**
* @return {@link WriteConcern#NONE} for MongoDB Java driver version 2, otherwise {@link WriteConcern#UNACKNOWLEDGED}.
*/
public static WriteConcern noneOrUnacknowledged() {
return NONE_OR_UNACKNOWLEDGED;
}
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright 2015 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.mongodb.core;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import com.mongodb.MongoException;
import com.mongodb.WriteResult;
/**
* {@link ReflectiveWriteResultInvoker} provides reflective access to {@link WriteResult} API that is not consistently
* available for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
final class ReflectiveWriteResultInvoker {
private static final Method GET_ERROR_METHOD;
private static final Method WAS_ACKNOWLEDGED_METHOD;
private ReflectiveWriteResultInvoker() {}
static {
GET_ERROR_METHOD = findMethod(WriteResult.class, "getError");
WAS_ACKNOWLEDGED_METHOD = findMethod(WriteResult.class, "wasAcknowledged");
}
/**
* @param writeResult can be {@literal null} for MongoDB Java driver version 3.
* @return null in case of MongoDB Java driver version 3 since errors are thrown as {@link MongoException}.
*/
public static String getError(WriteResult writeResult) {
if (isMongo3Driver()) {
return null;
}
return (String) invokeMethod(GET_ERROR_METHOD, writeResult);
}
/**
* @param writeResult
* @return return in case of MongoDB Java driver version 2.
*/
public static boolean wasAcknowledged(WriteResult writeResult) {
return isMongo3Driver() ? ((Boolean) invokeMethod(WAS_ACKNOWLEDGED_METHOD, writeResult)).booleanValue() : true;
}
}

View File

@@ -1,84 +0,0 @@
/*
* Copyright 2014-2015 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.mongodb.core;
import java.util.Set;
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import com.mongodb.DB;
/**
* Script operations on {@link com.mongodb.DB} level. Allows interaction with server side JavaScript functions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
public interface ScriptOperations {
/**
* Store given {@link ExecutableMongoScript} generating a syntheitcal name so that it can be called by it
* subsequently.
*
* @param script must not be {@literal null}.
* @return {@link NamedMongoScript} with name under which the {@code JavaScript} function can be called.
*/
NamedMongoScript register(ExecutableMongoScript script);
/**
* Registers the given {@link NamedMongoScript} in the database.
*
* @param script the {@link NamedMongoScript} to be registered.
* @return
*/
NamedMongoScript register(NamedMongoScript script);
/**
* Executes the {@literal script} by either calling it via its {@literal name} or directly sending it.
*
* @param script must not be {@literal null}.
* @param args arguments to pass on for script execution.
* @return the script evaluation result.
* @throws org.springframework.dao.DataAccessException
*/
Object execute(ExecutableMongoScript script, Object... args);
/**
* Call the {@literal JavaScript} by its name.
*
* @param scriptName must not be {@literal null} or empty.
* @param args
* @return
*/
Object call(String scriptName, Object... args);
/**
* Checks {@link DB} for existence of {@link ServerSideJavaScript} with given name.
*
* @param scriptName must not be {@literal null} or empty.
* @return false if no {@link ServerSideJavaScript} with given name exists.
*/
boolean exists(String scriptName);
/**
* Returns names of {@literal JavaScript} functions that can be called.
*
* @return empty {@link Set} if no scripts found.
*/
Set<String> getScriptNames();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2013 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.
@@ -27,8 +27,6 @@ import org.springframework.util.StringUtils;
import com.mongodb.DB;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoException;
import com.mongodb.MongoURI;
import com.mongodb.WriteConcern;
@@ -39,7 +37,6 @@ import com.mongodb.WriteConcern;
* @author Mark Pollack
* @author Oliver Gierke
* @author Thomas Darimont
* @author Christoph Strobl
*/
public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
@@ -57,9 +54,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
*
* @param mongo Mongo instance, must not be {@literal null}.
* @param databaseName database name, not be {@literal null} or empty.
* @deprecated since 1.7. Please use {@link #SimpleMongoDbFactory(MongoClient, String)}.
*/
@Deprecated
public SimpleMongoDbFactory(Mongo mongo, String databaseName) {
this(mongo, databaseName, null);
}
@@ -70,9 +65,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
* @param mongo Mongo instance, must not be {@literal null}.
* @param databaseName Database name, must not be {@literal null} or empty.
* @param credentials username and password.
* @deprecated since 1.7. The credentials used should be provided by {@link MongoClient#getCredentialsList()}.
*/
@Deprecated
public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials) {
this(mongo, databaseName, credentials, false, null);
}
@@ -84,9 +77,7 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
* @param databaseName Database name, must not be {@literal null} or empty.
* @param credentials username and password.
* @param authenticationDatabaseName the database name to use for authentication
* @deprecated since 1.7. The credentials used should be provided by {@link MongoClient#getCredentialsList()}.
*/
@Deprecated
public SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials,
String authenticationDatabaseName) {
this(mongo, databaseName, credentials, false, authenticationDatabaseName);
@@ -99,36 +90,13 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
* @throws MongoException
* @throws UnknownHostException
* @see MongoURI
* @deprecated since 1.7. Please use {@link #SimpleMongoDbFactory(MongoClientURI)} instead.
*/
@Deprecated
@SuppressWarnings("deprecation")
public SimpleMongoDbFactory(MongoURI uri) throws MongoException, UnknownHostException {
this(new Mongo(uri), uri.getDatabase(), new UserCredentials(uri.getUsername(), parseChars(uri.getPassword())),
true, uri.getDatabase());
}
/**
* Creates a new {@link SimpleMongoDbFactory} instance from the given {@link MongoClientURI}.
*
* @param uri must not be {@literal null}.
* @throws UnknownHostException
* @since 1.7
*/
public SimpleMongoDbFactory(MongoClientURI uri) throws UnknownHostException {
this(new MongoClient(uri), uri.getDatabase(), true);
}
/**
* Creates a new {@link SimpleMongoDbFactory} instance from the given {@link MongoClient}.
*
* @param mongoClient must not be {@literal null}.
* @param databaseName must not be {@literal null}.
* @since 1.7
*/
public SimpleMongoDbFactory(MongoClient mongoClient, String databaseName) {
this(mongoClient, databaseName, false);
}
private SimpleMongoDbFactory(Mongo mongo, String databaseName, UserCredentials credentials,
boolean mongoInstanceCreated, String authenticationDatabaseName) {
@@ -149,25 +117,6 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
"Authentication database name must only contain letters, numbers, underscores and dashes!");
}
/**
* @param client
* @param databaseName
* @param mongoInstanceCreated
* @since 1.7
*/
private SimpleMongoDbFactory(MongoClient client, String databaseName, boolean mongoInstanceCreated) {
Assert.notNull(client, "MongoClient must not be null!");
Assert.hasText(databaseName, "Database name must not be empty!");
this.mongo = client;
this.databaseName = databaseName;
this.mongoInstanceCreated = mongoInstanceCreated;
this.exceptionTranslator = new MongoExceptionTranslator();
this.credentials = UserCredentials.NO_CREDENTIALS;
this.authenticationDatabaseName = databaseName;
}
/**
* Configures the {@link WriteConcern} to be used on the {@link DB} instance being created.
*
@@ -189,7 +138,6 @@ public class SimpleMongoDbFactory implements DisposableBean, MongoDbFactory {
* (non-Javadoc)
* @see org.springframework.data.mongodb.MongoDbFactory#getDb(java.lang.String)
*/
@SuppressWarnings("deprecation")
public DB getDb(String dbName) throws DataAccessException {
Assert.hasText(dbName, "Database name must not be empty.");

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.aggregation;
import com.mongodb.DBObject;
/**
* An {@link AggregationExpression} can be used with field expressions in aggregation pipeline stages like
* {@code project} and {@code group}.
*
* @author Thomas Darimont
* @author Oliver Gierke
*/
interface AggregationExpression {
/**
* Turns the {@link AggregationExpression} into a {@link DBObject} within the given
* {@link AggregationOperationContext}.
*
* @param context
* @return
*/
DBObject toDbObject(AggregationOperationContext context);
}

View File

@@ -1,105 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.aggregation;
import java.util.ArrayList;
import java.util.List;
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* An enum of supported {@link AggregationExpression}s in aggregation pipeline stages.
*
* @author Thomas Darimont
* @author Oliver Gierke
* @since 1.10
*/
public enum AggregationFunctionExpressions {
SIZE;
/**
* Returns an {@link AggregationExpression} build from the current {@link Enum} name and the given parameters.
*
* @param parameters must not be {@literal null}
* @return
*/
public AggregationExpression of(Object... parameters) {
Assert.notNull(parameters, "Parameters must not be null!");
return new FunctionExpression(name().toLowerCase(), parameters);
}
/**
* An {@link AggregationExpression} representing a function call.
*
* @author Thomas Darimont
* @author Oliver Gierke
* @since 1.10
*/
static class FunctionExpression implements AggregationExpression {
private final String name;
private final Object[] values;
/**
* Creates a new {@link FunctionExpression} for the given name and values.
*
* @param name must not be {@literal null} or empty.
* @param values must not be {@literal null}.
*/
public FunctionExpression(String name, Object[] values) {
Assert.hasText(name, "Name must not be null!");
Assert.notNull(values, "Values must not be null!");
this.name = name;
this.values = values;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.Expression#toDbObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
*/
@Override
public DBObject toDbObject(AggregationOperationContext context) {
List<Object> args = new ArrayList<Object>(values.length);
for (int i = 0; i < values.length; i++) {
args.add(unpack(values[i], context));
}
return new BasicDBObject("$" + name, args);
}
private static Object unpack(Object value, AggregationOperationContext context) {
if (value instanceof AggregationExpression) {
return ((AggregationExpression) value).toDbObject(context);
}
if (value instanceof Field) {
return context.getReference((Field) value).toString();
}
return value;
}
}
}

View File

@@ -88,7 +88,7 @@ public final class ExposedFields implements Iterable<ExposedField> {
}
/**
* Creates a new {@link ExposedFields} instance for the given fields in either sythetic or non-synthetic way.
* Creates a new {@link ExposedFields} instance for the given fields in either synthetic or non-synthetic way.
*
* @param fields must not be {@literal null}.
* @param synthetic
@@ -107,7 +107,7 @@ public final class ExposedFields implements Iterable<ExposedField> {
}
/**
* Creates a new {@link ExposedFields} with the given orignals and synthetics.
* Creates a new {@link ExposedFields} with the given originals and synthetics.
*
* @param originals must not be {@literal null}.
* @param synthetic must not be {@literal null}.
@@ -363,7 +363,7 @@ public final class ExposedFields implements Iterable<ExposedField> {
}
/**
* Returns the referenve value for the given field reference. Will return 1 for a synthetic, unaliased field or the
* Returns the reference value for the given field reference. Will return 1 for a synthetic, unaliased field or the
* raw rendering of the reference otherwise.
*
* @return

View File

@@ -193,16 +193,6 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
return newBuilder(GroupOps.LAST, reference, null);
}
/**
* Generates an {@link GroupOperationBuilder} for an {@code $last}-expression for the given {@link AggregationExpression}.
*
* @param expr
* @return
*/
public GroupOperationBuilder last(AggregationExpression expr) {
return newBuilder(GroupOps.LAST, null, expr);
}
/**
* Generates an {@link GroupOperationBuilder} for a {@code $first}-expression for the given field-reference.
*
@@ -213,16 +203,6 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
return newBuilder(GroupOps.FIRST, reference, null);
}
/**
* Generates an {@link GroupOperationBuilder} for a {@code $first}-expression for the given {@link AggregationExpression}.
*
* @param expr
* @return
*/
public GroupOperationBuilder first(AggregationExpression expr) {
return newBuilder(GroupOps.FIRST, null, expr);
}
/**
* Generates an {@link GroupOperationBuilder} for an {@code $avg}-expression for the given field-reference.
*
@@ -233,16 +213,6 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
return newBuilder(GroupOps.AVG, reference, null);
}
/**
* Generates an {@link GroupOperationBuilder} for an {@code $avg}-expression for the given {@link AggregationExpression}.
*
* @param expr
* @return
*/
public GroupOperationBuilder avg(AggregationExpression expr) {
return newBuilder(GroupOps.AVG, null, expr);
}
/**
* Generates an {@link GroupOperationBuilder} for an {@code $push}-expression for the given field-reference.
*
@@ -277,16 +247,6 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
return newBuilder(GroupOps.MIN, reference, null);
}
/**
* Generates an {@link GroupOperationBuilder} for an {@code $min}-expression that for the given {@link AggregationExpression}.
*
* @param expr
* @return
*/
public GroupOperationBuilder min(AggregationExpression expr) {
return newBuilder(GroupOps.MIN, null, expr);
}
/**
* Generates an {@link GroupOperationBuilder} for an {@code $max}-expression that for the given field-reference.
*
@@ -297,16 +257,6 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
return newBuilder(GroupOps.MAX, reference, null);
}
/**
* Generates an {@link GroupOperationBuilder} for an {@code $max}-expression that for the given {@link AggregationExpression}.
*
* @param expr
* @return
*/
public GroupOperationBuilder max(AggregationExpression expr) {
return newBuilder(GroupOps.MAX, null, expr);
}
private GroupOperationBuilder newBuilder(Keyword keyword, String reference, Object value) {
return new GroupOperationBuilder(this, new Operation(keyword, null, reference, value));
}
@@ -419,11 +369,6 @@ public class GroupOperation implements FieldsExposingAggregationOperation {
public Object getValue(AggregationOperationContext context) {
if (reference == null) {
if (value instanceof AggregationExpression) {
return ((AggregationExpression) value).toDbObject(context);
}
return value;
}

View File

@@ -121,10 +121,6 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
return new ExpressionProjectionOperationBuilder(expression, this, params);
}
public ProjectionOperationBuilder and(AggregationExpression expression) {
return new ProjectionOperationBuilder(expression, this, null);
}
/**
* Excludes the given fields from the projection.
*
@@ -424,13 +420,9 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
if (this.previousProjection != null) {
return this.operation.andReplaceLastOneWith(this.previousProjection.withAlias(alias));
} else {
return this.operation.and(new FieldProjection(Fields.field(alias, name), null));
}
if (value instanceof AggregationExpression) {
return this.operation.and(new ExpressionProjection(Fields.field(alias), (AggregationExpression) value));
}
return this.operation.and(new FieldProjection(Fields.field(alias, name), null));
}
/**
@@ -560,10 +552,6 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
return project("mod", Fields.field(fieldReference));
}
public ProjectionOperationBuilder size() {
return project("size");
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
@@ -952,31 +940,4 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
*/
public abstract DBObject toDBObject(AggregationOperationContext context);
}
/**
* @author Thomas Darimont
*/
static class ExpressionProjection extends Projection {
private final AggregationExpression expression;
private final Field field;
/**
* Creates a new {@link ExpressionProjection}.
*
* @param field
* @param expression
*/
public ExpressionProjection(Field field, AggregationExpression expression) {
super(field);
this.field = field;
this.expression = expression;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject(field.getName(), expression.toDbObject(context));
}
}
}

View File

@@ -37,15 +37,11 @@ import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.data.convert.JodaTimeConverters;
import org.springframework.data.convert.Jsr310Converters;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.ThreeTenBackPortConverters;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.mongodb.core.convert.MongoConverters.BigDecimalToStringConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.BigIntegerToStringConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.NamedMongoScriptToDBObjectConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToNamedMongoScriptCoverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToStringConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
@@ -53,7 +49,6 @@ import org.springframework.data.mongodb.core.convert.MongoConverters.StringToURL
import org.springframework.data.mongodb.core.convert.MongoConverters.TermToStringConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.URLToStringConverter;
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
import org.springframework.data.util.CacheValue;
import org.springframework.util.Assert;
/**
@@ -80,9 +75,9 @@ public class CustomConversions {
private final List<Object> converters;
private final Map<ConvertiblePair, CacheValue<Class<?>>> customReadTargetTypes;
private final Map<ConvertiblePair, CacheValue<Class<?>>> customWriteTargetTypes;
private final Map<Class<?>, CacheValue<Class<?>>> rawWriteTargetTypes;
private final Map<ConvertiblePair, CacheValue> customReadTargetTypes;
private final Map<ConvertiblePair, CacheValue> customWriteTargetTypes;
private final Map<Class<?>, CacheValue> rawWriteTargetTypes;
/**
* Creates an empty {@link CustomConversions} object.
@@ -103,9 +98,9 @@ public class CustomConversions {
this.readingPairs = new LinkedHashSet<ConvertiblePair>();
this.writingPairs = new LinkedHashSet<ConvertiblePair>();
this.customSimpleTypes = new HashSet<Class<?>>();
this.customReadTargetTypes = new ConcurrentHashMap<ConvertiblePair, CacheValue<Class<?>>>();
this.customWriteTargetTypes = new ConcurrentHashMap<ConvertiblePair, CacheValue<Class<?>>>();
this.rawWriteTargetTypes = new ConcurrentHashMap<Class<?>, CacheValue<Class<?>>>();
this.customReadTargetTypes = new ConcurrentHashMap<ConvertiblePair, CacheValue>();
this.customWriteTargetTypes = new ConcurrentHashMap<ConvertiblePair, CacheValue>();
this.rawWriteTargetTypes = new ConcurrentHashMap<Class<?>, CacheValue>();
List<Object> toRegister = new ArrayList<Object>();
@@ -120,13 +115,9 @@ public class CustomConversions {
toRegister.add(StringToURLConverter.INSTANCE);
toRegister.add(DBObjectToStringConverter.INSTANCE);
toRegister.add(TermToStringConverter.INSTANCE);
toRegister.add(NamedMongoScriptToDBObjectConverter.INSTANCE);
toRegister.add(DBObjectToNamedMongoScriptCoverter.INSTANCE);
toRegister.addAll(JodaTimeConverters.getConvertersToRegister());
toRegister.addAll(GeoConverters.getConvertersToRegister());
toRegister.addAll(Jsr310Converters.getConvertersToRegister());
toRegister.addAll(ThreeTenBackPortConverters.getConvertersToRegister());
for (Object c : toRegister) {
registerConversion(c);
@@ -388,16 +379,16 @@ public class CustomConversions {
* @param producer the {@link Producer} to create values to cache, must not be {@literal null}.
* @return
*/
private static <T> Class<?> getOrCreateAndCache(T key, Map<T, CacheValue<Class<?>>> cache, Producer producer) {
private static <T> Class<?> getOrCreateAndCache(T key, Map<T, CacheValue> cache, Producer producer) {
CacheValue<Class<?>> cacheValue = cache.get(key);
CacheValue cacheValue = cache.get(key);
if (cacheValue != null) {
return cacheValue.getValue();
return cacheValue.getType();
}
Class<?> type = producer.get();
cache.put(key, CacheValue.<Class<?>> ofNullable(type));
cache.put(key, CacheValue.of(type));
return type;
}
@@ -424,4 +415,30 @@ public class CustomConversions {
return source.toString();
}
}
/**
* Wrapper to safely store {@literal null} values in the type cache.
*
* @author Patryk Wasik
* @author Oliver Gierke
* @author Thomas Darimont
*/
private static class CacheValue {
private static final CacheValue ABSENT = new CacheValue(null);
private final Class<?> type;
public CacheValue(Class<?> type) {
this.type = type;
}
public Class<?> getType() {
return type;
}
static CacheValue of(Class<?> type) {
return type == null ? ABSENT : new CacheValue(type);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2014 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.
@@ -18,7 +18,6 @@ package org.springframework.data.mongodb.core.convert;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
/**
@@ -26,7 +25,6 @@ import com.mongodb.DBRef;
*
* @author Thomas Darimont
* @author Oliver Gierke
* @author Christoph Strobl
* @since 1.4
*/
public interface DbRefResolver {
@@ -55,13 +53,4 @@ public interface DbRefResolver {
*/
DBRef createDbRef(org.springframework.data.mongodb.core.mapping.DBRef annotation, MongoPersistentEntity<?> entity,
Object id);
/**
* Actually loads the {@link DBRef} from the datasource.
*
* @param dbRef must not be {@literal null}.
* @return
* @since 1.7
*/
DBObject fetch(DBRef dbRef);
}

View File

@@ -15,8 +15,8 @@
*/
package org.springframework.data.mongodb.core.convert;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.BeanWrapper;
import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator;
import org.springframework.data.mapping.model.SpELContext;
import org.springframework.data.mapping.model.SpELExpressionEvaluator;
@@ -60,19 +60,19 @@ class DefaultDbRefProxyHandler implements DbRefProxyHandler {
return proxy;
}
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(property);
MongoPersistentProperty idProperty = entity.getIdProperty();
if (idProperty.usePropertyAccess()) {
MongoPersistentEntity<?> persistentEntity = mappingContext.getPersistentEntity(property);
MongoPersistentProperty idProperty = persistentEntity.getIdProperty();
if(idProperty.usePropertyAccess()) {
return proxy;
}
SpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator(proxy, spELContext);
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(proxy);
BeanWrapper<Object> proxyWrapper = BeanWrapper.create(proxy, null);
DBObject object = new BasicDBObject(idProperty.getFieldName(), source.getId());
ObjectPath objectPath = ObjectPath.ROOT.push(proxy, entity, null);
accessor.setProperty(idProperty, resolver.getValueInternal(idProperty, object, evaluator, objectPath));
ObjectPath objectPath = ObjectPath.ROOT.push(proxy, persistentEntity, null);
proxyWrapper.setProperty(idProperty, resolver.getValueInternal(idProperty, object, evaluator, objectPath));
return proxy;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2014 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.
@@ -39,8 +39,9 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.objenesis.ObjenesisStd;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import com.mongodb.DBObject;
import com.mongodb.DB;
import com.mongodb.DBRef;
/**
@@ -49,7 +50,6 @@ import com.mongodb.DBRef;
*
* @author Thomas Darimont
* @author Oliver Gierke
* @author Christoph Strobl
* @since 1.4
*/
public class DefaultDbRefResolver implements DbRefResolver {
@@ -97,16 +97,11 @@ public class DefaultDbRefResolver implements DbRefResolver {
@Override
public DBRef createDbRef(org.springframework.data.mongodb.core.mapping.DBRef annotation,
MongoPersistentEntity<?> entity, Object id) {
return new DBRef(entity.getCollection(), id);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.convert.DbRefResolver#fetch(com.mongodb.DBRef)
*/
@Override
public DBObject fetch(DBRef dbRef) {
return ReflectiveDBRefResolver.fetch(mongoDbFactory, dbRef);
DB db = mongoDbFactory.getDb();
db = annotation != null && StringUtils.hasText(annotation.db()) ? mongoDbFactory.getDb(annotation.db()) : db;
return new DBRef(db, entity.getCollection(), id);
}
/**
@@ -287,7 +282,7 @@ public class DefaultDbRefResolver implements DbRefResolver {
StringBuilder description = new StringBuilder();
if (dbref != null) {
description.append(dbref.getCollectionName());
description.append(dbref.getRef());
description.append(":");
description.append(dbref.getId());
} else {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014 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.
@@ -30,18 +30,9 @@ import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
import org.springframework.data.geo.Shape;
import org.springframework.data.mongodb.core.geo.GeoJson;
import org.springframework.data.mongodb.core.geo.GeoJsonGeometryCollection;
import org.springframework.data.mongodb.core.geo.GeoJsonLineString;
import org.springframework.data.mongodb.core.geo.GeoJsonMultiLineString;
import org.springframework.data.mongodb.core.geo.GeoJsonMultiPoint;
import org.springframework.data.mongodb.core.geo.GeoJsonMultiPolygon;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon;
import org.springframework.data.mongodb.core.geo.Sphere;
import org.springframework.data.mongodb.core.query.GeoCommand;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
@@ -52,7 +43,6 @@ import com.mongodb.DBObject;
*
* @author Thomas Darimont
* @author Oliver Gierke
* @author Christoph Strobl
* @since 1.5
*/
abstract class GeoConverters {
@@ -67,7 +57,6 @@ abstract class GeoConverters {
*
* @return
*/
@SuppressWarnings("unchecked")
public static Collection<? extends Object> getConvertersToRegister() {
return Arrays.asList( //
BoxToDbObjectConverter.INSTANCE //
@@ -80,17 +69,7 @@ abstract class GeoConverters {
, DbObjectToSphereConverter.INSTANCE //
, DbObjectToPointConverter.INSTANCE //
, PointToDbObjectConverter.INSTANCE //
, GeoCommandToDbObjectConverter.INSTANCE //
, GeoJsonToDbObjectConverter.INSTANCE //
, GeoJsonPointToDbObjectConverter.INSTANCE //
, GeoJsonPolygonToDbObjectConverter.INSTANCE //
, DbObjectToGeoJsonPointConverter.INSTANCE //
, DbObjectToGeoJsonPolygonConverter.INSTANCE //
, DbObjectToGeoJsonLineStringConverter.INSTANCE //
, DbObjectToGeoJsonMultiLineStringConverter.INSTANCE //
, DbObjectToGeoJsonMultiPointConverter.INSTANCE //
, DbObjectToGeoJsonMultiPolygonConverter.INSTANCE //
, DbObjectToGeoJsonGeometryCollectionConverter.INSTANCE);
, GeoCommandToDbObjectConverter.INSTANCE);
}
/**
@@ -100,7 +79,7 @@ abstract class GeoConverters {
* @since 1.5
*/
@ReadingConverter
static enum DbObjectToPointConverter implements Converter<DBObject, Point> {
public static enum DbObjectToPointConverter implements Converter<DBObject, Point> {
INSTANCE;
@@ -123,7 +102,7 @@ abstract class GeoConverters {
* @author Thomas Darimont
* @since 1.5
*/
static enum PointToDbObjectConverter implements Converter<Point, DBObject> {
public static enum PointToDbObjectConverter implements Converter<Point, DBObject> {
INSTANCE;
@@ -144,7 +123,7 @@ abstract class GeoConverters {
* @since 1.5
*/
@WritingConverter
static enum BoxToDbObjectConverter implements Converter<Box, DBObject> {
public static enum BoxToDbObjectConverter implements Converter<Box, DBObject> {
INSTANCE;
@@ -173,7 +152,7 @@ abstract class GeoConverters {
* @since 1.5
*/
@ReadingConverter
static enum DbObjectToBoxConverter implements Converter<DBObject, Box> {
public static enum DbObjectToBoxConverter implements Converter<DBObject, Box> {
INSTANCE;
@@ -201,7 +180,7 @@ abstract class GeoConverters {
* @author Thomas Darimont
* @since 1.5
*/
static enum CircleToDbObjectConverter implements Converter<Circle, DBObject> {
public static enum CircleToDbObjectConverter implements Converter<Circle, DBObject> {
INSTANCE;
@@ -231,7 +210,7 @@ abstract class GeoConverters {
* @since 1.5
*/
@ReadingConverter
static enum DbObjectToCircleConverter implements Converter<DBObject, Circle> {
public static enum DbObjectToCircleConverter implements Converter<DBObject, Circle> {
INSTANCE;
@@ -272,7 +251,7 @@ abstract class GeoConverters {
* @author Thomas Darimont
* @since 1.5
*/
static enum SphereToDbObjectConverter implements Converter<Sphere, DBObject> {
public static enum SphereToDbObjectConverter implements Converter<Sphere, DBObject> {
INSTANCE;
@@ -302,7 +281,7 @@ abstract class GeoConverters {
* @since 1.5
*/
@ReadingConverter
static enum DbObjectToSphereConverter implements Converter<DBObject, Sphere> {
public static enum DbObjectToSphereConverter implements Converter<DBObject, Sphere> {
INSTANCE;
@@ -343,7 +322,7 @@ abstract class GeoConverters {
* @author Thomas Darimont
* @since 1.5
*/
static enum PolygonToDbObjectConverter implements Converter<Polygon, DBObject> {
public static enum PolygonToDbObjectConverter implements Converter<Polygon, DBObject> {
INSTANCE;
@@ -378,7 +357,7 @@ abstract class GeoConverters {
* @since 1.5
*/
@ReadingConverter
static enum DbObjectToPolygonConverter implements Converter<DBObject, Polygon> {
public static enum DbObjectToPolygonConverter implements Converter<DBObject, Polygon> {
INSTANCE;
@@ -413,7 +392,7 @@ abstract class GeoConverters {
* @author Thomas Darimont
* @since 1.5
*/
static enum GeoCommandToDbObjectConverter implements Converter<GeoCommand, DBObject> {
public static enum GeoCommandToDbObjectConverter implements Converter<GeoCommand, DBObject> {
INSTANCE;
@@ -422,7 +401,6 @@ abstract class GeoConverters {
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
@SuppressWarnings("rawtypes")
public DBObject convert(GeoCommand source) {
if (source == null) {
@@ -433,10 +411,6 @@ abstract class GeoConverters {
Shape shape = source.getShape();
if (shape instanceof GeoJson) {
return GeoJsonToDbObjectConverter.INSTANCE.convert((GeoJson) shape);
}
if (shape instanceof Box) {
argument.add(toList(((Box) shape).getFirst()));
@@ -468,377 +442,7 @@ abstract class GeoConverters {
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
@SuppressWarnings("rawtypes")
static enum GeoJsonToDbObjectConverter implements Converter<GeoJson, DBObject> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public DBObject convert(GeoJson source) {
if (source == null) {
return null;
}
DBObject dbo = new BasicDBObject("type", source.getType());
if (source instanceof GeoJsonGeometryCollection) {
BasicDBList dbl = new BasicDBList();
for (GeoJson geometry : ((GeoJsonGeometryCollection) source).getCoordinates()) {
dbl.add(convert(geometry));
}
dbo.put("geometries", dbl);
} else {
dbo.put("coordinates", convertIfNecessarry(source.getCoordinates()));
}
return dbo;
}
private Object convertIfNecessarry(Object candidate) {
if (candidate instanceof GeoJson) {
return convertIfNecessarry(((GeoJson) candidate).getCoordinates());
}
if (candidate instanceof Iterable) {
BasicDBList dbl = new BasicDBList();
for (Object element : (Iterable) candidate) {
dbl.add(convertIfNecessarry(element));
}
return dbl;
}
if (candidate instanceof Point) {
return toList((Point) candidate);
}
return candidate;
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
static enum GeoJsonPointToDbObjectConverter implements Converter<GeoJsonPoint, DBObject> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public DBObject convert(GeoJsonPoint source) {
return GeoJsonToDbObjectConverter.INSTANCE.convert(source);
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
static enum GeoJsonPolygonToDbObjectConverter implements Converter<GeoJsonPolygon, DBObject> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public DBObject convert(GeoJsonPolygon source) {
return GeoJsonToDbObjectConverter.INSTANCE.convert(source);
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonPointConverter implements Converter<DBObject, GeoJsonPoint> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
@SuppressWarnings("unchecked")
public GeoJsonPoint convert(DBObject source) {
if (source == null) {
return null;
}
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "Point"),
String.format("Cannot convert type '%s' to Point.", source.get("type")));
List<Double> dbl = (List<Double>) source.get("coordinates");
return new GeoJsonPoint(dbl.get(0).doubleValue(), dbl.get(1).doubleValue());
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonPolygonConverter implements Converter<DBObject, GeoJsonPolygon> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public GeoJsonPolygon convert(DBObject source) {
if (source == null) {
return null;
}
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "Polygon"),
String.format("Cannot convert type '%s' to Polygon.", source.get("type")));
return toGeoJsonPolygon((BasicDBList) source.get("coordinates"));
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonMultiPolygonConverter implements Converter<DBObject, GeoJsonMultiPolygon> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public GeoJsonMultiPolygon convert(DBObject source) {
if (source == null) {
return null;
}
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "MultiPolygon"),
String.format("Cannot convert type '%s' to MultiPolygon.", source.get("type")));
BasicDBList dbl = (BasicDBList) source.get("coordinates");
List<GeoJsonPolygon> polygones = new ArrayList<GeoJsonPolygon>();
for (Object polygon : dbl) {
polygones.add(toGeoJsonPolygon((BasicDBList) polygon));
}
return new GeoJsonMultiPolygon(polygones);
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonLineStringConverter implements Converter<DBObject, GeoJsonLineString> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public GeoJsonLineString convert(DBObject source) {
if (source == null) {
return null;
}
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "LineString"),
String.format("Cannot convert type '%s' to LineString.", source.get("type")));
BasicDBList cords = (BasicDBList) source.get("coordinates");
return new GeoJsonLineString(toListOfPoint(cords));
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonMultiPointConverter implements Converter<DBObject, GeoJsonMultiPoint> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public GeoJsonMultiPoint convert(DBObject source) {
if (source == null) {
return null;
}
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "MultiPoint"),
String.format("Cannot convert type '%s' to MultiPoint.", source.get("type")));
BasicDBList cords = (BasicDBList) source.get("coordinates");
return new GeoJsonMultiPoint(toListOfPoint(cords));
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonMultiLineStringConverter implements Converter<DBObject, GeoJsonMultiLineString> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@Override
public GeoJsonMultiLineString convert(DBObject source) {
if (source == null) {
return null;
}
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "MultiLineString"),
String.format("Cannot convert type '%s' to MultiLineString.", source.get("type")));
List<GeoJsonLineString> lines = new ArrayList<GeoJsonLineString>();
BasicDBList cords = (BasicDBList) source.get("coordinates");
for (Object line : cords) {
lines.add(new GeoJsonLineString(toListOfPoint((BasicDBList) line)));
}
return new GeoJsonMultiLineString(lines);
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
static enum DbObjectToGeoJsonGeometryCollectionConverter implements Converter<DBObject, GeoJsonGeometryCollection> {
INSTANCE;
/*
* (non-Javadoc)
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
@SuppressWarnings("rawtypes")
@Override
public GeoJsonGeometryCollection convert(DBObject source) {
if (source == null) {
return null;
}
Assert.isTrue(ObjectUtils.nullSafeEquals(source.get("type"), "GeometryCollection"),
String.format("Cannot convert type '%s' to GeometryCollection.", source.get("type")));
List<GeoJson<?>> geometries = new ArrayList<GeoJson<?>>();
for (Object o : (List) source.get("geometries")) {
geometries.add(convertGeometries((DBObject) o));
}
return new GeoJsonGeometryCollection(geometries);
}
private static GeoJson<?> convertGeometries(DBObject source) {
Object type = source.get("type");
if (ObjectUtils.nullSafeEquals(type, "Point")) {
return DbObjectToGeoJsonPointConverter.INSTANCE.convert(source);
}
if (ObjectUtils.nullSafeEquals(type, "MultiPoint")) {
return DbObjectToGeoJsonMultiPointConverter.INSTANCE.convert(source);
}
if (ObjectUtils.nullSafeEquals(type, "LineString")) {
return DbObjectToGeoJsonLineStringConverter.INSTANCE.convert(source);
}
if (ObjectUtils.nullSafeEquals(type, "MultiLineString")) {
return DbObjectToGeoJsonMultiLineStringConverter.INSTANCE.convert(source);
}
if (ObjectUtils.nullSafeEquals(type, "Polygon")) {
return DbObjectToGeoJsonPolygonConverter.INSTANCE.convert(source);
}
if (ObjectUtils.nullSafeEquals(type, "MultiPolygon")) {
return DbObjectToGeoJsonMultiPolygonConverter.INSTANCE.convert(source);
}
throw new IllegalArgumentException(String.format("Cannot convert unknown GeoJson type %s", type));
}
}
static List<Double> toList(Point point) {
return Arrays.asList(point.getX(), point.getY());
}
/**
* Converts a coordinate pairs nested in in {@link BasicDBList} into {@link GeoJsonPoint}s.
*
* @param listOfCoordinatePairs
* @return
* @since 1.7
*/
@SuppressWarnings("unchecked")
static List<Point> toListOfPoint(BasicDBList listOfCoordinatePairs) {
List<Point> points = new ArrayList<Point>();
for (Object point : listOfCoordinatePairs) {
Assert.isInstanceOf(List.class, point);
List<Double> coordinatesList = (List<Double>) point;
points.add(new GeoJsonPoint(coordinatesList.get(0).doubleValue(), coordinatesList.get(1).doubleValue()));
}
return points;
}
/**
* Converts a coordinate pairs nested in in {@link BasicDBList} into {@link GeoJsonPolygon}.
*
* @param dbList
* @return
* @since 1.7
*/
static GeoJsonPolygon toGeoJsonPolygon(BasicDBList dbList) {
return new GeoJsonPolygon(toListOfPoint((BasicDBList) dbList.get(0)));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 by the original author(s).
* Copyright 2011-2014 by the original author(s).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,19 +29,18 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.CollectionFactory;
import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.convert.CollectionFactory;
import org.springframework.data.convert.EntityInstantiator;
import org.springframework.data.convert.TypeMapper;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.AssociationHandler;
import org.springframework.data.mapping.PersistentPropertyAccessor;
import org.springframework.data.mapping.PreferredConstructor.Parameter;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
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.ParameterValueProvider;
@@ -250,18 +249,16 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity);
S instance = instantiator.createInstance(entity, provider);
final PersistentPropertyAccessor accessor = new ConvertingPropertyAccessor(entity.getPropertyAccessor(instance),
conversionService);
final BeanWrapper<S> wrapper = BeanWrapper.create(instance, conversionService);
final MongoPersistentProperty idProperty = entity.getIdProperty();
final S result = instance;
final S result = wrapper.getBean();
// make sure id property is set before all other properties
Object idValue = null;
if (idProperty != null) {
idValue = getValueInternal(idProperty, dbo, evaluator, path);
accessor.setProperty(idProperty, idValue);
wrapper.setProperty(idProperty, idValue);
}
final ObjectPath currentPath = path.push(result, entity, idValue);
@@ -279,7 +276,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return;
}
accessor.setProperty(prop, getValueInternal(prop, dbo, evaluator, currentPath));
wrapper.setProperty(prop, getValueInternal(prop, dbo, evaluator, currentPath));
}
});
@@ -301,7 +298,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
DbRefResolverCallback callback = new DefaultDbRefResolverCallback(dbo, currentPath, evaluator,
MappingMongoConverter.this);
accessor.setProperty(property, dbRefResolver.resolveDbRef(property, dbref, callback, handler));
wrapper.setProperty(property, dbRefResolver.resolveDbRef(property, dbref, callback, handler));
}
});
@@ -401,13 +398,13 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
throw new MappingException("No mapping metadata found for entity of type " + obj.getClass().getName());
}
final PersistentPropertyAccessor accessor = entity.getPropertyAccessor(obj);
final BeanWrapper<Object> wrapper = BeanWrapper.create(obj, conversionService);
final MongoPersistentProperty idProperty = entity.getIdProperty();
if (!dbo.containsField("_id") && null != idProperty) {
try {
Object id = accessor.getProperty(idProperty);
Object id = wrapper.getProperty(idProperty, Object.class);
dbo.put("_id", idMapper.convertId(id));
} catch (ConversionException ignored) {}
}
@@ -420,7 +417,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return;
}
Object propertyObj = accessor.getProperty(prop);
Object propertyObj = wrapper.getProperty(prop);
if (null != propertyObj) {
@@ -434,12 +431,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
});
entity.doWithAssociations(new AssociationHandler<MongoPersistentProperty>() {
public void doWithAssociation(Association<MongoPersistentProperty> association) {
MongoPersistentProperty inverseProp = association.getInverse();
Object propertyObj = accessor.getProperty(inverseProp);
Class<?> type = inverseProp.getType();
Object propertyObj = wrapper.getProperty(inverseProp, type);
if (null != propertyObj) {
writePropertyInternal(propertyObj, dbo, inverseProp);
}
@@ -509,7 +504,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
Object existingValue = accessor.get(prop);
BasicDBObject propDbObj = existingValue instanceof BasicDBObject ? (BasicDBObject) existingValue
: new BasicDBObject();
addCustomTypeKeyIfNecessary(ClassTypeInformation.from(prop.getRawType()), obj, propDbObj);
addCustomTypeKeyIfNecessary(type, obj, propDbObj);
MongoPersistentEntity<?> entity = isSubtype(prop.getType(), obj.getClass())
? mappingContext.getPersistentEntity(obj.getClass()) : mappingContext.getPersistentEntity(type);
@@ -740,7 +735,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
/**
* Adds custom type information to the given {@link DBObject} if necessary. That is if the value is not the same as
* the one given. This is usually the case if you store a subtype of the actual declared type of the property.
*
*
* @param type
* @param value must not be {@literal null}.
* @param dbObject must not be {@literal null}.
@@ -847,8 +842,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
if (target.getClass().equals(idProperty.getType())) {
id = target;
} else {
PersistentPropertyAccessor accessor = targetEntity.getPropertyAccessor(target);
id = accessor.getProperty(idProperty);
BeanWrapper<Object> wrapper = BeanWrapper.create(target, conversionService);
id = wrapper.getProperty(idProperty, Object.class);
}
if (null == id) {
@@ -1195,7 +1190,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return (T) dbref;
}
Object object = dbref == null ? null : path.getPathItem(dbref.getId(), dbref.getCollectionName());
Object object = dbref == null ? null : path.getPathItem(dbref.getId(), dbref.getRef());
if (object != null) {
return (T) object;
@@ -1211,7 +1206,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
* @return
*/
DBObject readRef(DBRef ref) {
return dbRefResolver.fetch(ref);
return ref.fetch();
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -20,7 +20,6 @@ import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import org.bson.types.Code;
import org.bson.types.ObjectId;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.TypeDescriptor;
@@ -28,11 +27,8 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mongodb.core.query.Term;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBObject;
/**
@@ -182,50 +178,4 @@ abstract class MongoConverters {
return source == null ? null : source.getFormatted();
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
public static enum DBObjectToNamedMongoScriptCoverter implements Converter<DBObject, NamedMongoScript> {
INSTANCE;
@Override
public NamedMongoScript convert(DBObject source) {
if (source == null) {
return null;
}
String id = source.get("_id").toString();
Object rawValue = source.get("value");
return new NamedMongoScript(id, ((Code) rawValue).getCode());
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
public static enum NamedMongoScriptToDBObjectConverter implements Converter<NamedMongoScript, DBObject> {
INSTANCE;
@Override
public DBObject convert(NamedMongoScript source) {
if (source == null) {
return new BasicDBObject();
}
BasicDBObjectBuilder builder = new BasicDBObjectBuilder();
builder.append("_id", source.getName());
builder.append("value", new Code(source.getCode()));
return builder.get();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -226,7 +226,7 @@ public class QueryMapper {
protected DBObject getMappedKeyword(Keyword keyword, MongoPersistentEntity<?> entity) {
// $or/$nor
if (keyword.isOrOrNor() || (keyword.hasIterableValue() && !keyword.isGeometry())) {
if (keyword.isOrOrNor() || keyword.hasIterableValue()) {
Iterable<?> conditions = keyword.getValue();
BasicDBList newConditions = new BasicDBList();
@@ -394,7 +394,7 @@ public class QueryMapper {
if (source instanceof DBRef) {
DBRef ref = (DBRef) source;
return new DBRef(ref.getCollectionName(), convertId(ref.getId()));
return new DBRef(ref.getDB(), ref.getRef(), convertId(ref.getId()));
}
if (source instanceof Iterable) {
@@ -556,16 +556,6 @@ public class QueryMapper {
return key.matches(N_OR_PATTERN);
}
/**
* Returns whether the current keyword is the {@code $geometry} keyword.
*
* @return
* @since 1.8
*/
public boolean isGeometry() {
return "$geometry".equalsIgnoreCase(key);
}
public boolean hasIterableValue() {
return value instanceof Iterable;
}

View File

@@ -1,66 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.convert;
import static org.springframework.data.mongodb.util.MongoClientVersion.*;
import static org.springframework.util.ReflectionUtils.*;
import java.lang.reflect.Method;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.util.Assert;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
/**
* {@link ReflectiveDBRefResolver} provides reflective access to {@link DBRef} API that is not consistently available
* for various driver versions.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
class ReflectiveDBRefResolver {
private static final Method FETCH_METHOD;
static {
FETCH_METHOD = findMethod(DBRef.class, "fetch");
}
/**
* Fetches the object referenced from the database either be directly calling {@link DBRef#fetch()} or
* {@link DBCollection#findOne(Object)}.
*
* @param db can be {@literal null} when using MongoDB Java driver in version 2.x.
* @param ref must not be {@literal null}.
* @return the document that this references.
*/
public static DBObject fetch(MongoDbFactory factory, DBRef ref) {
Assert.notNull(ref, "DBRef to fetch must not be null!");
if (isMongo3Driver()) {
Assert.notNull(factory, "DbFactory to fetch DB from must not be null!");
return factory.getDb().getCollection(ref.getCollectionName()).findOne(ref.getId());
}
return (DBObject) invokeMethod(FETCH_METHOD, ref);
}
}

View File

@@ -66,8 +66,8 @@ public class UpdateMapper extends QueryMapper {
*/
@Override
protected Object delegateConvertToMongoType(Object source, MongoPersistentEntity<?> entity) {
return entity == null ? super.delegateConvertToMongoType(source, null)
: converter.convertToMongoType(source, getTypeHintForEntity(entity));
return converter.convertToMongoType(source,
entity == null ? ClassTypeInformation.OBJECT : getTypeHintForEntity(source, entity));
}
/*
@@ -90,7 +90,7 @@ public class UpdateMapper extends QueryMapper {
return getMappedUpdateModifier(field, rawValue);
}
return super.getMappedObjectForField(field, getMappedValue(field, rawValue));
return super.getMappedObjectForField(field, rawValue);
}
private Entry<String, Object> getMappedUpdateModifier(Field field, Object rawValue) {
@@ -141,18 +141,21 @@ public class UpdateMapper extends QueryMapper {
return new BasicDBObject(modifier.getKey(), value);
}
private TypeInformation<?> getTypeHintForEntity(MongoPersistentEntity<?> entity) {
return processTypeHintForNestedDocuments(entity.getTypeInformation());
private TypeInformation<?> getTypeHintForEntity(Object source, MongoPersistentEntity<?> entity) {
return processTypeHintForNestedDocuments(source, entity.getTypeInformation());
}
private TypeInformation<?> processTypeHintForNestedDocuments(TypeInformation<?> info) {
private TypeInformation<?> processTypeHintForNestedDocuments(Object source, TypeInformation<?> info) {
Class<?> type = info.getActualType().getType();
if (type.isInterface() || java.lang.reflect.Modifier.isAbstract(type.getModifiers())) {
return info;
}
return NESTED_DOCUMENT;
if (!type.equals(source.getClass())) {
return info;
}
return NESTED_DOCUMENT;
}
/*

View File

@@ -1,42 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.geo;
/**
* Interface definition for structures defined in GeoJSON ({@link http://geojson.org/}) format.
*
* @author Christoph Strobl
* @since 1.7
*/
public interface GeoJson<T extends Iterable<?>> {
/**
* String value representing the type of the {@link GeoJson} object.
*
* @return will never be {@literal null}.
* @see http://geojson.org/geojson-spec.html#geojson-objects
*/
String getType();
/**
* The value of the coordinates member is always an {@link Iterable}. The structure for the elements within is
* determined by {@link #getType()} of geometry.
*
* @return will never be {@literal null}.
* @see http://geojson.org/geojson-spec.html#geometry-objects
*/
T getCoordinates();
}

View File

@@ -1,96 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.geo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Defines a {@link GeoJsonGeometryCollection} that consists of a {@link List} of {@link GeoJson} objects.
*
* @author Christoph Strobl
* @since 1.7
* @see http://geojson.org/geojson-spec.html#geometry-collection
*/
public class GeoJsonGeometryCollection implements GeoJson<Iterable<GeoJson<?>>> {
private static final String TYPE = "GeometryCollection";
private final List<GeoJson<?>> geometries = new ArrayList<GeoJson<?>>();
/**
* Creates a new {@link GeoJsonGeometryCollection} for the given {@link GeoJson} instances.
*
* @param geometries
*/
public GeoJsonGeometryCollection(List<GeoJson<?>> geometries) {
Assert.notNull(geometries, "Geometries must not be null!");
this.geometries.addAll(geometries);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType()
*/
@Override
public String getType() {
return TYPE;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates()
*/
@Override
public Iterable<GeoJson<?>> getCoordinates() {
return Collections.unmodifiableList(this.geometries);
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.geometries);
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof GeoJsonGeometryCollection)) {
return false;
}
GeoJsonGeometryCollection other = (GeoJsonGeometryCollection) obj;
return ObjectUtils.nullSafeEquals(this.geometries, other.geometries);
}
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.geo;
import java.util.List;
import org.springframework.data.geo.Point;
/**
* {@link GeoJsonLineString} is defined as list of at least 2 {@link Point}s.
*
* @author Christoph Strobl
* @since 1.7
* @see http://geojson.org/geojson-spec.html#linestring
*/
public class GeoJsonLineString extends GeoJsonMultiPoint {
private static final String TYPE = "LineString";
/**
* Creates a new {@link GeoJsonLineString} for the given {@link Point}s.
*
* @param points must not be {@literal null} and have at least 2 entries.
*/
public GeoJsonLineString(List<Point> points) {
super(points);
}
/**
* Creates a new {@link GeoJsonLineString} for the given {@link Point}s.
*
* @param first must not be {@literal null}
* @param second must not be {@literal null}
* @param others can be {@literal null}
*/
public GeoJsonLineString(Point first, Point second, Point... others) {
super(first, second, others);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJsonMultiPoint#getType()
*/
@Override
public String getType() {
return TYPE;
}
}

View File

@@ -1,341 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.geo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.data.geo.Point;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
/**
* A Jackson {@link Module} to register custom {@link JsonSerializer} and {@link JsonDeserializer}s for GeoJSON types.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
public class GeoJsonModule extends SimpleModule {
private static final long serialVersionUID = -8723016728655643720L;
public GeoJsonModule() {
addDeserializer(GeoJsonPoint.class, new GeoJsonPointDeserializer());
addDeserializer(GeoJsonMultiPoint.class, new GeoJsonMultiPointDeserializer());
addDeserializer(GeoJsonLineString.class, new GeoJsonLineStringDeserializer());
addDeserializer(GeoJsonMultiLineString.class, new GeoJsonMultiLineStringDeserializer());
addDeserializer(GeoJsonPolygon.class, new GeoJsonPolygonDeserializer());
addDeserializer(GeoJsonMultiPolygon.class, new GeoJsonMultiPolygonDeserializer());
}
/**
* @author Christoph Strobl
* @since 1.7
*/
private static abstract class GeoJsonDeserializer<T extends GeoJson<?>> extends JsonDeserializer<T> {
/*
* (non-Javadoc)
* @see com.fasterxml.jackson.databind.JsonDeserializer#deserialize(com.fasterxml.jackson.core.JsonParser, com.fasterxml.jackson.databind.DeserializationContext)
*/
@Override
public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode node = jp.readValueAsTree();
JsonNode coordinates = node.get("coordinates");
if (coordinates != null && coordinates.isArray()) {
return doDeserialize((ArrayNode) coordinates);
}
return null;
}
/**
* Perform the actual deserialization given the {@literal coordinates} as {@link ArrayNode}.
*
* @param coordinates
* @return
*/
protected abstract T doDeserialize(ArrayNode coordinates);
/**
* Get the {@link GeoJsonPoint} representation of given {@link ArrayNode} assuming {@code node.[0]} represents
* {@literal x - coordinate} and {@code node.[1]} is {@literal y}.
*
* @param node can be {@literal null}.
* @return {@literal null} when given a {@code null} value.
*/
protected GeoJsonPoint toGeoJsonPoint(ArrayNode node) {
if (node == null) {
return null;
}
return new GeoJsonPoint(node.get(0).asDouble(), node.get(1).asDouble());
}
/**
* Get the {@link Point} representation of given {@link ArrayNode} assuming {@code node.[0]} represents
* {@literal x - coordinate} and {@code node.[1]} is {@literal y}.
*
* @param node can be {@literal null}.
* @return {@literal null} when given a {@code null} value.
*/
protected Point toPoint(ArrayNode node) {
if (node == null) {
return null;
}
return new Point(node.get(0).asDouble(), node.get(1).asDouble());
}
/**
* Get the points nested within given {@link ArrayNode}.
*
* @param node can be {@literal null}.
* @return {@literal empty list} when given a {@code null} value.
*/
protected List<Point> toPoints(ArrayNode node) {
if (node == null) {
return Collections.emptyList();
}
List<Point> points = new ArrayList<Point>(node.size());
for (JsonNode coordinatePair : node) {
if (coordinatePair.isArray()) {
points.add(toPoint((ArrayNode) coordinatePair));
}
}
return points;
}
protected GeoJsonLineString toLineString(ArrayNode node) {
return new GeoJsonLineString(toPoints((ArrayNode) node));
}
}
/**
* {@link JsonDeserializer} converting GeoJSON representation of {@literal Point}.
*
* <pre>
* <code>
* { "type": "Point", "coordinates": [10.0, 20.0] }
* </code>
* </pre>
*
* @author Christoph Strobl
* @since 1.7
*/
private static class GeoJsonPointDeserializer extends GeoJsonDeserializer<GeoJsonPoint> {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJsonModule.GeoJsonDeserializer#doDeserialize(com.fasterxml.jackson.databind.node.ArrayNode)
*/
@Override
protected GeoJsonPoint doDeserialize(ArrayNode coordinates) {
return toGeoJsonPoint(coordinates);
}
}
/**
* {@link JsonDeserializer} converting GeoJSON representation of {@literal LineString}.
*
* <pre>
* <code>
* {
* "type": "LineString",
* "coordinates": [
* [10.0, 20.0], [30.0, 40.0], [50.0, 60.0]
* ]
* }
* </code>
* </pre>
*
* @author Christoph Strobl
* @since 1.7
*/
private static class GeoJsonLineStringDeserializer extends GeoJsonDeserializer<GeoJsonLineString> {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJsonModule.GeoJsonDeserializer#doDeserialize(com.fasterxml.jackson.databind.node.ArrayNode)
*/
@Override
protected GeoJsonLineString doDeserialize(ArrayNode coordinates) {
return new GeoJsonLineString(toPoints(coordinates));
}
}
/**
* {@link JsonDeserializer} converting GeoJSON representation of {@literal MultiPoint}.
*
* <pre>
* <code>
* {
* "type": "MultiPoint",
* "coordinates": [
* [10.0, 20.0], [30.0, 40.0], [50.0, 60.0]
* ]
* }
* </code>
* </pre>
*
* @author Christoph Strobl
* @since 1.7
*/
private static class GeoJsonMultiPointDeserializer extends GeoJsonDeserializer<GeoJsonMultiPoint> {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJsonModule.GeoJsonDeserializer#doDeserialize(com.fasterxml.jackson.databind.node.ArrayNode)
*/
@Override
protected GeoJsonMultiPoint doDeserialize(ArrayNode coordinates) {
return new GeoJsonMultiPoint(toPoints(coordinates));
}
}
/**
* {@link JsonDeserializer} converting GeoJSON representation of {@literal MultiLineString}.
*
* <pre>
* <code>
* {
* "type": "MultiLineString",
* "coordinates": [
* [ [10.0, 20.0], [30.0, 40.0] ],
* [ [50.0, 60.0] , [70.0, 80.0] ]
* ]
* }
* </code>
* </pre>
*
* @author Christoph Strobl
* @since 1.7
*/
private static class GeoJsonMultiLineStringDeserializer extends GeoJsonDeserializer<GeoJsonMultiLineString> {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJsonModule.GeoJsonDeserializer#doDeserialize(com.fasterxml.jackson.databind.node.ArrayNode)
*/
@Override
protected GeoJsonMultiLineString doDeserialize(ArrayNode coordinates) {
List<GeoJsonLineString> lines = new ArrayList<GeoJsonLineString>(coordinates.size());
for (JsonNode lineString : coordinates) {
if (lineString.isArray()) {
lines.add(toLineString((ArrayNode) lineString));
}
}
return new GeoJsonMultiLineString(lines);
}
}
/**
* {@link JsonDeserializer} converting GeoJSON representation of {@literal Polygon}.
*
* <pre>
* <code>
* {
* "type": "Polygon",
* "coordinates": [
* [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]
* ]
* }
* </code>
* </pre>
*
* @author Christoph Strobl
* @since 1.7
*/
private static class GeoJsonPolygonDeserializer extends GeoJsonDeserializer<GeoJsonPolygon> {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJsonModule.GeoJsonDeserializer#doDeserialize(com.fasterxml.jackson.databind.node.ArrayNode)
*/
@Override
protected GeoJsonPolygon doDeserialize(ArrayNode coordinates) {
for (JsonNode ring : coordinates) {
// currently we do not support holes in polygons.
return new GeoJsonPolygon(toPoints((ArrayNode) ring));
}
return null;
}
}
/**
* {@link JsonDeserializer} converting GeoJSON representation of {@literal MultiPolygon}.
*
* <pre>
* <code>
* {
* "type": "MultiPolygon",
* "coordinates": [
* [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]],
* [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],
* [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]
* ]
* }
* </code>
* </pre>
*
* @author Christoph Strobl
* @since 1.7
*/
private static class GeoJsonMultiPolygonDeserializer extends GeoJsonDeserializer<GeoJsonMultiPolygon> {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJsonModule.GeoJsonDeserializer#doDeserialize(com.fasterxml.jackson.databind.node.ArrayNode)
*/
@Override
protected GeoJsonMultiPolygon doDeserialize(ArrayNode coordinates) {
List<GeoJsonPolygon> polygones = new ArrayList<GeoJsonPolygon>(coordinates.size());
for (JsonNode polygon : coordinates) {
for (JsonNode ring : (ArrayNode) polygon) {
polygones.add(new GeoJsonPolygon(toPoints((ArrayNode) ring)));
}
}
return new GeoJsonMultiPolygon(polygones);
}
}
}

View File

@@ -1,109 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.geo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* {@link GeoJsonMultiLineString} is defined as list of {@link GeoJsonLineString}s.
*
* @author Christoph Strobl
* @since 1.7
* @see http://geojson.org/geojson-spec.html#multilinestring
*/
public class GeoJsonMultiLineString implements GeoJson<Iterable<GeoJsonLineString>> {
private static final String TYPE = "MultiLineString";
private List<GeoJsonLineString> coordinates = new ArrayList<GeoJsonLineString>();
/**
* Creates new {@link GeoJsonMultiLineString} for the given {@link Point}s.
*
* @param lines must not be {@literal null}.
*/
public GeoJsonMultiLineString(List<Point>... lines) {
Assert.notEmpty(lines, "Points for MultiLineString must not be null!");
for (List<Point> line : lines) {
this.coordinates.add(new GeoJsonLineString(line));
}
}
/**
* Creates new {@link GeoJsonMultiLineString} for the given {@link GeoJsonLineString}s.
*
* @param lines must not be {@literal null}.
*/
public GeoJsonMultiLineString(List<GeoJsonLineString> lines) {
Assert.notNull(lines, "Lines for MultiLineString must not be null!");
this.coordinates.addAll(lines);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType()
*/
@Override
public String getType() {
return TYPE;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates()
*/
@Override
public Iterable<GeoJsonLineString> getCoordinates() {
return Collections.unmodifiableList(this.coordinates);
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.coordinates);
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof GeoJsonMultiLineString)) {
return false;
}
return ObjectUtils.nullSafeEquals(this.coordinates, ((GeoJsonMultiLineString) obj).coordinates);
}
}

View File

@@ -1,116 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.geo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.springframework.data.geo.Point;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* {@link GeoJsonMultiPoint} is defined as list of {@link Point}s.
*
* @author Christoph Strobl
* @since 1.7
* @see http://geojson.org/geojson-spec.html#multipoint
*/
public class GeoJsonMultiPoint implements GeoJson<Iterable<Point>> {
private static final String TYPE = "MultiPoint";
private final List<Point> points;
/**
* Creates a new {@link GeoJsonMultiPoint} for the given {@link Point}s.
*
* @param points points must not be {@literal null} and have at least 2 entries.
*/
public GeoJsonMultiPoint(List<Point> points) {
Assert.notNull(points, "Points must not be null.");
Assert.isTrue(points.size() >= 2, "Minimum of 2 Points required.");
this.points = new ArrayList<Point>(points);
}
/**
* Creates a new {@link GeoJsonMultiPoint} for the given {@link Point}s.
*
* @param first must not be {@literal null}.
* @param second must not be {@literal null}.
* @param others must not be {@literal null}.
*/
public GeoJsonMultiPoint(Point first, Point second, Point... others) {
Assert.notNull(first, "First point must not be null!");
Assert.notNull(second, "Second point must not be null!");
Assert.notNull(others, "Additional points must not be null!");
this.points = new ArrayList<Point>();
this.points.add(first);
this.points.add(second);
this.points.addAll(Arrays.asList(others));
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType()
*/
@Override
public String getType() {
return TYPE;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates()
*/
@Override
public List<Point> getCoordinates() {
return Collections.unmodifiableList(this.points);
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.points);
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof GeoJsonMultiPoint)) {
return false;
}
return ObjectUtils.nullSafeEquals(this.points, ((GeoJsonMultiPoint) obj).points);
}
}

View File

@@ -1,93 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.geo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* {@link GeoJsonMultiPolygon} is defined as a list of {@link GeoJsonPolygon}s.
*
* @author Christoph Strobl
* @since 1.7
*/
public class GeoJsonMultiPolygon implements GeoJson<Iterable<GeoJsonPolygon>> {
private static final String TYPE = "MultiPolygon";
private List<GeoJsonPolygon> coordinates = new ArrayList<GeoJsonPolygon>();
/**
* Creates a new {@link GeoJsonMultiPolygon} for the given {@link GeoJsonPolygon}s.
*
* @param polygons must not be {@literal null}.
*/
public GeoJsonMultiPolygon(List<GeoJsonPolygon> polygons) {
Assert.notNull(polygons, "Polygons for MultiPolygon must not be null!");
this.coordinates.addAll(polygons);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType()
*/
@Override
public String getType() {
return TYPE;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates()
*/
@Override
public List<GeoJsonPolygon> getCoordinates() {
return Collections.unmodifiableList(this.coordinates);
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.coordinates);
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof GeoJsonMultiPolygon)) {
return false;
}
return ObjectUtils.nullSafeEquals(this.coordinates, ((GeoJsonMultiPolygon) obj).coordinates);
}
}

View File

@@ -1,72 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.geo;
import java.util.Arrays;
import java.util.List;
import org.springframework.data.geo.Point;
/**
* {@link GeoJson} representation of {@link Point}.
*
* @author Christoph Strobl
* @since 1.7
* @see http://geojson.org/geojson-spec.html#point
*/
public class GeoJsonPoint extends Point implements GeoJson<List<Double>> {
private static final long serialVersionUID = -8026303425147474002L;
private static final String TYPE = "Point";
/**
* Creates {@link GeoJsonPoint} for given coordinates.
*
* @param x
* @param y
*/
public GeoJsonPoint(double x, double y) {
super(x, y);
}
/**
* Creates {@link GeoJsonPoint} for given {@link Point}.
*
* @param point must not be {@literal null}.
*/
public GeoJsonPoint(Point point) {
super(point);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType()
*/
@Override
public String getType() {
return TYPE;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates()
*/
@Override
public List<Double> getCoordinates() {
return Arrays.asList(Double.valueOf(getX()), Double.valueOf(getY()));
}
}

View File

@@ -1,95 +0,0 @@
/*
* Copyright 2015 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.mongodb.core.geo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Polygon;
/**
* {@link GeoJson} representation of {@link Polygon}. Unlike {@link Polygon} the {@link GeoJsonPolygon} requires a
* closed border. Which means that the first and last {@link Point} have to have same coordinate pairs.
*
* @author Christoph Strobl
* @since 1.7
* @see http://geojson.org/geojson-spec.html#polygon
*/
public class GeoJsonPolygon extends Polygon implements GeoJson<List<GeoJsonLineString>> {
private static final long serialVersionUID = 3936163018187247185L;
private static final String TYPE = "Polygon";
private List<GeoJsonLineString> coordinates = new ArrayList<GeoJsonLineString>();
/**
* Creates new {@link GeoJsonPolygon} from the given {@link Point}s.
*
* @param first must not be {@literal null}.
* @param second must not be {@literal null}.
* @param third must not be {@literal null}.
* @param fourth must not be {@literal null}.
* @param others can be {@literal null}.
*/
public GeoJsonPolygon(Point first, Point second, Point third, Point fourth, final Point... others) {
this(asList(first, second, third, fourth, others));
}
/**
* Creates new {@link GeoJsonPolygon} from the given {@link Point}s.
*
* @param points must not be {@literal null}.
*/
public GeoJsonPolygon(List<Point> points) {
super(points);
this.coordinates.add(new GeoJsonLineString(points));
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getType()
*/
@Override
public String getType() {
return TYPE;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.geo.GeoJson#getCoordinates()
*/
@Override
public List<GeoJsonLineString> getCoordinates() {
return Collections.unmodifiableList(this.coordinates);
}
private static List<Point> asList(Point first, Point second, Point third, Point fourth, final Point... others) {
ArrayList<Point> result = new ArrayList<Point>(3 + others.length);
result.add(first);
result.add(second);
result.add(third);
result.add(fourth);
result.addAll(Arrays.asList(others));
return result;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2013 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.
@@ -28,7 +28,6 @@ import java.lang.annotation.Target;
* @author Oliver Gierke
* @author Philipp Schneider
* @author Johno Crawford
* @author Christoph Strobl
*/
@Target({ ElementType.TYPE })
@Documented
@@ -106,9 +105,9 @@ public @interface CompoundIndex {
*
* <pre>
* <code>
* db.root.createIndex( { hybrid.h1: 1, hybrid.h2: 1 } , { name: "hybrid.compound_index" } )
* db.root.createIndex( { nested.n1: 1, nested.n2: 1 } , { name: "nested.compound_index" } )
* db.hybrid.createIndex( { h1: 1, h2: 1 } , { name: "compound_index" } )
* db.root.ensureIndex( { hybrid.h1: 1, hybrid.h2: 1 } , { name: "hybrid.compound_index" } )
* db.root.ensureIndex( { nested.n1: 1, nested.n2: 1 } , { name: "nested.compound_index" } )
* db.hybrid.ensureIndex( { h1: 1, h2: 1 } , { name: "compound_index" } )
* </code>
* </pre>
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2014 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.
@@ -26,7 +26,6 @@ import java.lang.annotation.Target;
* @author Jon Brisbin
* @author Laurent Canet
* @author Thomas Darimont
* @author Christoph Strobl
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@@ -63,9 +62,9 @@ public @interface GeoSpatialIndexed {
*
* <pre>
* <code>
* db.root.createIndex( { hybrid.h1: "2d" } , { name: "hybrid.index" } )
* db.root.createIndex( { nested.n1: "2d" } , { name: "nested.index" } )
* db.hybrid.createIndex( { h1: "2d" } , { name: "index" } )
* db.root.ensureIndex( { hybrid.h1: "2d" } , { name: "hybrid.index" } )
* db.root.ensureIndex( { nested.n1: "2d" } , { name: "nested.index" } )
* db.hybrid.ensureIndex( { h1: "2d" } , { name: "index" } )
* </code>
* </pre>
*

View File

@@ -35,17 +35,7 @@ import com.mongodb.DBObject;
public class Index implements IndexDefinition {
public enum Duplicates {
RETAIN, //
/**
* Dropping Duplicates was removed in MongoDB Server 2.8.0-rc0.
* <p>
* See https://jira.mongodb.org/browse/SERVER-14710
*
* @deprecated since 1.7.
*/
@Deprecated//
DROP
RETAIN, DROP
}
private final Map<String, Direction> fieldSpec = new LinkedHashMap<String, Direction>();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014 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,24 +16,22 @@
package org.springframework.data.mongodb.core.index;
import org.springframework.data.mongodb.core.index.MongoPersistentEntityIndexResolver.IndexDefinitionHolder;
import org.springframework.data.util.TypeInformation;
/**
* {@link IndexResolver} finds those {@link IndexDefinition}s to be created for a given class.
*
* @author Christoph Strobl
* @author Thomas Darimont
* @since 1.5
*/
interface IndexResolver {
/**
* Find and create {@link IndexDefinition}s for properties of given {@link TypeInformation}. {@link IndexDefinition}s are created
* Find and create {@link IndexDefinition}s for properties of given {@code type}. {@link IndexDefinition}s are created
* for properties and types with {@link Indexed}, {@link CompoundIndexes} or {@link GeoSpatialIndexed}.
*
* @param typeInformation
* @param type
* @return Empty {@link Iterable} in case no {@link IndexDefinition} could be resolved for type.
*/
Iterable<? extends IndexDefinitionHolder> resolveIndexFor(TypeInformation<?> typeInformation);
Iterable<? extends IndexDefinitionHolder> resolveIndexForClass(Class<?> type);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -28,7 +28,6 @@ import java.lang.annotation.Target;
* @author Philipp Schneider
* @author Johno Crawford
* @author Thomas Darimont
* @author Christoph Strobl
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@@ -89,9 +88,9 @@ public @interface Indexed {
*
* <pre>
* <code>
* db.root.createIndex( { hybrid.h1: 1 } , { name: "hybrid.index" } )
* db.root.createIndex( { nested.n1: 1 } , { name: "nested.index" } )
* db.hybrid.createIndex( { h1: 1} , { name: "index" } )
* db.root.ensureIndex( { hybrid.h1: 1 } , { name: "hybrid.index" } )
* db.root.ensureIndex( { nested.n1: 1 } , { name: "nested.index" } )
* db.hybrid.ensureIndex( { h1: 1} , { name: "index" } )
* </code>
* </pre>
*

View File

@@ -123,7 +123,7 @@ public class MongoPersistentEntityIndexCreator implements ApplicationListener<Ma
private void checkForAndCreateIndexes(MongoPersistentEntity<?> entity) {
if (entity.findAnnotation(Document.class) != null) {
for (IndexDefinitionHolder indexToCreate : indexResolver.resolveIndexFor(entity.getTypeInformation())) {
for (IndexDefinitionHolder indexToCreate : indexResolver.resolveIndexForClass(entity.getType())) {
createIndex(indexToCreate);
}
}

View File

@@ -36,7 +36,6 @@ import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -52,7 +51,6 @@ import com.mongodb.util.JSON;
* scanning related annotations.
*
* @author Christoph Strobl
* @author Thomas Darimont
* @since 1.5
*/
public class MongoPersistentEntityIndexResolver implements IndexResolver {
@@ -72,12 +70,13 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
this.mappingContext = mappingContext;
}
/* (non-Javadoc)
* @see org.springframework.data.mongodb.core.index.IndexResolver#resolveIndexForClass(org.springframework.data.util.TypeInformation)
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.index.IndexResolver#resolveIndexForClass(java.lang.Class)
*/
@Override
public Iterable<? extends IndexDefinitionHolder> resolveIndexFor(TypeInformation<?> typeInformation) {
return resolveIndexForEntity(mappingContext.getPersistentEntity(typeInformation));
public List<IndexDefinitionHolder> resolveIndexForClass(Class<?> type) {
return resolveIndexForEntity(mappingContext.getPersistentEntity(type));
}
/**
@@ -260,7 +259,7 @@ public class MongoPersistentEntityIndexResolver implements IndexResolver {
LOGGER.info(e.getMessage(), e);
} catch (InvalidDataAccessApiUsageException e) {
LOGGER.info(
String.format("Potentially invald index structure discovered. Breaking operation for %s.",
String.format("Potentially invalid index structure discovered. Breaking operation for %s.",
entity.getName()), e);
}
} else if (includeOptions.isForce() || indexed != null) {

View File

@@ -16,6 +16,7 @@
package org.springframework.data.mongodb.core.mapping;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
@@ -305,28 +306,44 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
*/
private static class PropertyTypeAssertionHandler implements PropertyHandler<MongoPersistentProperty> {
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.PropertyHandler#doWithPersistentProperty(org.springframework.data.mapping.PersistentProperty)
*/
@Override
public void doWithPersistentProperty(MongoPersistentProperty persistentProperty) {
potentiallyAssertTextScoreType(persistentProperty);
potentiallyAssertLanguageType(persistentProperty);
potentiallyAssertDBRefTargetType(persistentProperty);
}
private void potentiallyAssertLanguageType(MongoPersistentProperty persistentProperty) {
private static void potentiallyAssertLanguageType(MongoPersistentProperty persistentProperty) {
if (persistentProperty.isExplicitLanguageProperty()) {
assertPropertyType(persistentProperty, String.class);
}
}
private void potentiallyAssertTextScoreType(MongoPersistentProperty persistentProperty) {
private static void potentiallyAssertTextScoreType(MongoPersistentProperty persistentProperty) {
if (persistentProperty.isTextScoreProperty()) {
assertPropertyType(persistentProperty, Float.class, Double.class);
}
}
private void assertPropertyType(MongoPersistentProperty persistentProperty, Class<?>... validMatches) {
private static void potentiallyAssertDBRefTargetType(MongoPersistentProperty persistentProperty) {
if (persistentProperty.isDbReference() && persistentProperty.getDBRef().lazy()) {
if (persistentProperty.isArray() || Modifier.isFinal(persistentProperty.getActualType().getModifiers())) {
throw new MappingException(String.format(
"Invalid lazy DBRef property for %s. Found %s which must not be an array nor a final class.",
persistentProperty.getField(), persistentProperty.getActualType()));
}
}
}
private static void assertPropertyType(MongoPersistentProperty persistentProperty, Class<?>... validMatches) {
for (Class<?> potentialMatch : validMatches) {
if (ClassUtils.isAssignable(potentialMatch, persistentProperty.getActualType())) {
@@ -334,10 +351,9 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
}
}
throw new MappingException(String.format("Missmatching types for %s. Found %s expected one of %s.",
persistentProperty.getField(), persistentProperty.getActualType(),
StringUtils.arrayToCommaDelimitedString(validMatches)));
throw new MappingException(
String.format("Missmatching types for %s. Found %s expected one of %s.", persistentProperty.getField(),
persistentProperty.getActualType(), StringUtils.arrayToCommaDelimitedString(validMatches)));
}
}
}

View File

@@ -100,8 +100,7 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
}
// We need to support a wider range of ID types than just the ones that can be converted to an ObjectId
// but still we need to check if there happens to be an explicit name set
return SUPPORTED_ID_PROPERTY_NAMES.contains(getName()) && !hasExplicitFieldName();
return SUPPORTED_ID_PROPERTY_NAMES.contains(getName());
}
/*
@@ -135,8 +134,10 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
}
}
if (hasExplicitFieldName()) {
return getAnnotatedFieldName();
org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
if (annotation != null && StringUtils.hasText(annotation.value())) {
return annotation.value();
}
String fieldName = fieldNamingStrategy.getFieldName(this);
@@ -149,26 +150,6 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
return fieldName;
}
/**
* @return true if {@link org.springframework.data.mongodb.core.mapping.Field} having non blank
* {@link org.springframework.data.mongodb.core.mapping.Field#value()} present.
* @since 1.7
*/
protected boolean hasExplicitFieldName() {
return StringUtils.hasText(getAnnotatedFieldName());
}
private String getAnnotatedFieldName() {
org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
if (annotation != null && StringUtils.hasText(annotation.value())) {
return annotation.value();
}
return null;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#getFieldOrder()

View File

@@ -45,7 +45,7 @@ public interface MongoPersistentProperty extends PersistentProperty<MongoPersist
int getFieldOrder();
/**
* Returns whether the propert is a {@link com.mongodb.DBRef}. If this returns {@literal true} you can expect
* Returns whether the property is a {@link com.mongodb.DBRef}. If this returns {@literal true} you can expect
* {@link #getDBRef()} to return an non-{@literal null} value.
*
* @return

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011 - 2014 the original author or authors.
* Copyright 2011 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.
@@ -26,8 +26,7 @@ import com.mongodb.DBObject;
* Collects the results of executing a group operation.
*
* @author Mark Pollack
* @author Christoph Strobl
* @param <T> The class in which the results are mapped onto, accessible via an {@link Iterator}.
* @param <T> The class in which the results are mapped onto, accessible via an interator.
*/
public class GroupByResults<T> implements Iterable<T> {
@@ -39,7 +38,6 @@ public class GroupByResults<T> implements Iterable<T> {
private String serverUsed;
public GroupByResults(List<T> mappedResults, DBObject rawResults) {
Assert.notNull(mappedResults);
Assert.notNull(rawResults);
this.mappedResults = mappedResults;
@@ -70,24 +68,21 @@ public class GroupByResults<T> implements Iterable<T> {
}
private void parseCount() {
Object object = rawResults.get("count");
if (object instanceof Number) {
count = ((Number) object).doubleValue();
if (object instanceof Double) {
count = (Double) object;
}
}
private void parseKeys() {
Object object = rawResults.get("keys");
if (object instanceof Number) {
keys = ((Number) object).intValue();
if (object instanceof Integer) {
keys = (Integer) object;
}
}
private void parseServerUsed() {
// "serverUsed" : "127.0.0.1:27017"
Object object = rawResults.get("serverUsed");
if (object instanceof String) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2011 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.
@@ -22,11 +22,6 @@ import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.MapReduceCommand;
/**
* @author Mark Pollack
* @author Oliver Gierke
* @author Christoph Strobl
*/
public class MapReduceOptions {
private String outputCollection;
@@ -202,19 +197,12 @@ public class MapReduceOptions {
* @param key The key option
* @param value The value of the option
* @return MapReduceOptions so that methods can be chained in a fluent API style
* @deprecated since 1.7.
*/
@Deprecated
public MapReduceOptions extraOption(String key, Object value) {
extraOptions.put(key, value);
return this;
}
/**
* @return
* @deprecated since 1.7
*/
@Deprecated
public Map<String, Object> getExtraOptions() {
return extraOptions;
}
@@ -275,18 +263,18 @@ public class MapReduceOptions {
BasicDBObject out = new BasicDBObject();
switch (outputType) {
case INLINE:
out.put("inline", 1);
break;
case REPLACE:
out.put("replace", outputCollection);
break;
case MERGE:
out.put("merge", outputCollection);
break;
case REDUCE:
out.put("reduce", outputCollection);
break;
case INLINE:
out.put("inline", 1);
break;
case REPLACE:
out.put("replace", outputCollection);
break;
case MERGE:
out.put("merge", outputCollection);
break;
case REDUCE:
out.put("reduce", outputCollection);
break;
}
if (outputDatabase != null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 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.
@@ -21,14 +21,12 @@ import java.util.List;
import org.springframework.util.Assert;
import com.mongodb.DBObject;
import com.mongodb.MapReduceOutput;
/**
* Collects the results of performing a MapReduce operations.
*
* @author Mark Pollack
* @author Oliver Gierke
* @author Christoph Strobl
* @param <T> The class in which the results are mapped onto, accessible via an iterator.
*/
public class MapReduceResults<T> implements Iterable<T> {
@@ -44,9 +42,7 @@ public class MapReduceResults<T> implements Iterable<T> {
*
* @param mappedResults must not be {@literal null}.
* @param rawResults must not be {@literal null}.
* @deprecated since 1.7. Please use {@link #MapReduceResults(List, MapReduceOutput)}
*/
@Deprecated
public MapReduceResults(List<T> mappedResults, DBObject rawResults) {
Assert.notNull(mappedResults);
@@ -59,25 +55,6 @@ public class MapReduceResults<T> implements Iterable<T> {
this.outputCollection = parseOutputCollection(rawResults);
}
/**
* Creates a new {@link MapReduceResults} from the given mapped results and the {@link MapReduceOutput}.
*
* @param mappedResults must not be {@literal null}.
* @param mapReduceOutput must not be {@literal null}.
* @since 1.7
*/
public MapReduceResults(List<T> mappedResults, MapReduceOutput mapReduceOutput) {
Assert.notNull(mappedResults, "MappedResults must not be null!");
Assert.notNull(mapReduceOutput, "MapReduceOutput must not be null!");
this.mappedResults = mappedResults;
this.rawResults = null;
this.mapReduceTiming = parseTiming(mapReduceOutput);
this.mapReduceCounts = parseCounts(mapReduceOutput);
this.outputCollection = parseOutputCollection(mapReduceOutput);
}
/*
* (non-Javadoc)
* @see java.lang.Iterable#iterator()
@@ -102,7 +79,7 @@ public class MapReduceResults<T> implements Iterable<T> {
return rawResults;
}
private static MapReduceTiming parseTiming(DBObject rawResults) {
private MapReduceTiming parseTiming(DBObject rawResults) {
DBObject timing = (DBObject) rawResults.get("timing");
@@ -125,10 +102,8 @@ public class MapReduceResults<T> implements Iterable<T> {
* @param key
* @return
*/
private static Long getAsLong(DBObject source, String key) {
private Long getAsLong(DBObject source, String key) {
Object raw = source.get(key);
return raw instanceof Long ? (Long) raw : (Integer) raw;
}
@@ -138,7 +113,7 @@ public class MapReduceResults<T> implements Iterable<T> {
* @param rawResults
* @return
*/
private static MapReduceCounts parseCounts(DBObject rawResults) {
private MapReduceCounts parseCounts(DBObject rawResults) {
DBObject counts = (DBObject) rawResults.get("counts");
@@ -159,7 +134,7 @@ public class MapReduceResults<T> implements Iterable<T> {
* @param rawResults
* @return
*/
private static String parseOutputCollection(DBObject rawResults) {
private String parseOutputCollection(DBObject rawResults) {
Object resultField = rawResults.get("result");
@@ -170,17 +145,4 @@ public class MapReduceResults<T> implements Iterable<T> {
return resultField instanceof DBObject ? ((DBObject) resultField).get("collection").toString() : resultField
.toString();
}
private static MapReduceCounts parseCounts(final MapReduceOutput mapReduceOutput) {
return new MapReduceCounts(mapReduceOutput.getInputCount(), mapReduceOutput.getEmitCount(),
mapReduceOutput.getOutputCount());
}
private static String parseOutputCollection(final MapReduceOutput mapReduceOutput) {
return mapReduceOutput.getCollectionName();
}
private static MapReduceTiming parseTiming(MapReduceOutput mapReduceOutput) {
return new MapReduceTiming(-1, -1, mapReduceOutput.getDuration());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2014 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.
@@ -29,7 +29,6 @@ import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Shape;
import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
import org.springframework.data.mongodb.core.geo.GeoJson;
import org.springframework.data.mongodb.core.geo.Sphere;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -190,8 +189,8 @@ public class Criteria implements CriteriaDefinition {
*/
public Criteria in(Object... o) {
if (o.length > 1 && o[1] instanceof Collection) {
throw new InvalidMongoDbApiUsageException(
"You can only pass in one argument of type " + o[1].getClass().getName());
throw new InvalidMongoDbApiUsageException("You can only pass in one argument of type "
+ o[1].getClass().getName());
}
criteria.put("$in", Arrays.asList(o));
return this;
@@ -377,8 +376,8 @@ public class Criteria implements CriteriaDefinition {
}
/**
* Creates a geospatial criterion using a {@literal $geoWithin $centerSphere} operation. This is only available for
* Mongo 2.4 and higher.
* Creates a geospatial criterion using a {@literal $within $centerSphere} operation. This is only available for Mongo
* 1.7 and higher.
*
* @see http://docs.mongodb.org/manual/reference/operator/query/geoWithin/
* @see http://docs.mongodb.org/manual/reference/operator/query/centerSphere/
@@ -387,12 +386,12 @@ public class Criteria implements CriteriaDefinition {
*/
public Criteria withinSphere(Circle circle) {
Assert.notNull(circle);
criteria.put("$geoWithin", new GeoCommand(new Sphere(circle)));
criteria.put("$within", new GeoCommand(new Sphere(circle)));
return this;
}
/**
* Creates a geospatial criterion using a {@literal $geoWithin} operation.
* Creates a geospatial criterion using a {@literal $within} operation.
*
* @see http://docs.mongodb.org/manual/reference/operator/query/geoWithin/
* @param shape
@@ -401,7 +400,7 @@ public class Criteria implements CriteriaDefinition {
public Criteria within(Shape shape) {
Assert.notNull(shape);
criteria.put("$geoWithin", new GeoCommand(shape));
criteria.put("$within", new GeoCommand(shape));
return this;
}
@@ -433,58 +432,17 @@ public class Criteria implements CriteriaDefinition {
}
/**
* Creates criterion using {@code $geoIntersects} operator which matches intersections of the given {@code geoJson}
* structure and the documents one. Requires MongoDB 2.4 or better.
*
* @param geoJson must not be {@literal null}.
* @return
* @since 1.8
*/
@SuppressWarnings("rawtypes")
public Criteria intersects(GeoJson geoJson) {
Assert.notNull(geoJson, "GeoJson must not be null!");
criteria.put("$geoIntersects", geoJson);
return this;
}
/**
* Creates a geo-spatial criterion using a {@literal $maxDistance} operation, for use with $near
* Creates a geospatical criterion using a {@literal $maxDistance} operation, for use with $near
*
* @see http://docs.mongodb.org/manual/reference/operator/query/maxDistance/
* @param maxDistance
* @return
*/
public Criteria maxDistance(double maxDistance) {
if (createNearCriteriaForCommand("$near", "$maxDistance", maxDistance)
|| createNearCriteriaForCommand("$nearSphere", "$maxDistance", maxDistance)) {
return this;
}
criteria.put("$maxDistance", maxDistance);
return this;
}
/**
* Creates a geospatial criterion using a {@literal $minDistance} operation, for use with {@literal $near} or
* {@literal $nearSphere}.
*
* @param minDistance
* @return
* @since 1.7
*/
public Criteria minDistance(double minDistance) {
if (createNearCriteriaForCommand("$near", "$minDistance", minDistance)
|| createNearCriteriaForCommand("$nearSphere", "$minDistance", minDistance)) {
return this;
}
criteria.put("$minDistance", minDistance);
return this;
}
/**
* Creates a criterion using the {@literal $elemMatch} operator
*
@@ -542,8 +500,8 @@ public class Criteria implements CriteriaDefinition {
private Criteria registerCriteriaChainElement(Criteria criteria) {
if (lastOperatorWasNot()) {
throw new IllegalArgumentException(
"operator $not is not allowed around criteria chain element: " + criteria.getCriteriaObject());
throw new IllegalArgumentException("operator $not is not allowed around criteria chain element: "
+ criteria.getCriteriaObject());
} else {
criteriaChain.add(criteria);
}
@@ -582,13 +540,7 @@ public class Criteria implements CriteriaDefinition {
boolean not = false;
for (String k : this.criteria.keySet()) {
Object value = this.criteria.get(k);
if (requiresGeoJsonFormat(value)) {
value = new BasicDBObject("$geometry", value);
}
if (not) {
DBObject notDbo = new BasicDBObject();
notDbo.put(k, value);
@@ -641,31 +593,6 @@ public class Criteria implements CriteriaDefinition {
}
}
private boolean createNearCriteriaForCommand(String command, String operation, double maxDistance) {
if (!criteria.containsKey(command)) {
return false;
}
Object existingNearOperationValue = criteria.get(command);
if (existingNearOperationValue instanceof DBObject) {
((DBObject) existingNearOperationValue).put(operation, maxDistance);
return true;
} else if (existingNearOperationValue instanceof GeoJson) {
BasicDBObject dbo = new BasicDBObject("$geometry", existingNearOperationValue).append(operation, maxDistance);
criteria.put(command, dbo);
return true;
}
return false;
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
@@ -744,9 +671,4 @@ public class Criteria implements CriteriaDefinition {
return result;
}
private static boolean requiresGeoJsonFormat(Object value) {
return value instanceof GeoJson
|| (value instanceof GeoCommand && ((GeoCommand) value).getShape() instanceof GeoJson);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2015 the original author or authors.
* Copyright 2014 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.
@@ -15,8 +15,6 @@
*/
package org.springframework.data.mongodb.core.query;
import static org.springframework.util.ObjectUtils.*;
import org.springframework.data.geo.Box;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Polygon;
@@ -28,10 +26,9 @@ import org.springframework.util.Assert;
* Wrapper around a {@link Shape} to allow appropriate query rendering.
*
* @author Thomas Darimont
* @author Christoph Strobl
* @since 1.5
*/
public final class GeoCommand {
public class GeoCommand {
private final Shape shape;
private final String command;
@@ -85,39 +82,4 @@ public final class GeoCommand {
throw new IllegalArgumentException("Unknown shape: " + shape);
}
/*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int result = 31;
result += 17 * nullSafeHashCode(this.command);
result += 17 * nullSafeHashCode(this.shape);
return result;
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof GeoCommand)) {
return false;
}
GeoCommand that = (GeoCommand) obj;
return nullSafeEquals(this.command, that.command) && nullSafeEquals(this.shape, that.shape);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -40,7 +40,6 @@ public final class NearQuery {
private final Point point;
private Query query;
private Distance maxDistance;
private Distance minDistance;
private Metric metric;
private boolean spherical;
private Integer num;
@@ -212,63 +211,6 @@ public final class NearQuery {
return this;
}
/**
* Sets the minimum distance results shall have from the configured origin. If a {@link Metric} was set before the
* given value will be interpreted as being a value in that metric. E.g.
*
* <pre>
* NearQuery query = near(10.0, 20.0, Metrics.KILOMETERS).minDistance(150);
* </pre>
*
* Will set the minimum distance to 150 kilometers.
*
* @param minDistance
* @return
* @since 1.7
*/
public NearQuery minDistance(double minDistance) {
return minDistance(new Distance(minDistance, getMetric()));
}
/**
* Sets the minimum distance supplied in a given metric. Will normalize the distance but not reconfigure the query's
* result {@link Metric} if one was configured before.
*
* @param minDistance
* @param metric must not be {@literal null}.
* @return
* @since 1.7
*/
public NearQuery minDistance(double minDistance, Metric metric) {
Assert.notNull(metric);
return minDistance(new Distance(minDistance, metric));
}
/**
* Sets the minimum distance to the given {@link Distance}. Will set the returned {@link Metric} to be the one of the
* given {@link Distance} if no {@link Metric} was set before.
*
* @param distance must not be {@literal null}.
* @return
* @since 1.7
*/
public NearQuery minDistance(Distance distance) {
Assert.notNull(distance);
if (distance.getMetric() != Metrics.NEUTRAL) {
this.spherical(true);
}
if (this.metric == null) {
in(distance.getMetric());
}
this.minDistance = distance;
return this;
}
/**
* Returns the maximum {@link Distance}.
*
@@ -278,16 +220,6 @@ public final class NearQuery {
return this.maxDistance;
}
/**
* Returns the maximum {@link Distance}.
*
* @return
* @since 1.7
*/
public Distance getMinDistance() {
return this.minDistance;
}
/**
* Configures a {@link CustomMetric} with the given multiplier.
*
@@ -420,11 +352,7 @@ public final class NearQuery {
}
if (maxDistance != null) {
dbObject.put("maxDistance", maxDistance.getNormalizedValue());
}
if (minDistance != null) {
dbObject.put("minDistance", minDistance.getNormalizedValue());
dbObject.put("maxDistance", this.maxDistance.getNormalizedValue());
}
if (metric != null) {

View File

@@ -176,7 +176,7 @@ public class Query {
for (Order order : sort) {
if (order.isIgnoreCase()) {
throw new IllegalArgumentException(String.format("Gven sort contained an Order for %s with ignore case! "
throw new IllegalArgumentException(String.format("Given sort contained an Order for %s with ignore case! "
+ "MongoDB does not support sorting ignoreing case currently!", order.getProperty()));
}
}

View File

@@ -63,7 +63,7 @@ public class TextCriteria implements CriteriaDefinition {
}
/**
* For a full list of supported languages see the mongdodb reference manual for <a
* For a full list of supported languages see the mongodb reference manual for <a
* href="http://docs.mongodb.org/manual/reference/text-search-languages/">Text Search Languages</a>.
*
* @param language

View File

@@ -64,7 +64,7 @@ public class Update {
}
/**
* Creates an {@link Update} instance from the given {@link DBObject}. Allows to explicitly exlude fields from making
* Creates an {@link Update} instance from the given {@link DBObject}. Allows to explicitly exclude fields from making
* it into the created {@link Update} object. Note, that this will set attributes directly and <em>not</em> use
* {@literal $set}. This means fields not given in the {@link DBObject} will be nulled when executing the update. To
* create an only-updating {@link Update} instance of a {@link DBObject}, call {@link #set(String, Object)} for each
@@ -163,8 +163,7 @@ public class Update {
/**
* Update using {@code $push} modifier. <br/>
* Allows creation of {@code $push} command for single or multiple (using {@code $each}) values as well as using
* {@code $position}.
* Allows creation of {@code $push} command for single or multiple (using {@code $each}) values.
*
* @see http://docs.mongodb.org/manual/reference/operator/update/push/
* @see http://docs.mongodb.org/manual/reference/operator/update/each/
@@ -299,33 +298,6 @@ public class Update {
return this;
}
/**
* Multiply the value of given key by the given number.
*
* @see http://docs.mongodb.org/manual/reference/operator/update/mul/
* @param key must not be {@literal null}.
* @param multiplier must not be {@literal null}.
* @return
* @since 1.7
*/
public Update multiply(String key, Number multiplier) {
Assert.notNull(multiplier, "Multiplier must not be 'null'.");
addMultiFieldOperation("$mul", key, multiplier.doubleValue());
return this;
}
/**
* The operator supports bitwise {@code and}, bitwise {@code or}, and bitwise {@code xor} operations.
*
* @param key
* @return
* @since 1.7
*/
public BitwiseOperatorBuilder bitwise(String key) {
return new BitwiseOperatorBuilder(this, key);
}
public DBObject getUpdateObject() {
DBObject dbo = new BasicDBObject();
@@ -562,31 +534,6 @@ public class Update {
}
}
/**
* {@link Modifier} implementation used to propagate {@code $position}.
*
* @author Christoph Strobl
* @since 1.7
*/
private static class PositionModifier implements Modifier {
private final int position;
public PositionModifier(int position) {
this.position = position;
}
@Override
public String getKey() {
return "$position";
}
@Override
public Object getValue() {
return position;
}
}
/**
* Builder for creating {@code $push} modifiers
*
@@ -615,42 +562,6 @@ public class Update {
return Update.this.push(key, this.modifiers);
}
/**
* Forces values to be added at the given {@literal position}.
*
* @param position needs to be greater than or equal to zero.
* @return
* @since 1.7
*/
public PushOperatorBuilder atPosition(int position) {
if (position < 0) {
throw new IllegalArgumentException("Position must be greater than or equal to zero.");
}
this.modifiers.addModifier(new PositionModifier(position));
return this;
}
/**
* Forces values to be added at given {@literal position}.
*
* @param position can be {@literal null} which will be appended at the last position.
* @return
* @since 1.7
*/
public PushOperatorBuilder atPosition(Position position) {
if (position == null || Position.LAST.equals(position)) {
return this;
}
this.modifiers.addModifier(new PositionModifier(0));
return this;
}
/**
* Propagates {@link #value(Object)} to {@code $push}
*
@@ -740,79 +651,4 @@ public class Update {
return Update.this.addToSet(this.key, value);
}
}
/**
* @author Christoph Strobl
* @since 1.7
*/
public static class BitwiseOperatorBuilder {
private final String key;
private final Update reference;
private static final String BIT_OPERATOR = "$bit";
private enum BitwiseOperator {
AND, OR, XOR;
@Override
public String toString() {
return super.toString().toLowerCase();
};
}
/**
* Creates a new {@link BitwiseOperatorBuilder}.
*
* @param reference must not be {@literal null}
* @param key must not be {@literal null}
*/
protected BitwiseOperatorBuilder(Update reference, String key) {
Assert.notNull(reference, "Reference must not be null!");
Assert.notNull(key, "Key must not be null!");
this.reference = reference;
this.key = key;
}
/**
* Updates to the result of a bitwise and operation between the current value and the given one.
*
* @param value
* @return
*/
public Update and(long value) {
addFieldOperation(BitwiseOperator.AND, value);
return reference;
}
/**
* Updates to the result of a bitwise or operation between the current value and the given one.
*
* @param value
* @return
*/
public Update or(long value) {
addFieldOperation(BitwiseOperator.OR, value);
return reference;
}
/**
* Updates to the result of a bitwise xor operation between the current value and the given one.
*
* @param value
* @return
*/
public Update xor(long value) {
addFieldOperation(BitwiseOperator.XOR, value);
return reference;
}
private void addFieldOperation(BitwiseOperator operator, Number value) {
reference.addMultiFieldOperation(BIT_OPERATOR, key, new BasicDBObject(operator.toString(), value));
}
}
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright 2014-2015 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.mongodb.core.script;
import org.springframework.util.Assert;
/**
* Value object for MongoDB JavaScript functions implementation that can be saved or directly executed.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
public class ExecutableMongoScript {
private final String code;
/**
* Creates new {@link ExecutableMongoScript}.
*
* @param code must not be {@literal null} or empty.
*/
public ExecutableMongoScript(String code) {
Assert.hasText(code, "Code must not be null or empty!");
this.code = code;
}
/**
* Returns the actual script code.
*
* @return will never be {@literal null} or empty.
*/
public String getCode() {
return this.code;
}
}

View File

@@ -1,86 +0,0 @@
/*
* Copyright 2014-2015 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.mongodb.core.script;
import org.springframework.data.annotation.Id;
import org.springframework.util.Assert;
/**
* An {@link ExecutableMongoScript} assigned to a name that allows calling the function by its {@literal name} once it
* has been saved to the {@link com.mongodb.DB} instance.
*
* @author Christoph Strobl
* @author Oliver Gierke
* @since 1.7
*/
public class NamedMongoScript {
private final @Id String name;
private final ExecutableMongoScript script;
/**
* Creates new {@link NamedMongoScript} that can be saved to the {@link com.mongodb.DB} instance.
*
* @param name must not be {@literal null} or empty.
* @param rawScript the {@link String} representation of the {@literal JavaScript} function. Must not be
* {@literal null} or empty.
*/
public NamedMongoScript(String name, String rawScript) {
this(name, new ExecutableMongoScript(rawScript));
}
/**
* Creates new {@link NamedMongoScript}.
*
* @param name must not be {@literal null} or empty.
* @param script must not be {@literal null}.
*/
public NamedMongoScript(String name, ExecutableMongoScript script) {
Assert.hasText(name, "Name must not be null or empty!");
Assert.notNull(script, "ExecutableMongoScript must not be null!");
this.name = name;
this.script = script;
}
/**
* Returns the actual script code.
*
* @return will never be {@literal null}.
*/
public String getCode() {
return script.getCode();
}
/**
* Returns the underlying {@link ExecutableMongoScript}.
*
* @return will never be {@literal null}.
*/
public ExecutableMongoScript getScript() {
return script;
}
/**
* Returns the name of the script.
*
* @return will never be {@literal null} or empty.
*/
public String getName() {
return name;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2013 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.
@@ -22,14 +22,13 @@ import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.support.MetricType;
import com.mongodb.Mongo;
import com.mongodb.Mongo;
/**
* Expose basic server information via JMX
*
* @author Mark Pollack
* @author Thomas Darimont
* @author Christoph Strobl
* @author Thomas Darimont
*/
@ManagedResource(description = "Server Information")
public class ServerInfo extends AbstractMonitor {
@@ -38,20 +37,20 @@ public class ServerInfo extends AbstractMonitor {
this.mongo = mongo;
}
/**
* Returns the hostname of the used server reported by MongoDB.
*
* @return the reported hostname can also be an IP address.
* @throws UnknownHostException
*/
/**
* Returns the hostname of the used server reported by mongo.
*
* @return the reported hostname can also be an IP address.
* @throws UnknownHostException
*/
@ManagedOperation(description = "Server host name")
public String getHostName() throws UnknownHostException {
/*
* UnknownHostException is not necessary anymore, but clients could have
* called this method in a try..catch(UnknownHostException) already
*/
return mongo.getAddress().getHost();
/*
* UnknownHostException is not necessary anymore, but clients could have
* called this method in a try..catch(UnknownHostException) already
*/
return getServerStatus().getServerUsed().getHost();
}
@ManagedMetric(displayName = "Uptime Estimate")
@@ -73,4 +72,5 @@ public class ServerInfo extends AbstractMonitor {
public double getUptime() {
return (Double) getServerStatus().get("uptime");
}
}

View File

@@ -38,7 +38,7 @@ import org.springframework.data.annotation.QueryAnnotation;
public @interface Query {
/**
* Takes a MongoDB JSON string to define the actual query to be executed. This one will take precendece over the
* Takes a MongoDB JSON string to define the actual query to be executed. This one will take precedence over the
* method name then.
*
* @return

View File

@@ -27,7 +27,6 @@ import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Import;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
import org.springframework.data.repository.config.DefaultRepositoryBaseClass;
import org.springframework.data.repository.query.QueryLookupStrategy;
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
@@ -108,14 +107,6 @@ public @interface EnableMongoRepositories {
*/
Class<?> repositoryFactoryBeanClass() default MongoRepositoryFactoryBean.class;
/**
* Configure the repository base class to be used to create repository proxies for this particular configuration.
*
* @return
* @since 1.8
*/
Class<?> repositoryBaseClass() default DefaultRepositoryBaseClass.class;
/**
* Configures the name of the {@link MongoTemplate} bean to be used with the repositories detected.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2014 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.
@@ -18,9 +18,10 @@ package org.springframework.data.mongodb.repository.query;
import java.util.Collections;
import java.util.List;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Range;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.data.geo.Distance;
@@ -33,8 +34,6 @@ import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.query.ParameterAccessor;
import org.springframework.data.repository.query.RepositoryQuery;
import org.springframework.data.util.CloseableIterator;
import org.springframework.data.util.StreamUtils;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert;
@@ -49,6 +48,8 @@ import com.mongodb.WriteResult;
*/
public abstract class AbstractMongoQuery implements RepositoryQuery {
private static final ConversionService CONVERSION_SERVICE = new DefaultConversionService();
private final MongoQueryMethod method;
private final MongoOperations operations;
@@ -60,8 +61,8 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
*/
public AbstractMongoQuery(MongoQueryMethod method, MongoOperations operations) {
Assert.notNull(operations, "MongoOperations must not be null!");
Assert.notNull(method, "MongoQueryMethod must not be null!");
Assert.notNull(operations);
Assert.notNull(method);
this.method = method;
this.operations = operations;
@@ -86,9 +87,7 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
applyQueryMetaAttributesWhenPresent(query);
if (method.isStreamQuery()) {
return new StreamExecution().execute(query);
} else if (isDeleteQuery()) {
if (isDeleteQuery()) {
return new DeleteExecution().execute(query);
} else if (method.isGeoNearQuery() && method.isPageQuery()) {
@@ -114,7 +113,6 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
if (method.hasQueryMetaAttributes()) {
query.setMeta(method.getQueryMetaAttributes());
}
return query;
}
@@ -308,8 +306,8 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
Object execute(Query query) {
MongoEntityMetadata<?> metadata = method.getEntityInformation();
return countProjection ? operations.count(query, metadata.getJavaType())
: operations.findOne(query, metadata.getJavaType(), metadata.getCollectionName());
return countProjection ? operations.count(query, metadata.getJavaType()) : operations.findOne(query,
metadata.getJavaType(), metadata.getCollectionName());
}
}
@@ -362,19 +360,11 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
nearQuery.query(query);
}
Range<Distance> distances = accessor.getDistanceRange();
Distance maxDistance = distances.getUpperBound();
Distance maxDistance = accessor.getMaxDistance();
if (maxDistance != null) {
nearQuery.maxDistance(maxDistance).in(maxDistance.getMetric());
}
Distance minDistance = distances.getLowerBound();
if (minDistance != null) {
nearQuery.minDistance(minDistance).in(minDistance.getMetric());
}
Pageable pageable = accessor.getPageable();
if (pageable != null) {
nearQuery.with(pageable);
@@ -425,24 +415,4 @@ public abstract class AbstractMongoQuery implements RepositoryQuery {
return writeResult != null ? writeResult.getN() : 0L;
}
}
/**
* @author Thomas Darimont
* @since 1.7
*/
final class StreamExecution extends Execution {
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.query.AbstractMongoQuery.Execution#execute(org.springframework.data.mongodb.core.query.Query)
*/
@Override
@SuppressWarnings("unchecked")
Object execute(Query query) {
Class<?> entityType = getQueryMethod().getEntityInformation().getJavaType();
return StreamUtils.createStreamFromIterator((CloseableIterator<Object>) operations.stream(query, entityType));
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -22,7 +22,6 @@ import java.util.Iterator;
import java.util.List;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Range;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
@@ -41,7 +40,6 @@ import com.mongodb.DBRef;
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Thomas Darimont
*/
public class ConvertingParameterAccessor implements MongoParameterAccessor {
@@ -98,13 +96,12 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
return getConvertedValue(delegate.getBindableValue(index), null);
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.query.MongoParameterAccessor#getDistanceRange()
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getMaxDistance()
*/
@Override
public Range<Distance> getDistanceRange() {
return delegate.getDistanceRange();
public Distance getMaxDistance() {
return delegate.getMaxDistance();
}
/*
@@ -217,7 +214,7 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
/**
* Returns the given object as {@link Collection}. Will do a copy of it if it implements {@link Iterable} or is an
* array. Will return an empty {@link Collection} in case {@literal null} is given. Will wrap all other types into a
* single-element collection.
* single-element collction
*
* @param source
* @return
@@ -241,15 +238,6 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
return source.getClass().isArray() ? CollectionUtils.arrayToList(source) : Collections.singleton(source);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.query.MongoParameterAccessor#getValues()
*/
@Override
public Object[] getValues() {
return delegate.getValues();
}
/**
* Custom {@link Iterator} that adds a method to access elements in a converted manner.
*
@@ -264,5 +252,4 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor {
*/
Object nextConverted(MongoPersistentProperty property);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -15,7 +15,6 @@
*/
package org.springframework.data.mongodb.repository.query;
import org.springframework.data.domain.Range;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.query.TextCriteria;
@@ -26,7 +25,6 @@ import org.springframework.data.repository.query.ParameterAccessor;
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Thomas Darimont
*/
public interface MongoParameterAccessor extends ParameterAccessor {
@@ -36,7 +34,7 @@ public interface MongoParameterAccessor extends ParameterAccessor {
* @return the maximum distance to apply to the geo query or {@literal null} if there's no {@link Distance} parameter
* at all or the given value for it was {@literal null}.
*/
Range<Distance> getDistanceRange();
Distance getMaxDistance();
/**
* Returns the {@link Point} to use for a geo-near query.
@@ -52,12 +50,4 @@ public interface MongoParameterAccessor extends ParameterAccessor {
* @since 1.6
*/
TextCriteria getFullText();
/**
* Returns the raw parameter values of the underlying query method.
*
* @return
* @since 1.8
*/
Object[] getValues();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -20,7 +20,6 @@ import java.util.Arrays;
import java.util.List;
import org.springframework.core.MethodParameter;
import org.springframework.data.domain.Range;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.query.TextCriteria;
@@ -28,8 +27,6 @@ import org.springframework.data.mongodb.repository.Near;
import org.springframework.data.mongodb.repository.query.MongoParameters.MongoParameter;
import org.springframework.data.repository.query.Parameter;
import org.springframework.data.repository.query.Parameters;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
/**
* Custom extension of {@link Parameters} discovering additional
@@ -39,8 +36,7 @@ import org.springframework.data.util.TypeInformation;
*/
public class MongoParameters extends Parameters<MongoParameters, MongoParameter> {
private final int rangeIndex;
private final int maxDistanceIndex;
private final Integer distanceIndex;
private final Integer fullTextIndex;
private Integer nearIndex;
@@ -55,15 +51,9 @@ public class MongoParameters extends Parameters<MongoParameters, MongoParameter>
super(method);
List<Class<?>> parameterTypes = Arrays.asList(method.getParameterTypes());
this.distanceIndex = parameterTypes.indexOf(Distance.class);
this.fullTextIndex = parameterTypes.indexOf(TextCriteria.class);
ClassTypeInformation<?> declaringClassInfo = ClassTypeInformation.from(method.getDeclaringClass());
List<TypeInformation<?>> parameterTypeInfo = declaringClassInfo.getParameterTypes(method);
this.rangeIndex = getTypeIndex(parameterTypeInfo, Range.class, Distance.class);
this.maxDistanceIndex = this.rangeIndex == -1 ? getTypeIndex(parameterTypeInfo, Distance.class, null) : -1;
if (this.nearIndex == null && isGeoNearMethod) {
this.nearIndex = getNearIndex(parameterTypes);
} else if (this.nearIndex == null) {
@@ -71,15 +61,14 @@ public class MongoParameters extends Parameters<MongoParameters, MongoParameter>
}
}
private MongoParameters(List<MongoParameter> parameters, int maxDistanceIndex, Integer nearIndex,
Integer fullTextIndex, int rangeIndex) {
private MongoParameters(List<MongoParameter> parameters, Integer distanceIndex, Integer nearIndex,
Integer fullTextIndex) {
super(parameters);
this.distanceIndex = distanceIndex;
this.nearIndex = nearIndex;
this.fullTextIndex = fullTextIndex;
this.maxDistanceIndex = maxDistanceIndex;
this.rangeIndex = rangeIndex;
}
private final int getNearIndex(List<Class<?>> parameterTypes) {
@@ -122,29 +111,13 @@ public class MongoParameters extends Parameters<MongoParameters, MongoParameter>
return mongoParameter;
}
public int getDistanceRangeIndex() {
return -1;
}
/**
* Returns the index of a {@link Distance} parameter to be used for geo queries.
*
* @return
* @deprecated since 1.7. Please use {@link #getMaxDistanceIndex()} instead.
*/
@Deprecated
public int getDistanceIndex() {
return getMaxDistanceIndex();
}
/**
* Returns the index of the {@link Distance} parameter to be used for max distance in geo queries.
*
* @return
* @since 1.7
*/
public int getMaxDistanceIndex() {
return maxDistanceIndex;
return distanceIndex;
}
/**
@@ -174,40 +147,13 @@ public class MongoParameters extends Parameters<MongoParameters, MongoParameter>
return this.fullTextIndex != null && this.fullTextIndex.intValue() >= 0;
}
/**
* @return
* @since 1.7
*/
public int getRangeIndex() {
return rangeIndex;
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.Parameters#createFrom(java.util.List)
*/
@Override
protected MongoParameters createFrom(List<MongoParameter> parameters) {
return new MongoParameters(parameters, this.maxDistanceIndex, this.nearIndex, this.fullTextIndex, this.rangeIndex);
}
private int getTypeIndex(List<TypeInformation<?>> parameterTypes, Class<?> type, Class<?> componentType) {
for (int i = 0; i < parameterTypes.size(); i++) {
TypeInformation<?> candidate = parameterTypes.get(i);
if (candidate.getType().equals(type)) {
if (componentType == null) {
return i;
} else if (componentType.equals(candidate.getComponentType().getType())) {
return i;
}
}
}
return -1;
return new MongoParameters(parameters, this.distanceIndex, this.nearIndex, this.fullTextIndex);
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -15,7 +15,6 @@
*/
package org.springframework.data.mongodb.repository.query;
import org.springframework.data.domain.Range;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.query.Term;
@@ -29,39 +28,29 @@ import org.springframework.util.ClassUtils;
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Thomas Darimont
*/
public class MongoParametersParameterAccessor extends ParametersParameterAccessor implements MongoParameterAccessor {
private final MongoQueryMethod method;
private final Object[] values;
/**
* Creates a new {@link MongoParametersParameterAccessor}.
*
* @param method must not be {@literal null}.
* @param values must not be {@literal null}.
* @param values must not be {@@iteral null}.
*/
public MongoParametersParameterAccessor(MongoQueryMethod method, Object[] values) {
super(method.getParameters(), values);
this.method = method;
this.values = values;
}
public Range<Distance> getDistanceRange() {
MongoParameters mongoParameters = method.getParameters();
int rangeIndex = mongoParameters.getRangeIndex();
if (rangeIndex != -1) {
return getValue(rangeIndex);
}
int maxDistanceIndex = mongoParameters.getMaxDistanceIndex();
Distance maxDistance = maxDistanceIndex == -1 ? null : (Distance) getValue(maxDistanceIndex);
return new Range<Distance>(null, maxDistance);
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.MongoParameterAccessor#getMaxDistance()
*/
public Distance getMaxDistance() {
int index = method.getParameters().getDistanceIndex();
return index == -1 ? null : (Distance) getValue(index);
}
/*
@@ -120,17 +109,8 @@ public class MongoParametersParameterAccessor extends ParametersParameterAccesso
return ((TextCriteria) fullText);
}
throw new IllegalArgumentException(
String.format("Expected full text parameter to be one of String, Term or TextCriteria but found %s.",
ClassUtils.getShortName(fullText.getClass())));
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.query.MongoParameterAccessor#getValues()
*/
@Override
public Object[] getValues() {
return values;
throw new IllegalArgumentException(String.format(
"Expected full text parameter to be one of String, Term or TextCriteria but found %s.",
ClassUtils.getShortName(fullText.getClass())));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-2014 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.
@@ -20,19 +20,18 @@ import static org.springframework.data.mongodb.core.query.Criteria.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Range;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.geo.Shape;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mapping.context.PersistentPropertyPath;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexType;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexed;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
@@ -44,6 +43,7 @@ import org.springframework.data.repository.query.parser.Part.IgnoreCaseType;
import org.springframework.data.repository.query.parser.Part.Type;
import org.springframework.data.repository.query.parser.PartTree;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* Custom query creator to create Mongo criterias.
@@ -55,6 +55,7 @@ import org.springframework.util.Assert;
class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
private static final Logger LOG = LoggerFactory.getLogger(MongoQueryCreator.class);
private static final Pattern PUNCTATION_PATTERN = Pattern.compile("\\p{Punct}");
private final MongoParameterAccessor accessor;
private final boolean isGeoNearQuery;
@@ -196,8 +197,6 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
case ENDING_WITH:
case CONTAINING:
return createContainingCriteria(part, property, criteria, parameters);
case NOT_CONTAINING:
return createContainingCriteria(part, property, criteria, parameters).not();
case REGEX:
return criteria.regex(parameters.next().toString());
case EXISTS:
@@ -208,27 +207,19 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
return criteria.is(false);
case NEAR:
Range<Distance> range = accessor.getDistanceRange();
Distance distance = range.getUpperBound();
Distance minDistance = range.getLowerBound();
Distance distance = accessor.getMaxDistance();
Point point = accessor.getGeoNearLocation();
point = point == null ? nextAs(parameters, Point.class) : point;
boolean isSpherical = isSpherical(property);
if (distance == null) {
return isSpherical ? criteria.nearSphere(point) : criteria.near(point);
return criteria.near(point);
} else {
if (isSpherical || !Metrics.NEUTRAL.equals(distance.getMetric())) {
if (!Metrics.NEUTRAL.equals(distance.getMetric())) {
criteria.nearSphere(point);
} else {
criteria.near(point);
}
criteria.maxDistance(distance.getNormalizedValue());
if (minDistance != null) {
criteria.minDistance(minDistance.getNormalizedValue());
}
}
return criteria;
case WITHIN:
@@ -276,19 +267,23 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
private Criteria createLikeRegexCriteriaOrThrow(Part part, MongoPersistentProperty property, Criteria criteria,
PotentiallyConvertingIterator parameters, boolean shouldNegateExpression) {
PropertyPath path = part.getProperty().getLeafProperty();
switch (part.shouldIgnoreCase()) {
case ALWAYS:
if (part.getProperty().getType() != String.class) {
throw new IllegalArgumentException(String.format("part %s must be of type String but was %s",
part.getProperty(), part.getType()));
if (path.getType() != String.class) {
throw new IllegalArgumentException(
String.format("Part %s must be of type String but was %s", path, path.getType()));
}
// fall-through
case WHEN_POSSIBLE:
if (shouldNegateExpression) {
criteria = criteria.not();
}
return addAppropriateLikeRegexTo(criteria, part, parameters.nextConverted(property).toString());
case NEVER:
@@ -365,8 +360,8 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
return (T) parameter;
}
throw new IllegalArgumentException(String.format("Expected parameter type of %s but got %s!", type,
parameter.getClass()));
throw new IllegalArgumentException(
String.format("Expected parameter type of %s but got %s!", type, parameter.getClass()));
}
private Object[] nextAsArray(PotentiallyConvertingIterator iterator, MongoPersistentProperty property) {
@@ -384,30 +379,57 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
private String toLikeRegex(String source, Part part) {
Type type = part.getType();
String regex = prepareAndEscapeStringBeforeApplyingLikeRegex(source, part);
switch (type) {
case STARTING_WITH:
source = "^" + source;
regex = "^" + regex;
break;
case ENDING_WITH:
source = source + "$";
regex = regex + "$";
break;
case CONTAINING:
case NOT_CONTAINING:
source = "*" + source + "*";
regex = ".*" + regex + ".*";
break;
case SIMPLE_PROPERTY:
case NEGATING_SIMPLE_PROPERTY:
source = "^" + source + "$";
regex = "^" + regex + "$";
default:
}
return source.replaceAll("\\*", ".*");
return regex;
}
private boolean isSpherical(MongoPersistentProperty property) {
private String prepareAndEscapeStringBeforeApplyingLikeRegex(String source, Part qpart) {
GeoSpatialIndexed index = property.findAnnotation(GeoSpatialIndexed.class);
return index != null && index.type().equals(GeoSpatialIndexType.GEO_2DSPHERE);
if (!ObjectUtils.nullSafeEquals(Type.LIKE, qpart.getType())) {
return PUNCTATION_PATTERN.matcher(source).find() ? Pattern.quote(source) : source;
}
if (source.equals("*")) {
return ".*";
}
StringBuilder sb = new StringBuilder();
boolean leadingWildcard = source.startsWith("*");
boolean trailingWildcard = source.endsWith("*");
String valueToUse = source.substring(leadingWildcard ? 1 : 0,
trailingWildcard ? source.length() - 1 : source.length());
if (PUNCTATION_PATTERN.matcher(valueToUse).find()) {
valueToUse = Pattern.quote(valueToUse);
}
if (leadingWildcard) {
sb.append(".*");
}
sb.append(valueToUse);
if (trailingWildcard) {
sb.append(".*");
}
return sb.toString();
}
}

View File

@@ -34,7 +34,6 @@ import com.mongodb.util.JSONParseException;
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Thomas Darimont
*/
public class PartTreeMongoQuery extends AbstractMongoQuery {
@@ -46,7 +45,7 @@ public class PartTreeMongoQuery extends AbstractMongoQuery {
* Creates a new {@link PartTreeMongoQuery} from the given {@link QueryMethod} and {@link MongoTemplate}.
*
* @param method must not be {@literal null}.
* @param mongoOperations must not be {@literal null}.
* @param template must not be {@literal null}.
*/
public PartTreeMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -26,11 +26,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.query.EvaluationContextProvider;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.mongodb.DBObject;
@@ -48,7 +43,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
private static final String COUND_AND_DELETE = "Manually defined query for %s cannot be both a count and delete query at the same time!";
private static final Logger LOG = LoggerFactory.getLogger(StringBasedMongoQuery.class);
private static final ParameterBindingParser BINDING_PARSER = ParameterBindingParser.INSTANCE;
private static final ParameterBindingParser PARSER = ParameterBindingParser.INSTANCE;
private final String query;
private final String fieldSpec;
@@ -56,49 +51,33 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
private final boolean isDeleteQuery;
private final List<ParameterBinding> queryParameterBindings;
private final List<ParameterBinding> fieldSpecParameterBindings;
private final SpelExpressionParser expressionParser;
private final EvaluationContextProvider evaluationContextProvider;
/**
* Creates a new {@link StringBasedMongoQuery} for the given {@link MongoQueryMethod} and {@link MongoOperations}.
*
* @param method must not be {@literal null}.
* @param mongoOperations must not be {@literal null}.
* @param expressionParser must not be {@literal null}.
* @param evaluationContextProvider must not be {@literal null}.
*/
public StringBasedMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations,
SpelExpressionParser expressionParser, EvaluationContextProvider evaluationContextProvider) {
this(method.getAnnotatedQuery(), method, mongoOperations, expressionParser, evaluationContextProvider);
public StringBasedMongoQuery(MongoQueryMethod method, MongoOperations mongoOperations) {
this(method.getAnnotatedQuery(), method, mongoOperations);
}
/**
* Creates a new {@link StringBasedMongoQuery} for the given {@link String}, {@link MongoQueryMethod},
* {@link MongoOperations}, {@link SpelExpressionParser} and {@link EvaluationContextProvider}.
*
* @param query must not be {@literal null}.
* Creates a new {@link StringBasedMongoQuery} for the given {@link String}, {@link MongoQueryMethod} and
* {@link MongoOperations}.
*
* @param method must not be {@literal null}.
* @param mongoOperations must not be {@literal null}.
* @param expressionParser must not be {@literal null}.
* @param template must not be {@literal null}.
*/
public StringBasedMongoQuery(String query, MongoQueryMethod method, MongoOperations mongoOperations,
SpelExpressionParser expressionParser, EvaluationContextProvider evaluationContextProvider) {
public StringBasedMongoQuery(String query, MongoQueryMethod method, MongoOperations mongoOperations) {
super(method, mongoOperations);
Assert.notNull(query, "Query must not be null!");
Assert.notNull(expressionParser, "SpelExpressionParser must not be null!");
this.query = query;
this.queryParameterBindings = PARSER.parseParameterBindingsFrom(query);
this.expressionParser = expressionParser;
this.evaluationContextProvider = evaluationContextProvider;
this.queryParameterBindings = new ArrayList<ParameterBinding>();
this.query = BINDING_PARSER.parseAndCollectParameterBindingsFromQueryIntoBindings(query,
this.queryParameterBindings);
this.fieldSpecParameterBindings = new ArrayList<ParameterBinding>();
this.fieldSpec = BINDING_PARSER.parseAndCollectParameterBindingsFromQueryIntoBindings(
method.getFieldSpecification(), this.fieldSpecParameterBindings);
this.fieldSpec = method.getFieldSpecification();
this.fieldSpecParameterBindings = PARSER.parseParameterBindingsFrom(method.getFieldSpecification());
this.isCountQuery = method.hasAnnotatedQuery() ? method.getQueryAnnotation().count() : false;
this.isDeleteQuery = method.hasAnnotatedQuery() ? method.getQueryAnnotation().delete() : false;
@@ -161,8 +140,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
* @param bindings
* @return
*/
private String replacePlaceholders(String input, ConvertingParameterAccessor accessor,
List<ParameterBinding> bindings) {
private String replacePlaceholders(String input, ConvertingParameterAccessor accessor, List<ParameterBinding> bindings) {
if (bindings.isEmpty()) {
return input;
@@ -192,8 +170,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
*/
private String getParameterValueForBinding(ConvertingParameterAccessor accessor, ParameterBinding binding) {
Object value = binding.isExpression() ? evaluateExpression(binding.getExpression(), accessor.getValues())
: accessor.getBindableValue(binding.getParameterIndex());
Object value = accessor.getBindableValue(binding.getParameterIndex());
if (value instanceof String && binding.isQuoted()) {
return (String) value;
@@ -202,21 +179,6 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
return JSON.serialize(value);
}
/**
* Evaluates the given {@code expressionString}.
*
* @param expressionString
* @param parameterValues
* @return
*/
private Object evaluateExpression(String expressionString, Object[] parameterValues) {
EvaluationContext evaluationContext = evaluationContextProvider
.getEvaluationContext(getQueryMethod().getParameters(), parameterValues);
Expression expression = expressionParser.parseExpression(expressionString);
return expression.getValue(evaluationContext, Object.class);
}
/**
* A parser that extracts the parameter bindings from a given query string.
*
@@ -230,7 +192,6 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
private static final String PARSEABLE_PARAMETER = "\"" + PARAMETER_PREFIX + "$1\"";
private static final Pattern PARAMETER_BINDING_PATTERN = Pattern.compile("\\?(\\d+)");
private static final Pattern PARSEABLE_BINDING_PATTERN = Pattern.compile("\"?" + PARAMETER_PREFIX + "(\\d+)\"?");
private static final Pattern PARAMETER_EXPRESSION_PATTERN = Pattern.compile("((:|\\?)#\\{([^}]+)\\})");
private final static int PARAMETER_INDEX_GROUP = 1;
@@ -238,53 +199,23 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
* Returns a list of {@link ParameterBinding}s found in the given {@code input} or an
* {@link Collections#emptyList()}.
*
* @param input can be {@literal null} or empty.
* @param bindings must not be {@literal null}.
* @param input
* @param conversionService must not be {@literal null}.
* @return
*/
public String parseAndCollectParameterBindingsFromQueryIntoBindings(String input, List<ParameterBinding> bindings) {
public List<ParameterBinding> parseParameterBindingsFrom(String input) {
if (!StringUtils.hasText(input)) {
return input;
return Collections.emptyList();
}
Assert.notNull(bindings, "Parameter bindings must not be null!");
List<ParameterBinding> bindings = new ArrayList<ParameterBinding>();
String transformedInput = transformQueryAndCollectExpressionParametersIntoBindings(input, bindings);
String parseableInput = makeParameterReferencesParseable(transformedInput);
String parseableInput = makeParameterReferencesParseable(input);
collectParameterReferencesIntoBindings(bindings, JSON.parse(parseableInput));
return transformedInput;
}
private String transformQueryAndCollectExpressionParametersIntoBindings(String input,
List<ParameterBinding> bindings) {
Matcher matcher = PARAMETER_EXPRESSION_PATTERN.matcher(input);
StringBuilder result = new StringBuilder();
int lastPos = 0;
int exprIndex = 0;
while (matcher.find()) {
int startOffSet = matcher.start();
result.append(input.subSequence(lastPos, startOffSet));
result.append("'?expr").append(exprIndex).append("'");
lastPos = matcher.end();
bindings.add(new ParameterBinding(exprIndex, true, matcher.group(3)));
exprIndex++;
}
result.append(input.subSequence(lastPos, input.length()));
return result.toString();
return bindings;
}
private String makeParameterReferencesParseable(String input) {
@@ -305,10 +236,9 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
} else if (value instanceof Pattern) {
String string = ((Pattern) value).toString().trim();
Matcher valueMatcher = PARSEABLE_BINDING_PATTERN.matcher(string);
while (valueMatcher.find()) {
int paramIndex = Integer.parseInt(valueMatcher.group(PARAMETER_INDEX_GROUP));
/*
@@ -324,7 +254,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
DBRef dbref = (DBRef) value;
potentiallyAddBinding(dbref.getCollectionName(), bindings);
potentiallyAddBinding(dbref.getRef(), bindings);
potentiallyAddBinding(dbref.getId().toString(), bindings);
} else if (value instanceof DBObject) {
@@ -362,7 +292,6 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
private final int parameterIndex;
private final boolean quoted;
private final String expression;
/**
* Creates a new {@link ParameterBinding} with the given {@code parameterIndex} and {@code quoted} information.
@@ -371,14 +300,9 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
* @param quoted whether or not the parameter is already quoted.
*/
public ParameterBinding(int parameterIndex, boolean quoted) {
this(parameterIndex, quoted, null);
}
public ParameterBinding(int parameterIndex, boolean quoted, String expression) {
this.parameterIndex = parameterIndex;
this.quoted = quoted;
this.expression = expression;
}
public boolean isQuoted() {
@@ -390,15 +314,7 @@ public class StringBasedMongoQuery extends AbstractMongoQuery {
}
public String getParameter() {
return "?" + (isExpression() ? "expr" : "") + parameterIndex;
}
public String getExpression() {
return expression;
}
public boolean isExpression() {
return this.expression != null;
return "?" + parameterIndex;
}
}
}

View File

@@ -17,9 +17,11 @@ package org.springframework.data.mongodb.repository.support;
import java.io.Serializable;
import org.springframework.data.mapping.model.BeanWrapper;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.repository.query.MongoEntityInformation;
import org.springframework.data.repository.core.support.PersistentEntityInformation;
import org.springframework.data.repository.core.support.AbstractEntityInformation;
/**
* {@link MongoEntityInformation} implementation using a {@link MongoPersistentEntity} instance to lookup the necessary
@@ -28,7 +30,7 @@ import org.springframework.data.repository.core.support.PersistentEntityInformat
*
* @author Oliver Gierke
*/
public class MappingMongoEntityInformation<T, ID extends Serializable> extends PersistentEntityInformation<T, ID>
public class MappingMongoEntityInformation<T, ID extends Serializable> extends AbstractEntityInformation<T, ID>
implements MongoEntityInformation<T, ID> {
private final MongoPersistentEntity<T> entityMetadata;
@@ -48,16 +50,42 @@ public class MappingMongoEntityInformation<T, ID extends Serializable> extends P
* collection name.
*
* @param entity must not be {@literal null}.
* @param customCollectionName can be {@literal null}.
* @param customCollectionName
*/
public MappingMongoEntityInformation(MongoPersistentEntity<T> entity, String customCollectionName) {
super(entity);
super(entity.getType());
this.entityMetadata = entity;
this.customCollectionName = customCollectionName;
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.support.EntityInformation#getId(java.lang.Object)
*/
@SuppressWarnings("unchecked")
public ID getId(T entity) {
MongoPersistentProperty idProperty = entityMetadata.getIdProperty();
if (idProperty == null) {
return null;
}
try {
return (ID) BeanWrapper.create(entity, null).getProperty(idProperty);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/* (non-Javadoc)
* @see org.springframework.data.repository.support.EntityInformation#getIdType()
*/
@SuppressWarnings("unchecked")
public Class<ID> getIdType() {
return (Class<ID>) entityMetadata.getIdProperty().getType();
}
/* (non-Javadoc)
* @see org.springframework.data.mongodb.repository.MongoEntityInformation#getCollectionName()
*/

View File

@@ -35,7 +35,7 @@ import com.mysema.query.apt.Configuration;
import com.mysema.query.apt.DefaultConfiguration;
/**
* Annotation processor to create Querydsl query types for QueryDsl annoated classes.
* Annotation processor to create Querydsl query types for QueryDsl annotated classes.
*
* @author Oliver Gierke
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 the original author or authors.
* Copyright 2010-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.
@@ -32,38 +32,31 @@ import org.springframework.data.mongodb.repository.query.PartTreeMongoQuery;
import org.springframework.data.mongodb.repository.query.StringBasedMongoQuery;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.data.repository.core.NamedQueries;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.data.repository.query.EvaluationContextProvider;
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.expression.spel.standard.SpelExpressionParser;
import org.springframework.util.Assert;
/**
* Factory to create {@link MongoRepository} instances.
*
* @author Oliver Gierke
* @author Thomas Darimont
*/
public class MongoRepositoryFactory extends RepositoryFactorySupport {
private static final SpelExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
private final MongoOperations mongoOperations;
private final MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentProperty> mappingContext;
/**
* Creates a new {@link MongoRepositoryFactory} with the given {@link MongoOperations}.
*
* @param mongoOperations must not be {@literal null}.
* @param mongoOperations must not be {@literal null}
*/
public MongoRepositoryFactory(MongoOperations mongoOperations) {
Assert.notNull(mongoOperations);
this.mongoOperations = mongoOperations;
this.mappingContext = mongoOperations.getConverter().getMappingContext();
}
@@ -74,31 +67,67 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport {
*/
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
boolean isQueryDslRepository = QUERY_DSL_PRESENT
&& QueryDslPredicateExecutor.class.isAssignableFrom(metadata.getRepositoryInterface());
return isQueryDslRepository ? QueryDslMongoRepository.class : SimpleMongoRepository.class;
return isQueryDslRepository(metadata.getRepositoryInterface()) ? QueryDslMongoRepository.class
: SimpleMongoRepository.class;
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getTargetRepository(org.springframework.data.repository.core.RepositoryInformation)
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getTargetRepository(org.springframework.data.repository.core.RepositoryMetadata)
*/
@Override
protected Object getTargetRepository(RepositoryInformation information) {
@SuppressWarnings({ "rawtypes", "unchecked" })
protected Object getTargetRepository(RepositoryMetadata metadata) {
MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType());
return getTargetRepositoryViaReflection(information, entityInformation, mongoOperations);
Class<?> repositoryInterface = metadata.getRepositoryInterface();
MongoEntityInformation<?, Serializable> entityInformation = getEntityInformation(metadata.getDomainType());
if (isQueryDslRepository(repositoryInterface)) {
return new QueryDslMongoRepository(entityInformation, mongoOperations);
} else {
return new SimpleMongoRepository(entityInformation, mongoOperations);
}
}
/*
private static boolean isQueryDslRepository(Class<?> repositoryInterface) {
return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider)
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key)
*/
@Override
protected QueryLookupStrategy getQueryLookupStrategy(Key key, EvaluationContextProvider evaluationContextProvider) {
return new MongoQueryLookupStrategy(evaluationContextProvider);
protected QueryLookupStrategy getQueryLookupStrategy(Key key) {
return new MongoQueryLookupStrategy();
}
/**
* {@link QueryLookupStrategy} to create {@link PartTreeMongoQuery} instances.
*
* @author Oliver Gierke
*/
private class MongoQueryLookupStrategy implements QueryLookupStrategy {
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryLookupStrategy#resolveQuery(java.lang.reflect.Method, org.springframework.data.repository.core.RepositoryMetadata, org.springframework.data.repository.core.NamedQueries)
*/
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, NamedQueries namedQueries) {
MongoQueryMethod queryMethod = new MongoQueryMethod(method, metadata, mappingContext);
String namedQueryName = queryMethod.getNamedQueryName();
if (namedQueries.hasQuery(namedQueryName)) {
String namedQuery = namedQueries.getQuery(namedQueryName);
return new StringBasedMongoQuery(namedQuery, queryMethod, mongoOperations);
} else if (queryMethod.hasAnnotatedQuery()) {
return new StringBasedMongoQuery(queryMethod, mongoOperations);
} else {
return new PartTreeMongoQuery(queryMethod, mongoOperations);
}
}
}
/*
@@ -112,45 +141,10 @@ public class MongoRepositoryFactory extends RepositoryFactorySupport {
MongoPersistentEntity<?> entity = mappingContext.getPersistentEntity(domainClass);
if (entity == null) {
throw new MappingException(
String.format("Could not lookup mapping metadata for domain class %s!", domainClass.getName()));
throw new MappingException(String.format("Could not lookup mapping metadata for domain class %s!",
domainClass.getName()));
}
return new MappingMongoEntityInformation<T, ID>((MongoPersistentEntity<T>) entity);
}
/**
* {@link QueryLookupStrategy} to create {@link PartTreeMongoQuery} instances.
*
* @author Oliver Gierke
* @author Thomas Darimont
*/
private class MongoQueryLookupStrategy implements QueryLookupStrategy {
private final EvaluationContextProvider evaluationContextProvider;
public MongoQueryLookupStrategy(EvaluationContextProvider evaluationContextProvider) {
this.evaluationContextProvider = evaluationContextProvider;
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.QueryLookupStrategy#resolveQuery(java.lang.reflect.Method, org.springframework.data.repository.core.RepositoryMetadata, org.springframework.data.repository.core.NamedQueries)
*/
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, NamedQueries namedQueries) {
MongoQueryMethod queryMethod = new MongoQueryMethod(method, metadata, mappingContext);
String namedQueryName = queryMethod.getNamedQueryName();
if (namedQueries.hasQuery(namedQueryName)) {
String namedQuery = namedQueries.getQuery(namedQueryName);
return new StringBasedMongoQuery(namedQuery, queryMethod, mongoOperations, EXPRESSION_PARSER,
evaluationContextProvider);
} else if (queryMethod.hasAnnotatedQuery()) {
return new StringBasedMongoQuery(queryMethod, mongoOperations, EXPRESSION_PARSER, evaluationContextProvider);
} else {
return new PartTreeMongoQuery(queryMethod, mongoOperations);
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2015 the original author or authors.
* Copyright 2011-2014 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.
@@ -90,7 +90,6 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
* (non-Javadoc)
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findOne(com.mysema.query.types.Predicate)
*/
@Override
public T findOne(Predicate predicate) {
return createQueryFor(predicate).uniqueResult();
}
@@ -99,7 +98,6 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
* (non-Javadoc)
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.Predicate)
*/
@Override
public List<T> findAll(Predicate predicate) {
return createQueryFor(predicate).list();
}
@@ -108,34 +106,14 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
* (non-Javadoc)
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.Predicate, com.mysema.query.types.OrderSpecifier<?>[])
*/
@Override
public List<T> findAll(Predicate predicate, OrderSpecifier<?>... orders) {
return createQueryFor(predicate).orderBy(orders).list();
}
/*
* (non-Javadoc)
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.Predicate, org.springframework.data.domain.Sort)
*/
@Override
public List<T> findAll(Predicate predicate, Sort sort) {
return applySorting(createQueryFor(predicate), sort).list();
}
/*
* (non-Javadoc)
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.OrderSpecifier[])
*/
@Override
public Iterable<T> findAll(OrderSpecifier<?>... orders) {
return createQuery().orderBy(orders).list();
}
/*
* (non-Javadoc)
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findAll(com.mysema.query.types.Predicate, org.springframework.data.domain.Pageable)
*/
@Override
public Page<T> findAll(Predicate predicate, Pageable pageable) {
MongodbQuery<T> countQuery = createQueryFor(predicate);
@@ -170,20 +148,10 @@ public class QueryDslMongoRepository<T, ID extends Serializable> extends SimpleM
* (non-Javadoc)
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#count(com.mysema.query.types.Predicate)
*/
@Override
public long count(Predicate predicate) {
return createQueryFor(predicate).count();
}
/*
* (non-Javadoc)
* @see org.springframework.data.querydsl.QueryDslPredicateExecutor#exists(com.mysema.query.types.Predicate)
*/
@Override
public boolean exists(Predicate predicate) {
return createQueryFor(predicate).exists();
}
/**
* Creates a {@link MongodbQuery} for the given {@link Predicate}.
*

View File

@@ -1,47 +0,0 @@
/*
* Copyright 2015 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.mongodb.util;
import org.springframework.util.ClassUtils;
/**
* {@link MongoClientVersion} holds information about the used mongo-java client and is used to distinguish between
* different versions.
*
* @author Christoph Strobl
* @since 1.7
*/
public class MongoClientVersion {
private static final boolean IS_MONGO_30 = ClassUtils.isPresent("com.mongodb.binding.SingleServerBinding",
MongoClientVersion.class.getClassLoader());
private static final boolean IS_ASYNC_CLIENT = ClassUtils.isPresent("com.mongodb.async.client.MongoClient",
MongoClientVersion.class.getClassLoader());
/**
* @return |literal true} if MongoDB Java driver version 3.0 or later is on classpath.
*/
public static boolean isMongo3Driver() {
return IS_MONGO_30;
}
/**
* @return {lliteral true} if MongoDB Java driver is on classpath.
*/
public static boolean isAsyncClient() {
return IS_ASYNC_CLIENT;
}
}

View File

@@ -4,6 +4,4 @@ http\://www.springframework.org/schema/data/mongo/spring-mongo-1.2.xsd=org/sprin
http\://www.springframework.org/schema/data/mongo/spring-mongo-1.3.xsd=org/springframework/data/mongodb/config/spring-mongo-1.3.xsd
http\://www.springframework.org/schema/data/mongo/spring-mongo-1.4.xsd=org/springframework/data/mongodb/config/spring-mongo-1.4.xsd
http\://www.springframework.org/schema/data/mongo/spring-mongo-1.5.xsd=org/springframework/data/mongodb/config/spring-mongo-1.5.xsd
http\://www.springframework.org/schema/data/mongo/spring-mongo-1.7.xsd=org/springframework/data/mongodb/config/spring-mongo-1.7.xsd
http\://www.springframework.org/schema/data/mongo/spring-mongo-1.8.xsd=org/springframework/data/mongodb/config/spring-mongo-1.8.xsd
http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-1.8.xsd
http\://www.springframework.org/schema/data/mongo/spring-mongo.xsd=org/springframework/data/mongodb/config/spring-mongo-1.5.xsd

View File

@@ -1,888 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://www.springframework.org/schema/data/mongo"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:repository="http://www.springframework.org/schema/data/repository"
targetNamespace="http://www.springframework.org/schema/data/mongo"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" />
<xsd:import namespace="http://www.springframework.org/schema/tool" />
<xsd:import namespace="http://www.springframework.org/schema/context" />
<xsd:import namespace="http://www.springframework.org/schema/data/repository"
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd" />
<xsd:element name="mongo" type="mongoType">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mongodb.core.MongoFactoryBean"><![CDATA[
Deprecated since 1.7 - use mongo-client instead. Defines a Mongo instance used for accessing MongoDB.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="com.mongodb.Mongo"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="mongo-client" type="mongoClientType">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mongodb.core.MongoClientFactoryBean"><![CDATA[
Defines a MongoClient instance used for accessing MongoDB.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="com.mongodb.MongoClient"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="db-factory">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a MongoDbFactory for connecting to a specific database
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the mongo definition (by default "mongoDbFactory").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The reference to a Mongo instance. If not configured a default com.mongodb.Mongo instance will be created.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="dbname" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the database to connect to. Default is 'db'.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="authentication-dbname" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Deprecated since 1.7 - Please use MongoClient internal authentication. The name of the authentication database to connect to. Default is 'db'.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="port" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The port to connect to MongoDB server. Default is 27017
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="host" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The host to connect to a MongoDB server. Default is localhost
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="username" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Deprecated since 1.7 - Please use MongoClient internal authentication. The username to use when connecting to a MongoDB server.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="password" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Deprecated since 1.7 - Please use MongoClient internal authentication. The password to use when connecting to a MongoDB server.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="uri" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The Mongo URI string.]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="write-concern">
<xsd:annotation>
<xsd:documentation>
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:attributeGroup name="mongo-repository-attributes">
<xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" default="mongoTemplate">
<xsd:annotation>
<xsd:documentation>
The reference to a MongoTemplate. Will default to 'mongoTemplate'.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="create-query-indexes" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation>
Enables creation of indexes for queries that get derived from the method name
and thus reference domain class properties. Defaults to false.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:attributeGroup>
<xsd:element name="repositories">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="repository:repositories">
<xsd:attributeGroup ref="mongo-repository-attributes"/>
<xsd:attributeGroup ref="repository:repository-attributes"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="mapping-converter">
<xsd:annotation>
<xsd:documentation><![CDATA[Defines a MongoConverter for getting rich mapping functionality.]]></xsd:documentation>
<xsd:appinfo>
<tool:exports type="org.springframework.data.mongodb.core.convert.MappingMongoConverter" />
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="custom-converters" minOccurs="0">
<xsd:annotation>
<xsd:documentation><![CDATA[
Top-level element that contains one or more custom converters to be used for mapping
domain objects to and from Mongo's DBObject]]>
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="converter" type="customConverterType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="base-package" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the MappingMongoConverter instance (by default "mappingConverter").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="base-package" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The base package in which to scan for entities annotated with @Document
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="db-factory-ref" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation>
The reference to a DbFactory.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.MongoDbFactory" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="type-mapper-ref" type="typeMapperRef" use="optional">
<xsd:annotation>
<xsd:documentation>
The reference to a MongoTypeMapper to be used by this MappingMongoConverter.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="mapping-context-ref" type="mappingContextRef" use="optional">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mapping.model.MappingContext">
The reference to a MappingContext. Will default to 'mappingContext'.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="disable-validation" use="optional">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener">
Disables JSR-303 validation on MongoDB documents before they are saved. By default it is set to false.
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="xsd:boolean xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="abbreviate-field-names" use="optional">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mongodb.core.mapping.CamelCaseAbbreviatingFieldNamingStrategy">
Enables abbreviating the field names for domain class properties to the
first character of their camel case names, e.g. fooBar -> fb. Defaults to false.
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="xsd:boolean xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="field-naming-strategy-ref" type="fieldNamingStrategyRef" use="optional">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mongodb.core.mapping.FieldNamingStrategy">
The reference to a FieldNamingStrategy.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="jmx">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a JMX Model MBeans for monitoring a MongoDB server'.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the Mongo object that determines what server to monitor. (by default "mongo").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="auditing">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="org.springframework.data.mongodb.core.mapping.event.AuditingEventListener" />
<tool:exports type="org.springframework.data.auditing.IsNewAwareAuditingHandler" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:attributeGroup ref="repository:auditing-attributes" />
<xsd:attribute name="mapping-context-ref" type="mappingContextRef" />
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="typeMapperRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoTypeMapper"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="mappingContextRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mapping.model.MappingContext"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="fieldNamingStrategyRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.mapping.FieldNamingStrategy"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="mongoTemplateRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoTemplate"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="mongoRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoFactoryBean"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="sslSocketFactoryRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="javax.net.ssl.SSLSocketFactory"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="writeConcernEnumeration">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="NONE" />
<xsd:enumeration value="NORMAL" />
<xsd:enumeration value="SAFE" />
<xsd:enumeration value="FSYNC_SAFE" />
<xsd:enumeration value="REPLICAS_SAFE" />
<xsd:enumeration value="JOURNAL_SAFE" />
<xsd:enumeration value="MAJORITY" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="readPreferenceEnumeration">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="PRIMARY" />
<xsd:enumeration value="PRIMARY_PREFERRED" />
<xsd:enumeration value="SECONDARY" />
<xsd:enumeration value="SECONDARY_PREFERRED" />
<xsd:enumeration value="NEAREST" />
</xsd:restriction>
</xsd:simpleType>
<!-- MLP
<xsd:attributeGroup name="writeConcern">
<xsd:attribute name="write-concern">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="NONE" />
<xsd:enumeration value="NORMAL" />
<xsd:enumeration value="SAFE" />
<xsd:enumeration value="FSYNC_SAFE" />
<xsd:enumeration value="REPLICA_SAFE" />
<xsd:enumeration value="JOURNAL_SAFE" />
<xsd:enumeration value="MAJORITY" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:attributeGroup>
-->
<xsd:complexType name="mongoType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Deprecated since 1.7.
]]></xsd:documentation>
</xsd:annotation>
<xsd:sequence minOccurs="0" maxOccurs="1">
<xsd:element name="options" type="optionsType">
<xsd:annotation>
<xsd:documentation><![CDATA[
The Mongo driver options
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="com.mongodb.MongoOptions"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="write-concern">
<xsd:annotation>
<xsd:documentation>
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
<!-- MLP
<xsd:attributeGroup ref="writeConcern" />
-->
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the mongo definition (by default "mongo").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="port" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The port to connect to MongoDB server. Default is 27017
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="host" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The host to connect to a MongoDB server. Default is localhost
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="replica-set" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The comma delimited list of host:port entries to use for replica set/pairs.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="optionsType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Deprecated since 1.7.
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="connections-per-host" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The number of connections allowed per host. Will block if run out. Default is 10. System property MONGO.POOLSIZE can override
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="threads-allowed-to-block-for-connection-multiplier" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The multiplier for connectionsPerHost for # of threads that can block. Default is 5.
If connectionsPerHost is 10, and threadsAllowedToBlockForConnectionMultiplier is 5,
then 50 threads can block more than that and an exception will be thrown.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-wait-time" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The max wait time of a blocking thread for a connection. Default is 12000 ms (2 minutes)
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="connect-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The connect timeout in milliseconds. 0 is default and infinite.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="socket-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The socket timeout. 0 is default and infinite.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="socket-keep-alive" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The keep alive flag, controls whether or not to have socket keep alive timeout. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="auto-connect-retry" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls whether or not on a connect, the system retries automatically. Default is false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-auto-connect-retry-time" type="xsd:long">
<xsd:annotation>
<xsd:documentation><![CDATA[
The maximum amount of time in millisecons to spend retrying to open connection to the same server. Default is 0, which means to use the default 15s if autoConnectRetry is on.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="write-number" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This specifies the number of servers to wait for on the write operation, and exception raising behavior. The 'w' option to the getlasterror command. Defaults to 0.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="write-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls timeout for write operations in milliseconds. The 'wtimeout' option to the getlasterror command. Defaults to 0 (indefinite). Greater than zero is number of milliseconds to wait.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="write-fsync" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls whether or not to fsync. The 'fsync' option to the getlasterror command. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="slave-ok" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls if the driver is allowed to read from secondaries or slaves. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ssl" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls if the driver should us an SSL connection. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ssl-socket-factory-ref" type="sslSocketFactoryRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The SSLSocketFactory to use for the SSL connection. If none is configured here, SSLSocketFactory#getDefault() will be used.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="mongoClientType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Configuration options for 'MongoClient' - @since 1.7
]]></xsd:documentation>
</xsd:annotation>
<xsd:sequence minOccurs="0" maxOccurs="1">
<xsd:element name="client-options" type="clientOptionsType">
<xsd:annotation>
<xsd:documentation><![CDATA[
The Mongo driver options
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="com.mongodb.MongoClientOptions"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the mongo definition (by default "mongoClient").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="port" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The port to connect to MongoDB server. Default is 27017
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="host" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The host to connect to a MongoDB server. Default is localhost
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="replica-set" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The comma delimited list of host:port entries to use for replica set/pairs.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="credentials" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The comma delimited list of username:password@database entries to use for authentication. Appending ?uri.authMechanism allows to specify the authentication challenge mechanism.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="clientOptionsType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Configuration options for 'MongoClientOptions' - @since 1.7
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="description" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The MongoClient description.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="min-connections-per-host" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The minimum number of connections per host.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="connections-per-host" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The number of connections allowed per host. Will block if run out. Default is 10. System property MONGO.POOLSIZE can override
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="threads-allowed-to-block-for-connection-multiplier" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The multiplier for connectionsPerHost for # of threads that can block. Default is 5.
If connectionsPerHost is 10, and threadsAllowedToBlockForConnectionMultiplier is 5,
then 50 threads can block more than that and an exception will be thrown.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-wait-time" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The max wait time of a blocking thread for a connection. Default is 12000 ms (2 minutes)
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-connection-idle-time" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The maximum idle time for a pooled connection.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-connection-life-time" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The maximum life time for a pooled connection.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="connect-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The connect timeout in milliseconds. 0 is default and infinite.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="socket-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The socket timeout. 0 is default and infinite.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="socket-keep-alive" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The keep alive flag, controls whether or not to have socket keep alive timeout. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="read-preference">
<xsd:annotation>
<xsd:documentation><![CDATA[
The read preference.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="readPreferenceEnumeration xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="write-concern">
<xsd:annotation>
<xsd:documentation><![CDATA[
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="heartbeat-frequency" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This is the frequency that the driver will attempt to determine the current state of each server in the cluster.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="min-heartbeat-frequency" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
In the event that the driver has to frequently re-check a server's availability, it will wait at least this long since the previous check to avoid wasted effort.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="heartbeat-connect-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The connect timeout for connections used for the cluster heartbeat.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="heartbeat-socket-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The socket timeout for connections used for the cluster heartbeat.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ssl" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls if the driver should us an SSL connection. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ssl-socket-factory-ref" type="sslSocketFactoryRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The SSLSocketFactory to use for the SSL connection. If none is configured here, SSLSocketFactory#getDefault() will be used.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:group name="beanElementGroup">
<xsd:choice>
<xsd:element ref="beans:bean"/>
<xsd:element ref="beans:ref"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="customConverterType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Element defining a custom converterr.
]]></xsd:documentation>
</xsd:annotation>
<xsd:group ref="beanElementGroup" minOccurs="0" maxOccurs="1"/>
<xsd:attribute name="ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
A reference to a custom converter.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:simpleType name="converterRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoConverter"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:element name="template">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a MongoDbFactory for connecting to a specific database
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the mongo definition (by default "mongoDbFactory").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="converter-ref" type="converterRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The reference to a Mongoconverter instance.
]]>
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoConverter"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="db-factory-ref" type="xsd:string"
use="optional">
<xsd:annotation>
<xsd:documentation>
The reference to a DbFactory.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to
type="org.springframework.data.mongodb.MongoDbFactory" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="write-concern">
<xsd:annotation>
<xsd:documentation>
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="gridFsTemplate">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a MongoDbFactory for connecting to a specific database
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the mongo definition (by default "mongoDbFactory").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="converter-ref" type="converterRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The reference to a Mongoconverter instance.
]]>
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoConverter"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="db-factory-ref" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation>
The reference to a DbFactory.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.MongoDbFactory" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="bucket" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The GridFs bucket string.]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -1,894 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://www.springframework.org/schema/data/mongo"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:repository="http://www.springframework.org/schema/data/repository"
targetNamespace="http://www.springframework.org/schema/data/mongo"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" />
<xsd:import namespace="http://www.springframework.org/schema/tool" />
<xsd:import namespace="http://www.springframework.org/schema/context" />
<xsd:import namespace="http://www.springframework.org/schema/data/repository"
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd" />
<xsd:element name="mongo" type="mongoType">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mongodb.core.MongoFactoryBean"><![CDATA[
Deprecated since 1.7 - use mongo-client instead. Defines a Mongo instance used for accessing MongoDB.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="com.mongodb.Mongo"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="mongo-client" type="mongoClientType">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mongodb.core.MongoClientFactoryBean"><![CDATA[
Defines a MongoClient instance used for accessing MongoDB.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="com.mongodb.MongoClient"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="db-factory">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a MongoDbFactory for connecting to a specific database
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the mongo definition (by default "mongoDbFactory").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The reference to a Mongo instance. If not configured a default com.mongodb.Mongo instance will be created.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="dbname" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the database to connect to. Default is 'db'.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="authentication-dbname" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Deprecated since 1.7 - Please use MongoClient internal authentication. The name of the authentication database to connect to. Default is 'db'.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="port" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The port to connect to MongoDB server. Default is 27017
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="host" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The host to connect to a MongoDB server. Default is localhost
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="username" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Deprecated since 1.7 - Please use MongoClient internal authentication. The username to use when connecting to a MongoDB server.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="password" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Deprecated since 1.7 - Please use MongoClient internal authentication. The password to use when connecting to a MongoDB server.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="uri" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Deprecated since 1.8 - Please use client-uri instead. The Mongo URI string.]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="client-uri" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The MongoClientURI string.]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="write-concern">
<xsd:annotation>
<xsd:documentation>
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:attributeGroup name="mongo-repository-attributes">
<xsd:attribute name="mongo-template-ref" type="mongoTemplateRef" default="mongoTemplate">
<xsd:annotation>
<xsd:documentation>
The reference to a MongoTemplate. Will default to 'mongoTemplate'.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="create-query-indexes" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation>
Enables creation of indexes for queries that get derived from the method name
and thus reference domain class properties. Defaults to false.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:attributeGroup>
<xsd:element name="repositories">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="repository:repositories">
<xsd:attributeGroup ref="mongo-repository-attributes"/>
<xsd:attributeGroup ref="repository:repository-attributes"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="mapping-converter">
<xsd:annotation>
<xsd:documentation><![CDATA[Defines a MongoConverter for getting rich mapping functionality.]]></xsd:documentation>
<xsd:appinfo>
<tool:exports type="org.springframework.data.mongodb.core.convert.MappingMongoConverter" />
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="custom-converters" minOccurs="0">
<xsd:annotation>
<xsd:documentation><![CDATA[
Top-level element that contains one or more custom converters to be used for mapping
domain objects to and from Mongo's DBObject]]>
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="converter" type="customConverterType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="base-package" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the MappingMongoConverter instance (by default "mappingConverter").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="base-package" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The base package in which to scan for entities annotated with @Document
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="db-factory-ref" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation>
The reference to a DbFactory.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.MongoDbFactory" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="type-mapper-ref" type="typeMapperRef" use="optional">
<xsd:annotation>
<xsd:documentation>
The reference to a MongoTypeMapper to be used by this MappingMongoConverter.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="mapping-context-ref" type="mappingContextRef" use="optional">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mapping.model.MappingContext">
The reference to a MappingContext. Will default to 'mappingContext'.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="disable-validation" use="optional">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener">
Disables JSR-303 validation on MongoDB documents before they are saved. By default it is set to false.
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="xsd:boolean xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="abbreviate-field-names" use="optional">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mongodb.core.mapping.CamelCaseAbbreviatingFieldNamingStrategy">
Enables abbreviating the field names for domain class properties to the
first character of their camel case names, e.g. fooBar -> fb. Defaults to false.
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="xsd:boolean xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="field-naming-strategy-ref" type="fieldNamingStrategyRef" use="optional">
<xsd:annotation>
<xsd:documentation source="org.springframework.data.mongodb.core.mapping.FieldNamingStrategy">
The reference to a FieldNamingStrategy.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="jmx">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a JMX Model MBeans for monitoring a MongoDB server'.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="mongo-ref" type="mongoRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the Mongo object that determines what server to monitor. (by default "mongo").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="auditing">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="org.springframework.data.mongodb.core.mapping.event.AuditingEventListener" />
<tool:exports type="org.springframework.data.auditing.IsNewAwareAuditingHandler" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:attributeGroup ref="repository:auditing-attributes" />
<xsd:attribute name="mapping-context-ref" type="mappingContextRef" />
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="typeMapperRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoTypeMapper"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="mappingContextRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mapping.model.MappingContext"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="fieldNamingStrategyRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.mapping.FieldNamingStrategy"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="mongoTemplateRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoTemplate"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="mongoRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoFactoryBean"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="sslSocketFactoryRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="javax.net.ssl.SSLSocketFactory"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="writeConcernEnumeration">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="NONE" />
<xsd:enumeration value="NORMAL" />
<xsd:enumeration value="SAFE" />
<xsd:enumeration value="FSYNC_SAFE" />
<xsd:enumeration value="REPLICAS_SAFE" />
<xsd:enumeration value="JOURNAL_SAFE" />
<xsd:enumeration value="MAJORITY" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="readPreferenceEnumeration">
<xsd:restriction base="xsd:token">
<xsd:enumeration value="PRIMARY" />
<xsd:enumeration value="PRIMARY_PREFERRED" />
<xsd:enumeration value="SECONDARY" />
<xsd:enumeration value="SECONDARY_PREFERRED" />
<xsd:enumeration value="NEAREST" />
</xsd:restriction>
</xsd:simpleType>
<!-- MLP
<xsd:attributeGroup name="writeConcern">
<xsd:attribute name="write-concern">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="NONE" />
<xsd:enumeration value="NORMAL" />
<xsd:enumeration value="SAFE" />
<xsd:enumeration value="FSYNC_SAFE" />
<xsd:enumeration value="REPLICA_SAFE" />
<xsd:enumeration value="JOURNAL_SAFE" />
<xsd:enumeration value="MAJORITY" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:attributeGroup>
-->
<xsd:complexType name="mongoType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Deprecated since 1.7.
]]></xsd:documentation>
</xsd:annotation>
<xsd:sequence minOccurs="0" maxOccurs="1">
<xsd:element name="options" type="optionsType">
<xsd:annotation>
<xsd:documentation><![CDATA[
The Mongo driver options
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="com.mongodb.MongoOptions"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="write-concern">
<xsd:annotation>
<xsd:documentation>
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
<!-- MLP
<xsd:attributeGroup ref="writeConcern" />
-->
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the mongo definition (by default "mongo").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="port" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The port to connect to MongoDB server. Default is 27017
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="host" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The host to connect to a MongoDB server. Default is localhost
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="replica-set" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The comma delimited list of host:port entries to use for replica set/pairs.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="optionsType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Deprecated since 1.7.
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="connections-per-host" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The number of connections allowed per host. Will block if run out. Default is 10. System property MONGO.POOLSIZE can override
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="threads-allowed-to-block-for-connection-multiplier" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The multiplier for connectionsPerHost for # of threads that can block. Default is 5.
If connectionsPerHost is 10, and threadsAllowedToBlockForConnectionMultiplier is 5,
then 50 threads can block more than that and an exception will be thrown.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-wait-time" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The max wait time of a blocking thread for a connection. Default is 12000 ms (2 minutes)
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="connect-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The connect timeout in milliseconds. 0 is default and infinite.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="socket-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The socket timeout. 0 is default and infinite.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="socket-keep-alive" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The keep alive flag, controls whether or not to have socket keep alive timeout. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="auto-connect-retry" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls whether or not on a connect, the system retries automatically. Default is false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-auto-connect-retry-time" type="xsd:long">
<xsd:annotation>
<xsd:documentation><![CDATA[
The maximum amount of time in millisecons to spend retrying to open connection to the same server. Default is 0, which means to use the default 15s if autoConnectRetry is on.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="write-number" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This specifies the number of servers to wait for on the write operation, and exception raising behavior. The 'w' option to the getlasterror command. Defaults to 0.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="write-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls timeout for write operations in milliseconds. The 'wtimeout' option to the getlasterror command. Defaults to 0 (indefinite). Greater than zero is number of milliseconds to wait.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="write-fsync" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls whether or not to fsync. The 'fsync' option to the getlasterror command. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="slave-ok" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls if the driver is allowed to read from secondaries or slaves. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ssl" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls if the driver should us an SSL connection. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ssl-socket-factory-ref" type="sslSocketFactoryRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The SSLSocketFactory to use for the SSL connection. If none is configured here, SSLSocketFactory#getDefault() will be used.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="mongoClientType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Configuration options for 'MongoClient' - @since 1.7
]]></xsd:documentation>
</xsd:annotation>
<xsd:sequence minOccurs="0" maxOccurs="1">
<xsd:element name="client-options" type="clientOptionsType">
<xsd:annotation>
<xsd:documentation><![CDATA[
The Mongo driver options
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="com.mongodb.MongoClientOptions"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the mongo definition (by default "mongoClient").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="port" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The port to connect to MongoDB server. Default is 27017
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="host" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The host to connect to a MongoDB server. Default is localhost
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="replica-set" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The comma delimited list of host:port entries to use for replica set/pairs.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="credentials" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The comma delimited list of username:password@database entries to use for authentication. Appending ?uri.authMechanism allows to specify the authentication challenge mechanism.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="clientOptionsType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Configuration options for 'MongoClientOptions' - @since 1.7
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="description" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The MongoClient description.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="min-connections-per-host" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The minimum number of connections per host.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="connections-per-host" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The number of connections allowed per host. Will block if run out. Default is 10. System property MONGO.POOLSIZE can override
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="threads-allowed-to-block-for-connection-multiplier" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The multiplier for connectionsPerHost for # of threads that can block. Default is 5.
If connectionsPerHost is 10, and threadsAllowedToBlockForConnectionMultiplier is 5,
then 50 threads can block more than that and an exception will be thrown.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-wait-time" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The max wait time of a blocking thread for a connection. Default is 12000 ms (2 minutes)
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-connection-idle-time" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The maximum idle time for a pooled connection.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="max-connection-life-time" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The maximum life time for a pooled connection.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="connect-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The connect timeout in milliseconds. 0 is default and infinite.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="socket-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The socket timeout. 0 is default and infinite.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="socket-keep-alive" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The keep alive flag, controls whether or not to have socket keep alive timeout. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="read-preference">
<xsd:annotation>
<xsd:documentation><![CDATA[
The read preference.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="readPreferenceEnumeration xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="write-concern">
<xsd:annotation>
<xsd:documentation><![CDATA[
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="heartbeat-frequency" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
This is the frequency that the driver will attempt to determine the current state of each server in the cluster.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="min-heartbeat-frequency" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
In the event that the driver has to frequently re-check a server's availability, it will wait at least this long since the previous check to avoid wasted effort.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="heartbeat-connect-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The connect timeout for connections used for the cluster heartbeat.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="heartbeat-socket-timeout" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The socket timeout for connections used for the cluster heartbeat.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ssl" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation><![CDATA[
This controls if the driver should us an SSL connection. Defaults to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ssl-socket-factory-ref" type="sslSocketFactoryRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The SSLSocketFactory to use for the SSL connection. If none is configured here, SSLSocketFactory#getDefault() will be used.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:group name="beanElementGroup">
<xsd:choice>
<xsd:element ref="beans:bean"/>
<xsd:element ref="beans:ref"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="customConverterType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Element defining a custom converterr.
]]></xsd:documentation>
</xsd:annotation>
<xsd:group ref="beanElementGroup" minOccurs="0" maxOccurs="1"/>
<xsd:attribute name="ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
A reference to a custom converter.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:simpleType name="converterRef">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoConverter"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
<xsd:element name="template">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a MongoDbFactory for connecting to a specific database
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the mongo definition (by default "mongoDbFactory").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="converter-ref" type="converterRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The reference to a Mongoconverter instance.
]]>
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoConverter"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="db-factory-ref" type="xsd:string"
use="optional">
<xsd:annotation>
<xsd:documentation>
The reference to a DbFactory.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to
type="org.springframework.data.mongodb.MongoDbFactory" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="write-concern">
<xsd:annotation>
<xsd:documentation>
The WriteConcern that will be the default value used when asking the MongoDbFactory for a DB object
</xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:union memberTypes="writeConcernEnumeration xsd:string"/>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="gridFsTemplate">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a MongoDbFactory for connecting to a specific database
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the mongo definition (by default "mongoDbFactory").]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="converter-ref" type="converterRef" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The reference to a Mongoconverter instance.
]]>
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.core.convert.MongoConverter"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="db-factory-ref" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation>
The reference to a DbFactory.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:assignable-to type="org.springframework.data.mongodb.MongoDbFactory" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="bucket" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The GridFs bucket string.]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>

Some files were not shown because too many files have changed in this diff Show More