DATAMONGO-479 - Polishing.
Removed ServersideJavaScript abstraction as we still had to resort on instanceof checks and it created more ambiguities than it helped (e.g. in a script with name and code, which of the two get's executed?). We now have an ExecutableMongoScript which is code only and a NamedMongoScript, which basically is the former assigned to a name. Execution can be triggered on the former or a name. ScriptOperations.exists(…) now returns a primitive boolean to avoid null checks. JavaDoc. Original pull request: #254.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -27,8 +27,8 @@ import java.util.Set;
|
||||
|
||||
import org.bson.types.ObjectId;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.mongodb.core.script.CallableMongoScript;
|
||||
import org.springframework.data.mongodb.core.script.ServerSideJavaScript;
|
||||
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;
|
||||
@@ -41,12 +41,14 @@ 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
|
||||
*/
|
||||
public class DefaultScriptOperations implements ScriptOperations {
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -63,39 +65,39 @@ public class DefaultScriptOperations implements ScriptOperations {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.ScriptOperations#save(org.springframework.data.mongodb.core.script.MongoScript)
|
||||
* @see org.springframework.data.mongodb.core.ScriptOperations#register(org.springframework.data.mongodb.core.script.ExecutableMongoScript)
|
||||
*/
|
||||
@Override
|
||||
public CallableMongoScript register(ServerSideJavaScript script) {
|
||||
|
||||
Assert.notNull(script, "Script must not be null!");
|
||||
|
||||
CallableMongoScript callableScript = (script instanceof CallableMongoScript) ? (CallableMongoScript) script
|
||||
: new CallableMongoScript(generateScriptName(), script);
|
||||
mongoOperations.save(callableScript, SCRIPT_COLLECTION_NAME);
|
||||
return callableScript;
|
||||
public NamedMongoScript register(ExecutableMongoScript script) {
|
||||
return register(new NamedMongoScript(generateScriptName(), script));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.ScriptOperations#execute(org.springframework.data.mongodb.core.script.MongoScript, java.lang.Object[])
|
||||
* @see org.springframework.data.mongodb.core.ScriptOperations#register(org.springframework.data.mongodb.core.script.NamedMongoScript)
|
||||
*/
|
||||
@Override
|
||||
public Object execute(final ServerSideJavaScript script, final Object... args) {
|
||||
public NamedMongoScript register(NamedMongoScript script) {
|
||||
|
||||
Assert.notNull(script, "Script must not be null!");
|
||||
|
||||
if (script instanceof CallableMongoScript) {
|
||||
return call(((CallableMongoScript) script).getName(), args);
|
||||
}
|
||||
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 {
|
||||
|
||||
Assert.notNull(script.getCode(), "Script.code must not be null!");
|
||||
|
||||
return db.eval(script.getCode(), convertScriptArgs(args));
|
||||
}
|
||||
});
|
||||
@@ -114,9 +116,7 @@ public class DefaultScriptOperations implements ScriptOperations {
|
||||
|
||||
@Override
|
||||
public Object doInDB(DB db) throws MongoException, DataAccessException {
|
||||
|
||||
String evalString = scriptName + "(" + convertAndJoinScriptArgs(args) + ")";
|
||||
return db.eval(evalString);
|
||||
return db.eval(String.format("%s(%s)", scriptName, convertAndJoinScriptArgs(args)));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -126,43 +126,33 @@ public class DefaultScriptOperations implements ScriptOperations {
|
||||
* @see org.springframework.data.mongodb.core.ScriptOperations#exists(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Boolean exists(String scriptName) {
|
||||
public boolean exists(String scriptName) {
|
||||
|
||||
Assert.hasText(scriptName, "ScriptName must not be null or empty!");
|
||||
|
||||
return mongoOperations.exists(query(where("name").is(scriptName)), CallableMongoScript.class,
|
||||
SCRIPT_COLLECTION_NAME);
|
||||
return mongoOperations.exists(query(where("name").is(scriptName)), NamedMongoScript.class, SCRIPT_COLLECTION_NAME);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.ScriptOperations#scriptNames()
|
||||
* @see org.springframework.data.mongodb.core.ScriptOperations#getScriptNames()
|
||||
*/
|
||||
@Override
|
||||
public Set<String> scriptNames() {
|
||||
public Set<String> getScriptNames() {
|
||||
|
||||
List<CallableMongoScript> scripts = (mongoOperations.findAll(CallableMongoScript.class, SCRIPT_COLLECTION_NAME));
|
||||
List<NamedMongoScript> scripts = mongoOperations.findAll(NamedMongoScript.class, SCRIPT_COLLECTION_NAME);
|
||||
|
||||
if (CollectionUtils.isEmpty(scripts)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
Set<String> scriptNames = new HashSet<String>();
|
||||
for (CallableMongoScript script : scripts) {
|
||||
|
||||
for (NamedMongoScript script : scripts) {
|
||||
scriptNames.add(script.getName());
|
||||
}
|
||||
return scriptNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 String generateScriptName() {
|
||||
return SCRIPT_NAME_PREFIX + randomUUID().toString().replaceAll("-", "");
|
||||
return scriptNames;
|
||||
}
|
||||
|
||||
private Object[] convertScriptArgs(Object... args) {
|
||||
@@ -172,23 +162,27 @@ public class DefaultScriptOperations implements ScriptOperations {
|
||||
}
|
||||
|
||||
List<Object> convertedValues = new ArrayList<Object>(args.length);
|
||||
|
||||
for (Object arg : args) {
|
||||
if (arg instanceof String) {
|
||||
convertedValues.add("'" + arg + "'");
|
||||
} else {
|
||||
convertedValues.add(this.mongoOperations.getConverter().convertToMongoType(arg));
|
||||
}
|
||||
convertedValues.add(arg instanceof String ? String.format("'%s'", arg) : this.mongoOperations.getConverter()
|
||||
.convertToMongoType(arg));
|
||||
}
|
||||
|
||||
return convertedValues.toArray();
|
||||
}
|
||||
|
||||
private String convertAndJoinScriptArgs(Object... args) {
|
||||
|
||||
if (ObjectUtils.isEmpty(args)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return StringUtils.arrayToCommaDelimitedString(convertScriptArgs(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("-", "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -17,27 +17,36 @@ package org.springframework.data.mongodb.core;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.mongodb.core.script.CallableMongoScript;
|
||||
import org.springframework.data.mongodb.core.script.ServerSideJavaScript;
|
||||
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 {@literal JavaScript}
|
||||
* functions.
|
||||
* 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 {@literal script} to {@link com.mongodb.DB} so it can be called via its name.
|
||||
* 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 CallableMongoScript} with name under which the {@literal JavaScript} function can be called.
|
||||
* @return {@link NamedMongoScript} with name under which the {@code JavaScript} function can be called.
|
||||
*/
|
||||
CallableMongoScript register(ServerSideJavaScript script);
|
||||
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.
|
||||
@@ -47,7 +56,7 @@ public interface ScriptOperations {
|
||||
* @return the script evaluation result.
|
||||
* @throws org.springframework.dao.DataAccessException
|
||||
*/
|
||||
Object execute(ServerSideJavaScript script, Object... args);
|
||||
Object execute(ExecutableMongoScript script, Object... args);
|
||||
|
||||
/**
|
||||
* Call the {@literal JavaScript} by its name.
|
||||
@@ -64,13 +73,12 @@ public interface ScriptOperations {
|
||||
* @param scriptName must not be {@literal null} or empty.
|
||||
* @return false if no {@link ServerSideJavaScript} with given name exists.
|
||||
*/
|
||||
Boolean exists(String scriptName);
|
||||
boolean exists(String scriptName);
|
||||
|
||||
/**
|
||||
* Returns names of {@literal JavaScript} functions that can be called.
|
||||
*
|
||||
* @return empty {@link Set} if no scripts found.
|
||||
*/
|
||||
Set<String> scriptNames();
|
||||
|
||||
Set<String> getScriptNames();
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ 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.CallableMongoScriptToDBObjectConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToCallableMongoScriptCoverter;
|
||||
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;
|
||||
@@ -120,8 +120,8 @@ public class CustomConversions {
|
||||
toRegister.add(StringToURLConverter.INSTANCE);
|
||||
toRegister.add(DBObjectToStringConverter.INSTANCE);
|
||||
toRegister.add(TermToStringConverter.INSTANCE);
|
||||
toRegister.add(CallableMongoScriptToDBObjectConverter.INSTANCE);
|
||||
toRegister.add(DBObjectToCallableMongoScriptCoverter.INSTANCE);
|
||||
toRegister.add(NamedMongoScriptToDBObjectConverter.INSTANCE);
|
||||
toRegister.add(DBObjectToNamedMongoScriptCoverter.INSTANCE);
|
||||
|
||||
toRegister.addAll(JodaTimeConverters.getConvertersToRegister());
|
||||
toRegister.addAll(GeoConverters.getConvertersToRegister());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2014 the original author or authors.
|
||||
* Copyright 2011-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.
|
||||
@@ -28,7 +28,7 @@ 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.CallableMongoScript;
|
||||
import org.springframework.data.mongodb.core.script.NamedMongoScript;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
@@ -187,13 +187,12 @@ abstract class MongoConverters {
|
||||
* @author Christoph Strobl
|
||||
* @since 1.7
|
||||
*/
|
||||
@ReadingConverter
|
||||
public static enum DBObjectToCallableMongoScriptCoverter implements Converter<DBObject, CallableMongoScript> {
|
||||
public static enum DBObjectToNamedMongoScriptCoverter implements Converter<DBObject, NamedMongoScript> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public CallableMongoScript convert(DBObject source) {
|
||||
public NamedMongoScript convert(DBObject source) {
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
@@ -202,7 +201,7 @@ abstract class MongoConverters {
|
||||
String id = source.get("_id").toString();
|
||||
Object rawValue = source.get("value");
|
||||
|
||||
return new CallableMongoScript(id, ((Code) rawValue).getCode());
|
||||
return new NamedMongoScript(id, ((Code) rawValue).getCode());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,13 +209,12 @@ abstract class MongoConverters {
|
||||
* @author Christoph Strobl
|
||||
* @since 1.7
|
||||
*/
|
||||
@WritingConverter
|
||||
public static enum CallableMongoScriptToDBObjectConverter implements Converter<CallableMongoScript, DBObject> {
|
||||
public static enum NamedMongoScriptToDBObjectConverter implements Converter<NamedMongoScript, DBObject> {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public DBObject convert(CallableMongoScript source) {
|
||||
public DBObject convert(NamedMongoScript source) {
|
||||
|
||||
if (source == null) {
|
||||
return new BasicDBObject();
|
||||
@@ -225,9 +223,7 @@ abstract class MongoConverters {
|
||||
BasicDBObjectBuilder builder = new BasicDBObjectBuilder();
|
||||
|
||||
builder.append("_id", source.getName());
|
||||
if (source.getCode() != null) {
|
||||
builder.append("value", new Code(source.getCode()));
|
||||
}
|
||||
builder.append("value", new Code(source.getCode()));
|
||||
|
||||
return builder.get();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -18,19 +18,20 @@ package org.springframework.data.mongodb.core.script;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link ServerSideJavaScript} implementation that can be saved or directly executed.
|
||||
* 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 implements ServerSideJavaScript {
|
||||
public class ExecutableMongoScript {
|
||||
|
||||
private final String code;
|
||||
|
||||
/**
|
||||
* Creates new {@link ExecutableMongoScript}.
|
||||
*
|
||||
* @param code must not be {@literal null} or {@literal empty}.
|
||||
* @param code must not be {@literal null} or empty.
|
||||
*/
|
||||
public ExecutableMongoScript(String code) {
|
||||
|
||||
@@ -38,13 +39,12 @@ public class ExecutableMongoScript implements ServerSideJavaScript {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.script.MongoScript#getCode()
|
||||
/**
|
||||
* Returns the actual script code.
|
||||
*
|
||||
* @return will never be {@literal null} or empty.
|
||||
*/
|
||||
@Override
|
||||
public String getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -19,62 +19,68 @@ import org.springframework.data.annotation.Id;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A {@link ServerSideJavaScript} implementation that allows calling the function by its {@literal name} once it has
|
||||
* been saved to the {@link com.mongodb.DB} instance.
|
||||
* 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 CallableMongoScript implements ServerSideJavaScript {
|
||||
public class NamedMongoScript {
|
||||
|
||||
private final @Id String name;
|
||||
private final ServerSideJavaScript script;
|
||||
private final ExecutableMongoScript script;
|
||||
|
||||
/**
|
||||
* Creates new {@link CallableMongoScript} that can be saved to the {@link com.mongodb.DB} instance.
|
||||
* Creates new {@link NamedMongoScript} that can be saved to the {@link com.mongodb.DB} instance.
|
||||
*
|
||||
* @param name must not be {@literal null} or {@literal empty}.
|
||||
* @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 {@literal empty}.
|
||||
* {@literal null} or empty.
|
||||
*/
|
||||
public CallableMongoScript(String name, String rawScript) {
|
||||
public NamedMongoScript(String name, String rawScript) {
|
||||
this(name, new ExecutableMongoScript(rawScript));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link CallableMongoScript}.
|
||||
* Creates new {@link NamedMongoScript}.
|
||||
*
|
||||
* @param name must not be {@literal null} or {@literal empty}.
|
||||
* @param script can be {@literal null}.
|
||||
* @param name must not be {@literal null} or empty.
|
||||
* @param script must not be {@literal null}.
|
||||
*/
|
||||
public CallableMongoScript(String name, ServerSideJavaScript script) {
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.script.MongoScript#getCode()
|
||||
/**
|
||||
* Returns the actual script code.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
@Override
|
||||
public String getCode() {
|
||||
|
||||
if (script == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return script.getCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the {@link CallableMongoScript} script.
|
||||
* Returns the underlying {@link ExecutableMongoScript}.
|
||||
*
|
||||
* @return
|
||||
* @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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface ServerSideJavaScript {
|
||||
|
||||
/**
|
||||
* Get the {@link String} representation of the JavaScript code.
|
||||
*
|
||||
* @return {@literal null} when no code available.
|
||||
*/
|
||||
String getCode();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,26 +15,22 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core;
|
||||
|
||||
import static org.hamcrest.collection.IsEmptyCollection.*;
|
||||
import static org.hamcrest.core.Is.*;
|
||||
import static org.hamcrest.core.IsCollectionContaining.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.core.query.Query.*;
|
||||
|
||||
import org.hamcrest.core.Is;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.UncategorizedDataAccessException;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.data.mongodb.core.script.CallableMongoScript;
|
||||
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
|
||||
import org.springframework.data.mongodb.core.script.NamedMongoScript;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@@ -43,7 +39,11 @@ import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DefaultScriptOperations}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Oliver Gierke
|
||||
* @since 1.7
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
@@ -70,7 +70,7 @@ public class DefaultScriptOperationsTests {
|
||||
static final String SCRIPT_NAME = "echo";
|
||||
static final String JS_FUNCTION = "function(x) { return x; }";
|
||||
static final ExecutableMongoScript EXECUTABLE_SCRIPT = new ExecutableMongoScript(JS_FUNCTION);
|
||||
static final CallableMongoScript CALLABLE_SCRIPT = new CallableMongoScript(SCRIPT_NAME, JS_FUNCTION);
|
||||
static final NamedMongoScript CALLABLE_SCRIPT = new NamedMongoScript(SCRIPT_NAME, JS_FUNCTION);
|
||||
|
||||
@Autowired MongoTemplate template;
|
||||
DefaultScriptOperations scriptOps;
|
||||
@@ -87,18 +87,7 @@ public class DefaultScriptOperationsTests {
|
||||
*/
|
||||
@Test
|
||||
public void executeShouldDirectlyRunExecutableMongoScript() {
|
||||
|
||||
Object result = scriptOps.execute(EXECUTABLE_SCRIPT, 10);
|
||||
|
||||
assertThat(result, Is.<Object> is(10D));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-479
|
||||
*/
|
||||
@Test(expected = DataAccessException.class)
|
||||
public void executeThowsDataAccessExceptionWhenRunningCallableScriptThatHasNotBeenSavedBefore() {
|
||||
scriptOps.execute(CALLABLE_SCRIPT, 10);
|
||||
assertThat(scriptOps.execute(EXECUTABLE_SCRIPT, 10), is((Object) 10D));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,7 +110,7 @@ public class DefaultScriptOperationsTests {
|
||||
@Test
|
||||
public void saveShouldStoreExecutableScriptCorrectly() {
|
||||
|
||||
CallableMongoScript script = scriptOps.register(EXECUTABLE_SCRIPT);
|
||||
NamedMongoScript script = scriptOps.register(EXECUTABLE_SCRIPT);
|
||||
|
||||
Query query = query(where("_id").is(script.getName()));
|
||||
assumeThat(template.exists(query, JAVASCRIPT_COLLECTION_NAME), is(true));
|
||||
@@ -138,9 +127,9 @@ public class DefaultScriptOperationsTests {
|
||||
Query query = query(where("_id").is(SCRIPT_NAME));
|
||||
assumeThat(template.exists(query, JAVASCRIPT_COLLECTION_NAME), is(true));
|
||||
|
||||
Object result = scriptOps.execute(CALLABLE_SCRIPT, 10);
|
||||
Object result = scriptOps.call(CALLABLE_SCRIPT.getName(), 10);
|
||||
|
||||
assertThat(result, Is.<Object> is(10D));
|
||||
assertThat(result, is((Object) 10D));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,7 +161,7 @@ public class DefaultScriptOperationsTests {
|
||||
|
||||
Object result = scriptOps.call(SCRIPT_NAME, 10);
|
||||
|
||||
assertThat(result, Is.<Object> is(10D));
|
||||
assertThat(result, is((Object) 10D));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,7 +180,7 @@ public class DefaultScriptOperationsTests {
|
||||
|
||||
scriptOps.register(CALLABLE_SCRIPT);
|
||||
|
||||
assertThat(scriptOps.scriptNames(), hasItems("echo"));
|
||||
assertThat(scriptOps.getScriptNames(), hasItems("echo"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,6 +188,6 @@ public class DefaultScriptOperationsTests {
|
||||
*/
|
||||
@Test
|
||||
public void scriptNamesShouldReturnEmptySetWhenNoScriptRegistered() {
|
||||
assertThat(scriptOps.scriptNames(), empty());
|
||||
assertThat(scriptOps.getScriptNames(), is(empty()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -26,30 +26,41 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.mongodb.core.script.CallableMongoScript;
|
||||
import org.springframework.data.mongodb.core.script.ExecutableMongoScript;
|
||||
import org.springframework.data.mongodb.core.script.NamedMongoScript;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DefaultScriptOperations}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Oliver Gierke
|
||||
* @since 1.7
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DefaultScriptOperationsUnitTests {
|
||||
|
||||
DefaultScriptOperations scriptOps;
|
||||
@Mock MongoOperations mongoOperationsMock;
|
||||
@Mock MongoOperations mongoOperations;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.scriptOps = new DefaultScriptOperations(mongoOperationsMock);
|
||||
this.scriptOps = new DefaultScriptOperations(mongoOperations);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-479
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void saveShouldThrowExceptionWhenCalledWithNullValue() {
|
||||
scriptOps.register(null);
|
||||
public void rejectsNullExecutableMongoScript() {
|
||||
scriptOps.register((ExecutableMongoScript) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-479
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullNamedMongoScript() {
|
||||
scriptOps.register((NamedMongoScript) null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,9 +69,9 @@ public class DefaultScriptOperationsUnitTests {
|
||||
@Test
|
||||
public void saveShouldUseCorrectCollectionName() {
|
||||
|
||||
scriptOps.register(new CallableMongoScript("foo", "function..."));
|
||||
scriptOps.register(new NamedMongoScript("foo", "function..."));
|
||||
|
||||
verify(mongoOperationsMock, times(1)).save(any(CallableMongoScript.class), eq("system.js"));
|
||||
verify(mongoOperations, times(1)).save(any(NamedMongoScript.class), eq("system.js"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,9 +82,9 @@ public class DefaultScriptOperationsUnitTests {
|
||||
|
||||
scriptOps.register(new ExecutableMongoScript("function..."));
|
||||
|
||||
ArgumentCaptor<CallableMongoScript> captor = ArgumentCaptor.forClass(CallableMongoScript.class);
|
||||
ArgumentCaptor<NamedMongoScript> captor = ArgumentCaptor.forClass(NamedMongoScript.class);
|
||||
|
||||
verify(mongoOperationsMock, times(1)).save(captor.capture(), eq("system.js"));
|
||||
verify(mongoOperations, times(1)).save(captor.capture(), eq("system.js"));
|
||||
Assert.assertThat(captor.getValue().getName(), notNullValue());
|
||||
}
|
||||
|
||||
@@ -116,5 +127,4 @@ public class DefaultScriptOperationsUnitTests {
|
||||
public void callShouldThrowExceptionWhenScriptNameIsEmpty() {
|
||||
scriptOps.call("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,53 +15,55 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import static org.hamcrest.core.IsEqual.*;
|
||||
import static org.hamcrest.core.IsInstanceOf.*;
|
||||
import static org.hamcrest.core.IsNull.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.bson.types.Code;
|
||||
import org.hamcrest.core.IsEqual;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import org.junit.runners.Suite.SuiteClasses;
|
||||
import org.springframework.data.mongodb.core.convert.CallableMongoScriptConvertsUnitTests.CallableMongoScriptToDboConverterUnitTests;
|
||||
import org.springframework.data.mongodb.core.convert.CallableMongoScriptConvertsUnitTests.DboToCallableMongoScriptConverterUnitTests;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.CallableMongoScriptToDBObjectConverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToCallableMongoScriptCoverter;
|
||||
import org.springframework.data.mongodb.core.script.CallableMongoScript;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToNamedMongoScriptCoverter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoConverters.NamedMongoScriptToDBObjectConverter;
|
||||
import org.springframework.data.mongodb.core.convert.NamedMongoScriptConvertsUnitTests.DboToNamedMongoScriptConverterUnitTests;
|
||||
import org.springframework.data.mongodb.core.convert.NamedMongoScriptConvertsUnitTests.NamedMongoScriptToDboConverterUnitTests;
|
||||
import org.springframework.data.mongodb.core.script.NamedMongoScript;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.BasicDBObjectBuilder;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link Converter} implementations for {@link NamedMongoScript}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Oliver Gierke
|
||||
* @since 1.7
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
@SuiteClasses({ CallableMongoScriptToDboConverterUnitTests.class, DboToCallableMongoScriptConverterUnitTests.class })
|
||||
public class CallableMongoScriptConvertsUnitTests {
|
||||
@SuiteClasses({ NamedMongoScriptToDboConverterUnitTests.class, DboToNamedMongoScriptConverterUnitTests.class })
|
||||
public class NamedMongoScriptConvertsUnitTests {
|
||||
|
||||
static final String FUNCTION_NAME = "echo";
|
||||
static final String JS_FUNCTION = "function(x) { return x; }";
|
||||
static final CallableMongoScript ECHO_SCRIPT = new CallableMongoScript(FUNCTION_NAME, JS_FUNCTION);
|
||||
static final NamedMongoScript ECHO_SCRIPT = new NamedMongoScript(FUNCTION_NAME, JS_FUNCTION);
|
||||
static final DBObject FUNCTION = new BasicDBObjectBuilder().add("_id", FUNCTION_NAME)
|
||||
.add("value", new Code(JS_FUNCTION)).get();
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public static class CallableMongoScriptToDboConverterUnitTests {
|
||||
public static class NamedMongoScriptToDboConverterUnitTests {
|
||||
|
||||
CallableMongoScriptToDBObjectConverter converter = CallableMongoScriptToDBObjectConverter.INSTANCE;
|
||||
NamedMongoScriptToDBObjectConverter converter = NamedMongoScriptToDBObjectConverter.INSTANCE;
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-479
|
||||
*/
|
||||
@Test
|
||||
public void convertShouldReturnEmptyDboWhenScriptIsNull() {
|
||||
assertThat(converter.convert(null), IsEqual.<DBObject> equalTo(new BasicDBObject()));
|
||||
assertThat(converter.convert(null), is((DBObject) new BasicDBObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,8 +75,8 @@ public class CallableMongoScriptConvertsUnitTests {
|
||||
DBObject dbo = converter.convert(ECHO_SCRIPT);
|
||||
|
||||
Object id = dbo.get("_id");
|
||||
assertThat(id, instanceOf(String.class));
|
||||
assertThat(id, IsEqual.<Object> equalTo(FUNCTION_NAME));
|
||||
assertThat(id, is(instanceOf(String.class)));
|
||||
assertThat(id, is((Object) FUNCTION_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,24 +88,24 @@ public class CallableMongoScriptConvertsUnitTests {
|
||||
DBObject dbo = converter.convert(ECHO_SCRIPT);
|
||||
|
||||
Object code = dbo.get("value");
|
||||
assertThat(code, instanceOf(Code.class));
|
||||
assertThat(code, equalTo((Object) new Code(JS_FUNCTION)));
|
||||
assertThat(code, is(instanceOf(Code.class)));
|
||||
assertThat(code, is((Object) new Code(JS_FUNCTION)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public static class DboToCallableMongoScriptConverterUnitTests {
|
||||
public static class DboToNamedMongoScriptConverterUnitTests {
|
||||
|
||||
DBObjectToCallableMongoScriptCoverter converter = DBObjectToCallableMongoScriptCoverter.INSTANCE;
|
||||
DBObjectToNamedMongoScriptCoverter converter = DBObjectToNamedMongoScriptCoverter.INSTANCE;
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-479
|
||||
*/
|
||||
@Test
|
||||
public void convertShouldReturnNullIfSourceIsNull() {
|
||||
assertThat(converter.convert(null), nullValue());
|
||||
assertThat(converter.convert(null), is(nullValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,9 +114,9 @@ public class CallableMongoScriptConvertsUnitTests {
|
||||
@Test
|
||||
public void convertShouldConvertIdCorreclty() {
|
||||
|
||||
CallableMongoScript script = converter.convert(FUNCTION);
|
||||
NamedMongoScript script = converter.convert(FUNCTION);
|
||||
|
||||
assertThat(script.getName(), equalTo(FUNCTION_NAME));
|
||||
assertThat(script.getName(), is(FUNCTION_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,10 +125,10 @@ public class CallableMongoScriptConvertsUnitTests {
|
||||
@Test
|
||||
public void convertShouldConvertScriptValueCorreclty() {
|
||||
|
||||
CallableMongoScript script = converter.convert(FUNCTION);
|
||||
NamedMongoScript script = converter.convert(FUNCTION);
|
||||
|
||||
assertThat(script.getCode(), notNullValue());
|
||||
assertThat(script.getCode(), equalTo(JS_FUNCTION));
|
||||
assertThat(script.getCode(), is(notNullValue()));
|
||||
assertThat(script.getCode(), is(JS_FUNCTION));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
* 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.
|
||||
@@ -15,22 +15,26 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.script;
|
||||
|
||||
import static org.hamcrest.core.IsEqual.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link NamedMongoScript}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @author Oliver Gierke
|
||||
* @since 1.7
|
||||
*/
|
||||
public class CallableMongoScriptUnitTests {
|
||||
public class NamedMongoScriptUnitTests {
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-479
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowExceptionWhenScriptNameIsNull() {
|
||||
new CallableMongoScript(null, "return 1;");
|
||||
new NamedMongoScript(null, "return 1;");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,7 +42,7 @@ public class CallableMongoScriptUnitTests {
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowExceptionWhenScriptNameIsEmptyString() {
|
||||
new CallableMongoScript("", "return 1");
|
||||
new NamedMongoScript("", "return 1");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +50,7 @@ public class CallableMongoScriptUnitTests {
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowExceptionWhenRawScriptIsEmptyString() {
|
||||
new CallableMongoScript("foo", "");
|
||||
new NamedMongoScript("foo", "");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,9 +61,6 @@ public class CallableMongoScriptUnitTests {
|
||||
|
||||
String jsFunction = "function(x) { return x; }";
|
||||
|
||||
CallableMongoScript script = new CallableMongoScript("echo", jsFunction);
|
||||
|
||||
assertThat(script.getCode(), equalTo(jsFunction));
|
||||
assertThat(new NamedMongoScript("echo", jsFunction).getCode(), is(jsFunction));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user