Skip to content

Commit eb1eb96

Browse files
author
Hideki Itakura
committed
Merge branch 'master' into release/1.1.0
* master: update submodule update submodule - Replace Gson with Jackson - Refactor package - Added unit test cases which were covered by previous unit tests - Rename the one java class name to fix typo - Set 1.6 for sourceCompatibility and targetCompatibility - removed unnecessary lines test case for issue #7 (Arrays) complete rewrite update submodule update submodule update submodule update submodule
2 parents 1b1341e + a39d465 commit eb1eb96

File tree

16 files changed

+724
-1184
lines changed

16 files changed

+724
-1184
lines changed

build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
21
apply plugin: 'java'
32
apply plugin: 'maven'
43
apply plugin: 'eclipse'
54

5+
sourceCompatibility = 1.6
6+
targetCompatibility = 1.6
7+
68
repositories {
79
maven { url 'http://files.couchbase.com/maven2/' }
810
mavenCentral()
Lines changed: 5 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -1,201 +1,26 @@
11
package com.couchbase.lite.javascript;
22

3-
import com.couchbase.lite.Database;
4-
import com.couchbase.lite.Emitter;
53
import com.couchbase.lite.Mapper;
64
import com.couchbase.lite.Reducer;
75
import com.couchbase.lite.ViewCompiler;
8-
import com.couchbase.lite.util.Log;
9-
import com.fasterxml.jackson.databind.ObjectMapper;
10-
11-
import org.elasticsearch.script.javascript.support.NativeList;
12-
import org.elasticsearch.script.javascript.support.NativeMap;
13-
import org.mozilla.javascript.Context;
14-
import org.mozilla.javascript.Function;
15-
import org.mozilla.javascript.NativeArray;
16-
import org.mozilla.javascript.Scriptable;
17-
import org.mozilla.javascript.WrapFactory;
18-
19-
import java.io.IOException;
20-
import java.util.List;
21-
import java.util.Map;
226

237
public class JavaScriptViewCompiler implements ViewCompiler {
24-
25-
@Override
26-
public Mapper compileMap(String source, String language) {
8+
@Override
9+
public Mapper compileMap(String source, String language) {
2710
if (language.equals("javascript")) {
2811
return new ViewMapBlockRhino(source);
2912
}
3013
throw new IllegalArgumentException(language + " is not supported");
31-
}
14+
}
3215

33-
@Override
34-
public Reducer compileReduce(String source, String language) {
16+
@Override
17+
public Reducer compileReduce(String source, String language) {
3518
if (language.equals("javascript")) {
3619
return new ViewReduceBlockRhino(source);
3720
}
3821
throw new IllegalArgumentException(language + " is not supported");
39-
}
40-
41-
}
42-
43-
/**
44-
* Wrap Factory for Rhino Script Engine
45-
*/
46-
class CustomWrapFactory extends WrapFactory {
47-
48-
public CustomWrapFactory() {
49-
setJavaPrimitiveWrap(false); // RingoJS does that..., claims its annoying...
50-
}
51-
52-
@Override
53-
public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class staticType) {
54-
if (javaObject instanceof Map) {
55-
return new NativeMap(scope, (Map) javaObject);
56-
}
57-
else if(javaObject instanceof List) {
58-
return new NativeList(scope, (List<Object>)javaObject);
59-
}
60-
61-
return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
62-
}
63-
}
64-
65-
// REFACT: Extract superview for both the map and reduce blocks as they do pretty much the same thing
66-
67-
class ViewMapBlockRhino implements Mapper {
68-
69-
private static WrapFactory wrapFactory = new CustomWrapFactory();
70-
private Scriptable globalScope;
71-
private String src;
72-
73-
public ViewMapBlockRhino(String src) {
74-
this.src = src;
75-
Context ctx = Context.enter();
76-
try {
77-
ctx.setOptimizationLevel(-1);
78-
ctx.setWrapFactory(wrapFactory);
79-
globalScope = ctx.initStandardObjects(null, true);
80-
} finally {
81-
Context.exit();
82-
}
8322
}
84-
85-
@Override
86-
public void map(Map<String, Object> document, Emitter emitter) {
87-
Context ctx = Context.enter();
88-
try {
89-
ctx.setOptimizationLevel(-1);
90-
ctx.setWrapFactory(wrapFactory);
91-
92-
//create a place to hold results
93-
String placeHolder = "var map_results = [];";
94-
ctx.evaluateString(globalScope, placeHolder, "placeHolder", 1, null);
95-
96-
//register the emit function
97-
String emitFunction = "var emit = function(key, value) { map_results.push([key, value]); };";
98-
ctx.evaluateString(globalScope, emitFunction, "emit", 1, null);
99-
100-
//register the map function
101-
String mapSrc = "var map = " + src + ";";
102-
try {
103-
ctx.evaluateString(globalScope, mapSrc, "map", 1, null);
104-
} catch(org.mozilla.javascript.EvaluatorException e) {
105-
// Error in the JavaScript view - CouchDB swallows the error and tries the next document
106-
// REFACT: would be nice to check this in the constructor so we don't have to reparse every time
107-
// should also be much faster if we can insert the map function into this objects globals
108-
Log.e(Database.TAG, "Javascript syntax error in view:\n" + src, e);
109-
return;
110-
}
111-
112-
// Need to stringify the json tree, as the ContextWrapper is unable
113-
// to correctly convert nested json to their js representation.
114-
// More specifically, if a dictionary is included that contains an array as a value
115-
// that array will not be wrapped correctly but you'll get the plain
116-
// java.util.ArrayList instead - and then an error.
117-
ObjectMapper mapper = new ObjectMapper();
118-
String json = null;
119-
try {
120-
json = mapper.writeValueAsString(document);
121-
} catch (IOException e) {
122-
// Can thrown different subclasses of IOException- but we really do not care,
123-
// as this document was unserialized from JSON, so Jackson should be able to serialize it.
124-
Log.e(Database.TAG, "Error reserializing json from the db: " + document, e);
125-
return;
126-
}
127-
128-
String mapInvocation = "map(" + json + ");";
129-
try {
130-
ctx.evaluateString(globalScope, mapInvocation, "map invocation", 1, null);
131-
}
132-
catch (org.mozilla.javascript.RhinoException e) {
133-
// Error in the JavaScript view - CouchDB swallows the error and tries the next document
134-
Log.e(Database.TAG, "Error in javascript view:\n" + src + "\n with document:\n" + document, e);
135-
return;
136-
}
137-
138-
//now pull values out of the place holder and emit them
139-
NativeArray mapResults = (NativeArray)globalScope.get("map_results", globalScope);
140-
for(int i=0; i<mapResults.getLength(); i++) {
141-
NativeArray mapResultItem = (NativeArray)mapResults.get(i);
142-
if(mapResultItem.getLength() == 2) {
143-
Object key = mapResultItem.get(0);
144-
Object value = mapResultItem.get(1);
145-
emitter.emit(key, value);
146-
} else {
147-
Log.e(Database.TAG, String.format("Expected 2 element array with key and value. Got: %s", mapResultItem));
148-
}
149-
150-
}
151-
} finally {
152-
Context.exit();
153-
}
154-
155-
}
156-
15723
}
15824

159-
class ViewReduceBlockRhino implements Reducer {
160-
161-
private static WrapFactory wrapFactory = new CustomWrapFactory();
162-
private Scriptable globalScope;
163-
private String src;
16425

165-
public ViewReduceBlockRhino(String src) {
166-
this.src = src;
167-
Context ctx = Context.enter();
168-
try {
169-
ctx.setOptimizationLevel(-1);
170-
ctx.setWrapFactory(wrapFactory);
171-
globalScope = ctx.initStandardObjects(null, true);
172-
} finally {
173-
Context.exit();
174-
}
175-
}
176-
177-
@Override
178-
public Object reduce(List<Object> keys, List<Object> values, boolean rereduce) {
179-
Context ctx = Context.enter();
180-
try {
181-
ctx.setOptimizationLevel(-1);
182-
ctx.setWrapFactory(wrapFactory);
183-
184-
//register the reduce function
185-
String reduceSrc = "var reduce = " + src + ";";
186-
ctx.evaluateString(globalScope, reduceSrc, "reduce", 1, null);
187-
188-
//find the reduce function and execute it
189-
Function reduceFun = (Function)globalScope.get("reduce", globalScope);
190-
Object[] functionArgs = { keys, values, rereduce };
191-
Object result = reduceFun.call(ctx, globalScope, globalScope, functionArgs);
19226

193-
return result;
194-
195-
} finally {
196-
Context.exit();
197-
}
198-
199-
}
200-
201-
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.couchbase.lite.javascript;
2+
3+
import com.couchbase.lite.Emitter;
4+
import com.couchbase.lite.Mapper;
5+
import com.couchbase.lite.javascript.scopes.MapGlobalScope;
6+
import com.couchbase.lite.javascript.wrapper.CustomWrapFactory;
7+
8+
import org.mozilla.javascript.Function;
9+
import org.mozilla.javascript.Scriptable;
10+
import org.mozilla.javascript.WrapFactory;
11+
12+
import java.util.Map;
13+
14+
class ViewMapBlockRhino implements Mapper {
15+
16+
private static WrapFactory wrapFactory = new CustomWrapFactory();
17+
private Scriptable globalScope;
18+
private MapGlobalScope mapGlobalScope;
19+
private Function mapFunction;
20+
21+
public ViewMapBlockRhino(String src) {
22+
23+
org.mozilla.javascript.Context ctx = org.mozilla.javascript.Context.enter();
24+
25+
try {
26+
ctx.setOptimizationLevel(-1);
27+
ctx.setWrapFactory(wrapFactory);
28+
mapGlobalScope = new MapGlobalScope();
29+
globalScope = ctx.initStandardObjects(mapGlobalScope, true);
30+
mapFunction = ctx.compileFunction(globalScope, src, "map", 0, null);
31+
} finally {
32+
org.mozilla.javascript.Context.exit();
33+
}
34+
}
35+
36+
@Override
37+
public void map(Map<String, Object> document, Emitter emitter) {
38+
39+
mapGlobalScope.setEmitter(emitter);
40+
41+
org.mozilla.javascript.Context ctx = org.mozilla.javascript.Context.enter();
42+
try {
43+
ctx.setOptimizationLevel(-1);
44+
ctx.setWrapFactory(wrapFactory);
45+
46+
Scriptable localScope = ctx.newObject(globalScope);
47+
localScope.setPrototype(globalScope);
48+
localScope.setParentScope(null);
49+
50+
Object jsDocument = org.mozilla.javascript.Context.javaToJS(document, localScope);
51+
52+
try {
53+
mapFunction.call(ctx, localScope, null, new Object[]{jsDocument});
54+
} catch (org.mozilla.javascript.RhinoException e) {
55+
// Error in the JavaScript view - CouchDB swallows the error and tries the next document
56+
return;
57+
}
58+
} finally {
59+
org.mozilla.javascript.Context.exit();
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)