├── README.md
├── .gitignore
├── circle.yml
├── java
├── src
│ └── org
│ │ └── nutz
│ │ └── mongo
│ │ ├── interceptor
│ │ ├── MongoInterceptor.java
│ │ ├── ZOperationExecutor.java
│ │ ├── impl
│ │ │ └── LogMongoInterceptor.java
│ │ └── MongoInterceptorChain.java
│ │ ├── adaptor
│ │ ├── ZMoPojoAdaptor.java
│ │ ├── ZMoSimpleAdaptor.java
│ │ ├── ZMoEnumAdaptor.java
│ │ ├── ZMoSmartAdaptor.java
│ │ ├── ZMoMapAdaptor.java
│ │ ├── ZMoIdAdaptor.java
│ │ ├── ZMoDBObjectAdaptor.java
│ │ ├── ZMoAs.java
│ │ ├── ZMoCollectionAdaptor.java
│ │ └── ZMoArrayAdaptor.java
│ │ ├── annotation
│ │ ├── MoIgnore.java
│ │ ├── MoEnum.java
│ │ └── MoField.java
│ │ ├── fieldfilter
│ │ ├── ZMoRegexFF.java
│ │ ├── ZMoSimpleFF.java
│ │ └── ZMoFF.java
│ │ ├── entity
│ │ ├── ZMoGeneralMapField.java
│ │ ├── ZMoEntityHolder.java
│ │ ├── ZMoGeneralMapEntity.java
│ │ ├── ZMoField.java
│ │ ├── ZMoEntity.java
│ │ └── ZMoEntityMaker.java
│ │ ├── ZMongoDB2.java
│ │ ├── ZMoAdaptor.java
│ │ ├── mr
│ │ ├── ZMoMapReduce.java
│ │ └── ZMoMapReduceManager.java
│ │ ├── ZMoDB.java
│ │ ├── ZMongo.java
│ │ ├── ZMo.java
│ │ ├── ZMoDoc.java
│ │ └── ZMoCo.java
├── test
│ └── org
│ │ └── nutz
│ │ └── mongo
│ │ ├── AllZMoTest.java
│ │ ├── pojo
│ │ ├── PetType.java
│ │ ├── PetColor.java
│ │ ├── Pet2.java
│ │ ├── Human.java
│ │ └── Pet.java
│ │ ├── ZMoBaseTest.java
│ │ ├── ZMoDocTest.java
│ │ └── ZMoPetTest.java
└── build
│ └── build.xml
├── mvn_settings.py
├── .travis.yml
├── pom.xml
└── mvn_settings.xml
/README.md:
--------------------------------------------------------------------------------
1 | move to https://github.com/nutzam/nutzmore/tree/master/nutz-plugins-mongodb
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /bin
2 | .classpath
3 | .project
4 | .settings
5 | *.DS_Store
6 | /target
7 | .idea
8 | *.iml
9 |
--------------------------------------------------------------------------------
/circle.yml:
--------------------------------------------------------------------------------
1 | machine:
2 | timezone: Asia/Shanghai
3 | java:
4 | version: oraclejdk8
5 |
6 | general:
7 | branches:
8 | only:
9 | - master
10 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/interceptor/MongoInterceptor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.interceptor;
2 |
3 | public interface MongoInterceptor {
4 |
5 | void filter(MongoInterceptorChain> chain);
6 | }
7 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/adaptor/ZMoPojoAdaptor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.adaptor;
2 |
3 | public class ZMoPojoAdaptor extends ZMoMapAdaptor {
4 |
5 | ZMoPojoAdaptor() {
6 | super();
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/java/test/org/nutz/mongo/AllZMoTest.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo;
2 |
3 | import org.junit.runner.RunWith;
4 | import org.junit.runners.Suite;
5 |
6 | @RunWith(Suite.class)
7 | @Suite.SuiteClasses({ZMoDocTest.class, ZMoPetTest.class})
8 | public class AllZMoTest {}
9 |
--------------------------------------------------------------------------------
/java/test/org/nutz/mongo/pojo/PetType.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.pojo;
2 |
3 | public enum PetType {
4 |
5 | // 0
6 | DOG,
7 |
8 | // 1
9 | CAT,
10 |
11 | // 2
12 | CROCDILE,
13 |
14 | // 3
15 | PYTHON,
16 |
17 | // 4
18 | HAMSTER
19 | }
20 |
--------------------------------------------------------------------------------
/java/test/org/nutz/mongo/pojo/PetColor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.pojo;
2 |
3 | public enum PetColor {
4 |
5 | // 0
6 | RED,
7 |
8 | // 1
9 | BLUE,
10 |
11 | // 2
12 | GREEN,
13 |
14 | // 3
15 | GRAY,
16 |
17 | // 4
18 | WHITE,
19 |
20 | // 5
21 | BLACK,
22 |
23 | // 6
24 | OTHER
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/mvn_settings.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import sys
3 | import os
4 | import os.path
5 | import xml.dom.minidom
6 | import subprocess
7 |
8 | if "1.8.0" in subprocess.check_output("java -Xmx32m -version", shell=1, stderr=subprocess.STDOUT) :
9 | subprocess.check_call("mvn -Dmaven.test.skip=true clean source:jar deploy --settings mvn_settings.xml", shell=1, stderr=subprocess.STDOUT)
10 | else :
11 | print "not java 8"
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/annotation/MoIgnore.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.annotation;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 | import java.lang.annotation.Target;
8 |
9 | /**
10 | * 如果声明了这个属性的字段,不被当做映射实体
11 | *
12 | * @author zozoh(zozohtnt@gmail.com)
13 | */
14 | @Retention(RetentionPolicy.RUNTIME)
15 | @Target({ElementType.FIELD, ElementType.METHOD})
16 | @Documented
17 | public @interface MoIgnore {}
18 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/fieldfilter/ZMoRegexFF.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.fieldfilter;
2 |
3 | import java.util.regex.Pattern;
4 |
5 | /**
6 | * 根据给定的正则表达式,来判断Java字段或者Mongo字段是否忽略该字段
7 | *
8 | * @author zozoh(zozohtnt@gmail.com)
9 | */
10 | public class ZMoRegexFF extends ZMoFF {
11 |
12 | private Pattern regex;
13 |
14 | public ZMoRegexFF(String regex) {
15 | super();
16 | this.regex = Pattern.compile(regex);
17 | }
18 |
19 | @Override
20 | public boolean match(String fld) {
21 | return regex.matcher(fld).find();
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/annotation/MoEnum.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.annotation;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 | import java.lang.annotation.Target;
8 |
9 | /**
10 | * 对枚举类型字段的补充说明
11 | *
12 | * 指明这个字段映射的时候,是要转换成数字还是字符串
13 | *
14 | * @author zozoh(zozohtnt@gmail.com)
15 | */
16 | @Retention(RetentionPolicy.RUNTIME)
17 | @Target({ElementType.FIELD, ElementType.METHOD})
18 | @Documented
19 | public @interface MoEnum {
20 |
21 | boolean str() default true;
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/entity/ZMoGeneralMapField.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.entity;
2 |
3 | import org.nutz.mongo.ZMoAdaptor;
4 | import org.nutz.mongo.adaptor.ZMoAs;
5 |
6 | public class ZMoGeneralMapField extends ZMoField {
7 |
8 | @Override
9 | public boolean isEnumStr() {
10 | return true;
11 | }
12 |
13 | @Override
14 | public void setEnumStr(boolean isEnumString) {}
15 |
16 | @Override
17 | public ZMoField clone() {
18 | return new ZMoGeneralMapField();
19 | }
20 |
21 | @Override
22 | public ZMoAdaptor getAdaptor() {
23 | return ZMoAs.smart();
24 | }
25 |
26 | @Override
27 | public void setAdaptor(ZMoAdaptor adaptor) {}
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/annotation/MoField.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.annotation;
2 |
3 | import java.lang.annotation.Documented;
4 | import java.lang.annotation.ElementType;
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 | import java.lang.annotation.Target;
8 |
9 | /**
10 | * MongoDB 的字段映射关系
11 | *
12 | * @author zozoh(zozohtnt@gmail.com)
13 | */
14 | @Retention(RetentionPolicy.RUNTIME)
15 | @Target({ElementType.FIELD, ElementType.METHOD})
16 | @Documented
17 | public @interface MoField {
18 |
19 | /**
20 | * 空字符串,表示采用 Java 字段原名
21 | */
22 | String value() default "";
23 |
24 | /**
25 | * 特殊声明一下当前字段的实现类,默认为 Object.class 表示 ZMo 自行决定
26 | */
27 | Class> type() default Object.class;
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/fieldfilter/ZMoSimpleFF.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.fieldfilter;
2 |
3 | import java.util.List;
4 |
5 | import org.nutz.lang.Lang;
6 |
7 | /**
8 | * 根据给定的 java 字段名字,来判断是否忽略该字段
9 | *
10 | * @author zozoh(zozohtnt@gmail.com)
11 | */
12 | public class ZMoSimpleFF extends ZMoFF {
13 |
14 | private String[] names;
15 |
16 | /**
17 | * @param names
18 | * 给定一个字段名称列表(大小写敏感)
19 | */
20 | public ZMoSimpleFF(String... names) {
21 | super();
22 | this.names = names;
23 | }
24 |
25 | public ZMoSimpleFF(List names) {
26 | this.names = names.toArray(new String[names.size()]);
27 | }
28 |
29 | @Override
30 | public boolean match(String fld) {
31 | return Lang.contains(names, fld);
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/adaptor/ZMoSimpleAdaptor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.adaptor;
2 |
3 | import org.nutz.castor.Castors;
4 | import org.nutz.lang.Mirror;
5 | import org.nutz.mongo.ZMoAdaptor;
6 | import org.nutz.mongo.entity.ZMoField;
7 |
8 | public class ZMoSimpleAdaptor implements ZMoAdaptor {
9 |
10 | ZMoSimpleAdaptor() {}
11 |
12 | @Override
13 | public Object toJava(ZMoField fld, Object obj) {
14 | if (null == fld || obj == null)
15 | return obj;
16 | Mirror> mirror = fld.getMirror();
17 | if (null != mirror && (mirror.isArray() || mirror.isCollection())) {
18 | return Castors.me().castTo(obj, fld.getEleType());
19 | }
20 | return Castors.me().castTo(obj, fld.getType());
21 | }
22 |
23 | @Override
24 | public Object toMongo(ZMoField fld, Object obj) {
25 | return obj;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/ZMongoDB2.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo;
2 |
3 | import org.nutz.log.Log;
4 | import org.nutz.log.Logs;
5 |
6 | import com.mongodb.CommandResult;
7 | import com.mongodb.DB;
8 | import com.mongodb.DBEncoder;
9 | import com.mongodb.DBObject;
10 | import com.mongodb.Mongo;
11 | import com.mongodb.ReadPreference;
12 |
13 | public class ZMongoDB2 extends DB {
14 |
15 | private static final Log log = Logs.get();
16 |
17 | public ZMongoDB2(Mongo mongo, String name) {
18 | super(mongo, name);
19 | }
20 |
21 | @Override
22 | public CommandResult command(DBObject command,
23 | ReadPreference readPreference,
24 | DBEncoder encoder) {
25 | if (log.isDebugEnabled())
26 | log.debug("cmd= " + command.toString());
27 | return super.command(command, readPreference, encoder);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/java/test/org/nutz/mongo/ZMoBaseTest.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import org.junit.After;
6 | import org.junit.Before;
7 |
8 | public abstract class ZMoBaseTest {
9 |
10 | private static final String DB_NAME = "nutzmongo";
11 |
12 | protected static final ZMo mo = ZMo.me();
13 |
14 | protected ZMoDB db;
15 |
16 | @Before
17 | public void before() {
18 | db = ZMongo.me("localhost").db(DB_NAME);
19 | prepare();
20 | }
21 |
22 | @SuppressWarnings("deprecation")
23 | @After
24 | public void after() {
25 | db.cleanCursors(true);
26 | }
27 |
28 | protected void prepare() {};
29 |
30 | protected void assertArray(T[] expects, T[] objs) {
31 | assertEquals(expects.length, objs.length);
32 | for (int i = 0; i < objs.length; i++) {
33 | assertEquals(expects[i], objs[i]);
34 | }
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: java
3 | script: mvn -Dmaven.test.skip=true package source:jar
4 | jdk:
5 | - oraclejdk8
6 | # whitelist
7 | branches:
8 | only:
9 | - master
10 | notifications:
11 | email: false
12 | before_install:
13 | - export TZ=Asia/Shanghai
14 | env:
15 | global:
16 | # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
17 | # via the "travis encrypt" command using the project repo's public key
18 | - secure: "E1z+6z9M4iTdAXZ2a1rYSrxfIOq6PkdXEMutAbIn/bp1e/Qvb5IVoAS0heo7SPwcIlHlN8mDiOtKdzbcu9q8VaftfHwFjff6AoKyuWtfDqE1ecTfflebWwzmtXKJmT5uxBPvu442dS4sIc2zx3zjvnxMsSmvrdSwbMxwdbAKvDc="
19 | - SONATYPE_USERNAME=wendal
20 | - secure : "BaXmGpodQiuU23YgtUThWCHf7Vig2Gv3UfpBjo3FATgn1LRF3i2IOgY5sCSi+XJYqx+05fVNdwVYccxS/9UfhPNSqQuslIwgmg0y9f26DYaX2gaW+jk8padhZRkeBrY3fO+g9nQuu+Epgqi0ITru6+IjH932O0m1JR7iJu2RNhs="
21 | after_success:
22 | - bash <(curl -s https://codecov.io/bash)
23 | - python mvn_settings.py
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/ZMoAdaptor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo;
2 |
3 | import org.nutz.mongo.entity.ZMoField;
4 |
5 | /**
6 | * 将 Mongo 驱动的字段值与普通 Java 字段值互相转换的适配器
7 | *
8 | * 每个适配器的实例将只能处理特定范围的数据类型,比如 ZMoMapAdaptor 只能处理 Map
9 | *
10 | * 注意:
11 | *
12 | * - 所有的适配器都不会处理 null 这个情况
13 | *
14 | *
15 | * @author zozoh(zozohtnt@gmail.com)
16 | */
17 | public interface ZMoAdaptor {
18 |
19 | /**
20 | * 将任何 Mongo 驱动的数据类型变成 Java 的值
21 | *
22 | * @param fld
23 | * 要映射的字段
24 | * @param obj
25 | * 字段值
26 | *
27 | * @return 适合普通 Java 程序的字段值
28 | */
29 | Object toJava(ZMoField fld, Object obj);
30 |
31 | /**
32 | * 将任何 Java 字段值变成 Mongo 驱动能接受的值
33 | *
34 | * @param fld
35 | * 要映射的字段
36 | * @param obj
37 | * 字段值
38 | *
39 | * @return Mongo 驱动能接受的值
40 | */
41 | Object toMongo(ZMoField fld, Object obj);
42 | }
43 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/adaptor/ZMoEnumAdaptor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.adaptor;
2 |
3 | import org.nutz.castor.Castors;
4 | import org.nutz.lang.Lang;
5 | import org.nutz.mongo.ZMoAdaptor;
6 | import org.nutz.mongo.entity.ZMoField;
7 |
8 | public class ZMoEnumAdaptor implements ZMoAdaptor {
9 |
10 | ZMoEnumAdaptor() {}
11 |
12 | @Override
13 | public Object toJava(ZMoField fld, Object obj) {
14 | if (null == fld)
15 | return obj;
16 | return Castors.me().castTo(obj, fld.getType());
17 | }
18 |
19 | @SuppressWarnings("rawtypes")
20 | @Override
21 | public Object toMongo(ZMoField fld, Object obj) {
22 | if (obj.getClass().isEnum()) {
23 | if (null != fld && fld.isEnumStr()) {
24 | return ((Enum) obj).name();
25 | }
26 | return Castors.me().castTo(obj, Integer.class);
27 | }
28 | throw Lang.makeThrow("obj<%s> should be ENUM", obj.getClass());
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/java/test/org/nutz/mongo/pojo/Pet2.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.pojo;
2 |
3 | import java.util.List;
4 |
5 | import org.nutz.mongo.annotation.MoField;
6 |
7 | public class Pet2 {
8 |
9 | private String _id;
10 |
11 | @MoField("nm")
12 | private String name;
13 |
14 | private int age;
15 |
16 | private List pets;
17 |
18 | public String get_id() {
19 | return _id;
20 | }
21 |
22 | public void set_id(String _id) {
23 | this._id = _id;
24 | }
25 |
26 | public String getName() {
27 | return name;
28 | }
29 |
30 | public void setName(String name) {
31 | this.name = name;
32 | }
33 |
34 | public int getAge() {
35 | return age;
36 | }
37 |
38 | public void setAge(int age) {
39 | this.age = age;
40 | }
41 |
42 | public List getPets() {
43 | return pets;
44 | }
45 |
46 | public void setPets(List pets) {
47 | this.pets = pets;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/java/test/org/nutz/mongo/pojo/Human.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.pojo;
2 |
3 | import org.nutz.lang.random.R;
4 | import org.nutz.mongo.annotation.MoField;
5 |
6 | public class Human {
7 |
8 | public static Human NEW(String name) {
9 | return new Human().setName(name);
10 | }
11 |
12 | public static Human[] ARR(String... names) {
13 | Human[] people = new Human[names.length];
14 | for (int i = 0; i < names.length; i++) {
15 | people[i] = NEW(names[i]).setAge(R.random(2, 20));
16 | }
17 | return people;
18 | }
19 |
20 | public static final String CNAME = "human";
21 |
22 | @MoField("nm")
23 | private String name;
24 |
25 | private int age;
26 |
27 | public String getName() {
28 | return name;
29 | }
30 |
31 | public Human setName(String name) {
32 | this.name = name;
33 | return this;
34 | }
35 |
36 | public int getAge() {
37 | return age;
38 | }
39 |
40 | public Human setAge(int age) {
41 | this.age = age;
42 | return this;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/entity/ZMoEntityHolder.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.entity;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.Set;
6 |
7 | import org.nutz.lang.Strings;
8 |
9 | /**
10 | * 缓存 ZMoEntity 对象
11 | *
12 | * @author zozoh(zozohtnt@gmail.com)
13 | */
14 | public class ZMoEntityHolder {
15 |
16 | private Map ens;
17 |
18 | public ZMoEntityHolder() {
19 | ens = new HashMap();
20 | }
21 |
22 | public ZMoEntity get(String key) {
23 | return ens.get(key);
24 | }
25 |
26 | public void add(String key, ZMoEntity en) {
27 | if (null != en && !Strings.isBlank(key)) {
28 | en.setKey(key);
29 | ens.put(key, en);
30 | }
31 | }
32 |
33 | public Set keys() {
34 | return ens.keySet();
35 | }
36 |
37 | public int count() {
38 | return ens.size();
39 | }
40 |
41 | public ZMoEntity remove(String key) {
42 | return ens.remove(key);
43 | }
44 |
45 | public void clear() {
46 | ens.clear();
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/mr/ZMoMapReduce.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.mr;
2 |
3 | import org.nutz.mongo.ZMoDoc;
4 |
5 | public class ZMoMapReduce {
6 |
7 | private String key;
8 |
9 | private String init;
10 |
11 | private ZMoDoc _init_obj;
12 |
13 | private String reduceFunc;
14 |
15 | public String getKey() {
16 | return key;
17 | }
18 |
19 | public void setKey(String key) {
20 | this.key = key;
21 | }
22 |
23 | public String getInit() {
24 | return init;
25 | }
26 |
27 | public ZMoDoc getInitObj() {
28 | if (null == _init_obj) {
29 | synchronized (this) {
30 | if (null == _init_obj) {
31 | _init_obj = ZMoDoc.NEW(init);
32 | }
33 | }
34 | }
35 | return _init_obj;
36 | }
37 |
38 | public void setInit(String initObj) {
39 | this.init = initObj;
40 | }
41 |
42 | public String getReduce() {
43 | return reduceFunc;
44 | }
45 |
46 | public void setReduceFunc(String reduceFunc) {
47 | this.reduceFunc = reduceFunc;
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/adaptor/ZMoSmartAdaptor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.adaptor;
2 |
3 | import org.nutz.lang.Lang;
4 | import org.nutz.lang.Mirror;
5 | import org.nutz.mongo.ZMoAdaptor;
6 | import org.nutz.mongo.entity.ZMoField;
7 |
8 | /**
9 | * 根据值的类型而不是字段类型类判断如何适配
10 | *
11 | * @author zozoh(zozohtnt@gmail.com)
12 | */
13 | public class ZMoSmartAdaptor implements ZMoAdaptor {
14 |
15 | ZMoSmartAdaptor() {}
16 |
17 | @Override
18 | public Object toJava(ZMoField fld, Object obj) {
19 | Mirror> mi = Mirror.me(obj);
20 | try {
21 | return ZMoAs.get(mi).toJava(fld, obj);
22 | }
23 | catch (Exception e) {
24 | throw Lang.wrapThrow(e, "I am not such smart toJava -_-! : %s", obj.getClass());
25 | }
26 | }
27 |
28 | @Override
29 | public Object toMongo(ZMoField fld, Object obj) {
30 | Mirror> mi = Mirror.me(obj);
31 | try {
32 | return ZMoAs.get(mi).toMongo(fld, obj);
33 | }
34 | catch (Exception e) {
35 | throw Lang.wrapThrow(e, "I am not such smart toMongo -_-! : %s", obj.getClass());
36 | }
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/adaptor/ZMoMapAdaptor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.adaptor;
2 |
3 | import org.nutz.lang.Lang;
4 | import org.nutz.lang.Mirror;
5 | import org.nutz.mongo.ZMo;
6 | import org.nutz.mongo.ZMoAdaptor;
7 | import org.nutz.mongo.ZMoDoc;
8 | import org.nutz.mongo.entity.ZMoEntity;
9 | import org.nutz.mongo.entity.ZMoField;
10 |
11 | import com.mongodb.DBObject;
12 |
13 | public class ZMoMapAdaptor implements ZMoAdaptor {
14 |
15 | ZMoMapAdaptor() {}
16 |
17 | @Override
18 | public Object toJava(ZMoField fld, Object obj) {
19 | if (obj instanceof DBObject) {
20 | ZMoDoc doc = ZMoDoc.WRAP((DBObject) obj);
21 | ZMoEntity en = ZMo.me().getEntity(fld.getType());
22 | return ZMo.me().fromDoc(doc, en);
23 | }
24 | throw Lang.makeThrow("toJava error: %s", obj.getClass());
25 | }
26 |
27 | @Override
28 | public Object toMongo(ZMoField fld, Object obj) {
29 | Mirror> mi = Mirror.me(obj);
30 | if (mi.isMap() || mi.isPojo()) {
31 | ZMoEntity en = ZMo.me().getEntity(mi.getType());
32 | return ZMo.me().toDoc(obj, en);
33 | }
34 | throw Lang.makeThrow("toMongo error: %s", obj.getClass());
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/adaptor/ZMoIdAdaptor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.adaptor;
2 |
3 | import org.bson.types.ObjectId;
4 | import org.nutz.lang.Lang;
5 | import org.nutz.lang.Mirror;
6 | import org.nutz.mongo.ZMoAdaptor;
7 | import org.nutz.mongo.entity.ZMoField;
8 |
9 | public class ZMoIdAdaptor implements ZMoAdaptor {
10 |
11 | @Override
12 | public Object toJava(ZMoField fld, Object obj) {
13 | if (obj instanceof ObjectId || obj instanceof Integer || obj instanceof Long) {
14 | if (null != fld) {
15 | Mirror> mi = fld.getMirror();
16 | if (null != mi) {
17 | if (mi.isOf(Object.class)) {
18 | return obj;
19 | }
20 | if (mi.isArray() && fld.getEleMirror().isOf(Object.class)) {
21 | return obj;
22 | }
23 | }
24 | }
25 | return obj.toString();
26 | }
27 | throw Lang.makeThrow("should be ObjectId");
28 | }
29 |
30 | @Override
31 | public Object toMongo(ZMoField fld, Object obj) {
32 | if (obj instanceof ObjectId) {
33 | return obj;
34 | }
35 | return new ObjectId(obj.toString());
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/interceptor/ZOperationExecutor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.interceptor;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import com.mongodb.ReadPreference;
7 | import com.mongodb.operation.OperationExecutor;
8 | import com.mongodb.operation.ReadOperation;
9 | import com.mongodb.operation.WriteOperation;
10 |
11 | public class ZOperationExecutor implements OperationExecutor {
12 |
13 | protected OperationExecutor proxy;
14 | protected List interceptors;
15 |
16 | protected ZOperationExecutor() {}
17 |
18 | public ZOperationExecutor(OperationExecutor proxy, List interceptors) {
19 | this.proxy = proxy;
20 | this.interceptors = interceptors;
21 | }
22 |
23 |
24 |
25 | public T execute(ReadOperation operation, ReadPreference readPreference) {
26 | if (interceptors == null)
27 | return proxy.execute(operation, readPreference);
28 | else {
29 | MongoInterceptorChain chain = new MongoInterceptorChain();
30 | chain.interceptors = new ArrayList(interceptors);
31 | chain.proxy = proxy;
32 | chain.readOperation = operation;
33 | chain.readPreference = readPreference;
34 | chain.doChain();
35 | return chain.result;
36 | }
37 | }
38 |
39 | public T execute(WriteOperation operation) {
40 | if (interceptors == null)
41 | return proxy.execute(operation);
42 | else {
43 | MongoInterceptorChain chain = new MongoInterceptorChain();
44 | chain.interceptors = new ArrayList(interceptors);
45 | chain.proxy = proxy;
46 | chain.writeOperation = operation;
47 | chain.doChain();
48 | return chain.result;
49 | }
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/java/build/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Nutz-mongo library build file
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
52 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/adaptor/ZMoDBObjectAdaptor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.adaptor;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import org.nutz.lang.Lang;
7 | import org.nutz.mongo.ZMo;
8 | import org.nutz.mongo.ZMoAdaptor;
9 | import org.nutz.mongo.ZMoDoc;
10 | import org.nutz.mongo.entity.ZMoField;
11 |
12 | import com.mongodb.DBObject;
13 |
14 | /**
15 | * 如果面对的值的类型是个 DBObject 我们有下面两个策略:
16 | *
17 | * - 如果是 List,那么就变 ArrayList
18 | *
- 否则变成 Map
19 | *
20 | * 转成 mongo 的值则不予考虑,直接转换就是了
21 | *
22 | * @author zozoh(zozohtnt@gmail.com)
23 | */
24 | public class ZMoDBObjectAdaptor implements ZMoAdaptor {
25 |
26 | @SuppressWarnings({"rawtypes", "unchecked"})
27 | @Override
28 | public Object toJava(ZMoField fld, Object obj) {
29 | // if(obj instanceof ArrayList>){
30 | // return obj;
31 | // }
32 | // 可能是 BasicDBList or LazyDBList
33 | if (obj instanceof List>) {
34 | List> list = (List>) obj;
35 | ArrayList arr = new ArrayList(list.size());
36 | int i = 0;
37 | for (Object o : list) {
38 | if (o == null) {
39 | arr.add(i++, o);
40 | } else if (o instanceof DBObject) {
41 | arr.add(i++, ZMoAs.dbo().toJava(null, o));
42 | } else {
43 | arr.add(o);
44 | }
45 | }
46 |
47 | return arr;
48 |
49 | }
50 | // 普通 DBObject 变 map
51 | else if (obj instanceof DBObject) {
52 | return ZMo.me().fromDocToMap(ZMoDoc.WRAP((DBObject) obj));
53 | }
54 | // 不可忍受,抛吧 >:D
55 | throw Lang.makeThrow("toJava error: %s", obj.getClass());
56 | }
57 |
58 | @Override
59 | public Object toMongo(ZMoField fld, Object obj) {
60 | if (obj instanceof DBObject) {
61 | return obj;
62 | }
63 | throw Lang.makeThrow("toMongo error: %s", obj.getClass());
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/entity/ZMoGeneralMapEntity.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.entity;
2 |
3 | import java.util.Map;
4 | import java.util.Set;
5 |
6 | import org.nutz.lang.util.NutMap;
7 |
8 | import com.mongodb.DBObject;
9 |
10 | public class ZMoGeneralMapEntity extends ZMoEntity {
11 |
12 | public ZMoGeneralMapEntity() {
13 | super();
14 | setDefaultField(new ZMoGeneralMapField());
15 | setType(NutMap.class);
16 | setBorning(this.getMirror().getBorning());
17 | }
18 |
19 | @Override
20 | public ZMoEntity forMap() {
21 | return this;
22 | }
23 |
24 | @Override
25 | public ZMoEntity forPojo() {
26 | return this;
27 | }
28 |
29 | @Override
30 | public boolean isForMap() {
31 | return true;
32 | }
33 |
34 | @Override
35 | public boolean isForPojo() {
36 | return false;
37 | }
38 |
39 | @SuppressWarnings("unchecked")
40 | @Override
41 | public Set getJavaNames(Object obj) {
42 | Map map = (Map) obj;
43 | return map.keySet();
44 | }
45 |
46 | @Override
47 | public Set getMongoNames(Object obj) {
48 | if (obj instanceof DBObject) {
49 | return ((DBObject) obj).keySet();
50 | }
51 | return getJavaNames(obj);
52 | }
53 |
54 | @Override
55 | public String getJavaNameFromMongo(String mongoName) {
56 | return mongoName;
57 | }
58 |
59 | @Override
60 | public String getMongoNameFromJava(String javaName) {
61 | return javaName;
62 | }
63 |
64 | @Override
65 | public Object getValue(Object obj, String javaName) {
66 | return ((Map, ?>) obj).get(javaName);
67 | }
68 |
69 | @SuppressWarnings("unchecked")
70 | @Override
71 | public void setValue(Object obj, String javaName, Object value) {
72 | ((Map) obj).put(javaName, value);
73 | }
74 |
75 | @Override
76 | public ZMoEntity clone() {
77 | return new ZMoGeneralMapEntity();
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/java/test/org/nutz/mongo/ZMoDocTest.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo;
2 |
3 | import static org.junit.Assert.*;
4 |
5 | import org.bson.types.ObjectId;
6 | import org.junit.Test;
7 | import org.nutz.lang.Lang;
8 | import org.nutz.lang.util.Closer;
9 | import org.nutz.mongo.fieldfilter.ZMoFF;
10 | import org.nutz.mongo.fieldfilter.ZMoRegexFF;
11 | import org.nutz.mongo.fieldfilter.ZMoSimpleFF;
12 | import org.nutz.mongo.pojo.Pet;
13 | import org.nutz.mongo.pojo.PetType;
14 |
15 | import com.mongodb.BasicDBList;
16 |
17 | public class ZMoDocTest {
18 |
19 | @Test
20 | public void test_simple_field_filter() {
21 | final Pet pet = Pet.NEW("xiaobai").setAge(10).setType(PetType.CAT);
22 | ZMoSimpleFF ff = new ZMoSimpleFF("name");
23 | ZMoDoc doc = ff.run(new Closer() {
24 | public ZMoDoc invoke() {
25 | return ZMo.me().toDoc(pet);
26 | }
27 | });
28 | assertEquals(1, doc.size());
29 | assertEquals("xiaobai", doc.get("nm").toString());
30 | }
31 |
32 | @Test
33 | public void test_regex_field_filter() {
34 | final Pet pet = Pet.NEW("xiaobai").setAge(10).setType(PetType.CAT);
35 | ZMoFF ff = new ZMoRegexFF("nm|tp").byJava(false);
36 | ZMoDoc doc = ff.run(new Closer() {
37 | public ZMoDoc invoke() {
38 | return ZMo.me().toDoc(pet);
39 | }
40 | });
41 | assertEquals(2, doc.size());
42 | assertEquals("xiaobai", doc.get("nm").toString());
43 | assertEquals(PetType.CAT, doc.getAs("tp", PetType.class));
44 | }
45 |
46 | @Test
47 | public void test_fld_is_ObjectIdArray() {
48 | ZMoDoc d2 = ZMoDoc.NEW("nm", "B");
49 | ObjectId[] ids = Lang.array(new ObjectId());
50 |
51 | d2.putv("frs", ids);
52 |
53 | BasicDBList frs = (BasicDBList) d2.get("frs");
54 | assertEquals(1, frs.size());
55 | ObjectId theId = (ObjectId) frs.get(0);
56 | assertEquals(ids[0], theId);
57 | }
58 |
59 | @Test
60 | public void test_fld_is_ObjectId() {
61 | ZMoDoc doc = ZMoDoc.NEW("abc", new ObjectId("521c6ffa3004c3c9cbfe59d3"));
62 | ObjectId id = doc.getAsId("abc");
63 | assertEquals("521c6ffa3004c3c9cbfe59d3", id.toString());
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/mr/ZMoMapReduceManager.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.mr;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.IOException;
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | import org.nutz.lang.Files;
10 | import org.nutz.lang.Lang;
11 | import org.nutz.lang.Streams;
12 | import org.nutz.lang.Strings;
13 |
14 | public class ZMoMapReduceManager {
15 |
16 | private Map map;
17 |
18 | private String home;
19 |
20 | public ZMoMapReduceManager(String home) {
21 | this.home = (home.endsWith("/") ? home.substring(0, home.length() - 1)
22 | : home).replaceAll("[.\\\\]", "/");
23 | this.map = new HashMap();
24 | }
25 |
26 | public ZMoMapReduce get(String key) {
27 | ZMoMapReduce mr = map.get(key);
28 | if (null == mr) {
29 | mr = syncGet(key);
30 | }
31 | return mr;
32 | }
33 |
34 | private synchronized ZMoMapReduce syncGet(String key) {
35 | ZMoMapReduce mr;
36 | mr = map.get(key);
37 | if (null == mr) {
38 | File f = Files.findFile(home + "/" + key + ".js");
39 | if (null != f) {
40 | try {
41 | StringBuilder sb = new StringBuilder();
42 | mr = new ZMoMapReduce();
43 | mr.setKey(key);
44 | BufferedReader br = Streams.buffr(Streams.fileInr(f));
45 | String line;
46 | // 首先得到 init obj
47 | while (null != (line = br.readLine())) {
48 | // 如果是 function 开头退出
49 | if (line.startsWith("function("))
50 | break;
51 | // 去掉注释符
52 | if (line.startsWith("//"))
53 | line = line.substring(2);
54 | // 累加
55 | sb.append(line).append('\n');
56 | }
57 | mr.setInit(Strings.trim(sb));
58 | // 继续读取函数
59 | sb = new StringBuilder(line);
60 | while (null != (line = br.readLine())) {
61 | sb.append('\n').append(line);
62 | }
63 | mr.setReduceFunc(sb.toString());
64 | // 加入缓存
65 | map.put(key, mr);
66 | }
67 | catch (IOException e) {
68 | throw Lang.wrapThrow(e);
69 | }
70 | }
71 | }
72 | return mr;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/ZMoDB.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo;
2 |
3 | import java.util.Set;
4 |
5 | import org.nutz.lang.Lang;
6 |
7 | import com.mongodb.DB;
8 |
9 | /**
10 | * 对于 DB 对象的薄封装
11 | *
12 | * @author zozoh(zozohtnt@gmail.com)
13 | */
14 | public class ZMoDB {
15 |
16 | private DB db;
17 |
18 | public ZMoDB(DB db) {
19 | this.db = db;
20 | }
21 |
22 | /**
23 | * 获取集合,如果集合不存在,则抛错
24 | *
25 | * @param name
26 | * 集合名称
27 | * @return 集合薄封装
28 | */
29 | public ZMoCo c(String name) {
30 | if (!db.collectionExists(name))
31 | throw Lang.makeThrow("Colection noexitst: %s.%s", db.getName(), name);
32 | return new ZMoCo(db.getCollection(name));
33 | }
34 |
35 | /**
36 | * 获取一个集合,如果集合不存在,就创建它
37 | *
38 | * @param name
39 | * 集合名
40 | * @param dropIfExists
41 | * true 如果存在就清除
42 | * @return 集合薄封装
43 | */
44 | public ZMoCo cc(String name, boolean dropIfExists) {
45 | // 不存在则创建
46 | if (!db.collectionExists(name)) {
47 | return createCollection(name, null);
48 | }
49 | // 固定清除
50 | else if (dropIfExists) {
51 | db.getCollection(name).drop();
52 | return createCollection(name, null);
53 | }
54 | // 已经存在
55 | return new ZMoCo(db.getCollection(name));
56 | }
57 |
58 | /**
59 | * 是否存在某个集合
60 | *
61 | * @param name
62 | * 集合名
63 | * @return 是否存在
64 | */
65 | public boolean cExists(String name) {
66 | return db.collectionExists(name);
67 | }
68 |
69 | /**
70 | * 创建一个集合
71 | *
72 | * @param name
73 | * 集合名
74 | * @param options
75 | * 集合配置信息
76 | * @return 集合薄封装
77 | */
78 | public ZMoCo createCollection(String name, ZMoDoc options) {
79 | if (db.collectionExists(name)) {
80 | throw Lang.makeThrow("Colection exitst: %s.%s", db.getName(), name);
81 | }
82 |
83 | // 创建默认配置信息
84 | if (null == options) {
85 | options = ZMoDoc.NEW("capped:false");
86 | }
87 |
88 | return new ZMoCo(db.createCollection(name, options));
89 | }
90 |
91 | /**
92 | * 清除数据库的游标
93 | *
94 | * @param force
95 | * 是否强制
96 | */
97 | @Deprecated
98 | public void cleanCursors(boolean force) {
99 | //db.cleanCursors(force);
100 | }
101 |
102 | /**
103 | * @return 当前数据库所有可用集合名称
104 | */
105 | public Set cNames() {
106 | return db.getCollectionNames();
107 | }
108 |
109 | public DB getNativeDB() {
110 | return this.db;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/interceptor/impl/LogMongoInterceptor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.interceptor.impl;
2 |
3 | import java.lang.reflect.Field;
4 |
5 | import org.bson.BsonDocument;
6 | import org.nutz.log.Log;
7 | import org.nutz.log.Logs;
8 | import org.nutz.mongo.interceptor.MongoInterceptor;
9 | import org.nutz.mongo.interceptor.MongoInterceptorChain;
10 |
11 | import com.mongodb.operation.CommandReadOperation;
12 | import com.mongodb.operation.CommandWriteOperation;
13 |
14 | public class LogMongoInterceptor implements MongoInterceptor {
15 |
16 | protected static final Log log = Logs.get();
17 |
18 | protected static Field cr_command;
19 | protected static Field cr_databaseName;
20 | protected static Field cw_command;
21 | protected static Field cw_databaseName;
22 | static {
23 | try {
24 | cr_command = CommandReadOperation.class.getDeclaredField("command");
25 | cw_command = CommandWriteOperation.class.getDeclaredField("command");
26 | cr_databaseName = CommandReadOperation.class.getDeclaredField("databaseName");
27 | cw_databaseName = CommandWriteOperation.class.getDeclaredField("databaseName");
28 |
29 | cr_command.setAccessible(true);
30 | cw_command.setAccessible(true);
31 | cr_databaseName.setAccessible(true);
32 | cw_databaseName.setAccessible(true);
33 | }
34 | catch (Exception e) {
35 | throw new RuntimeException(e);
36 | }
37 | }
38 |
39 | @SuppressWarnings("rawtypes")
40 | public void filter(MongoInterceptorChain> chain) {
41 | if (log.isDebugEnabled()) {
42 | try {
43 | BsonDocument command = null;
44 | String databaseName = "";
45 | String tag = "";
46 | if (chain.getReadOperation() != null && chain.getReadOperation() instanceof CommandReadOperation) {
47 | CommandReadOperation cr = (CommandReadOperation)chain.getReadOperation();
48 | command = (BsonDocument) cr_command.get(cr);
49 | databaseName = (String) cr_databaseName.get(cr);
50 | tag = "R";
51 | } else if (chain.getWriteOperation() != null && chain.getWriteOperation() instanceof CommandWriteOperation) {
52 | CommandWriteOperation cr = (CommandWriteOperation)chain.getReadOperation();
53 | command = (BsonDocument) cw_command.get(cr);
54 | databaseName = (String) cw_databaseName.get(cr);
55 | tag = "W";
56 | }
57 | if (command != null) {
58 | log.debugf("%s : db=%s : cmd=%s", tag, databaseName, command.values().iterator().next());
59 | }
60 | }
61 | catch (Exception e) {
62 | e.printStackTrace();
63 | }
64 | }
65 | chain.doChain();
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/adaptor/ZMoAs.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.adaptor;
2 |
3 | import java.util.regex.Pattern;
4 |
5 | import org.bson.types.ObjectId;
6 | import org.nutz.lang.Lang;
7 | import org.nutz.lang.Mirror;
8 | import org.nutz.mongo.ZMoAdaptor;
9 |
10 | import com.mongodb.DBObject;
11 |
12 | /**
13 | * 各个适配器的单例工厂方法
14 | *
15 | * @author zozoh(zozohtnt@gmail.com)
16 | */
17 | public class ZMoAs {
18 |
19 | private static ZMoAdaptor _id = new ZMoIdAdaptor();
20 |
21 | private static ZMoAdaptor _dbo = new ZMoDBObjectAdaptor();
22 |
23 | private static ZMoAdaptor _collection = new ZMoCollectionAdaptor();
24 |
25 | private static ZMoAdaptor _array = new ZMoArrayAdaptor();
26 |
27 | private static ZMoAdaptor _enum = new ZMoEnumAdaptor();
28 |
29 | private static ZMoAdaptor _map = new ZMoMapAdaptor();
30 |
31 | private static ZMoAdaptor _pojo = new ZMoPojoAdaptor();
32 |
33 | private static ZMoAdaptor _simple = new ZMoSimpleAdaptor();
34 |
35 | private static ZMoAdaptor _smart = new ZMoSmartAdaptor();
36 |
37 | public static ZMoAdaptor get(Mirror> mi) {
38 | // ID 对象
39 | if (mi.isOf(ObjectId.class)) {
40 | return ZMoAs.id();
41 | }
42 | // 简单类型
43 | else if (mi.isSimple() || mi.is(Pattern.class)) {
44 | return ZMoAs.simple();
45 | }
46 | // DBObject
47 | else if (mi.isOf(DBObject.class)) {
48 | return ZMoAs.dbo();
49 | }
50 | // 集合
51 | else if (mi.isCollection()) {
52 | return ZMoAs.collection();
53 | }
54 | // 数组
55 | else if (mi.isArray()) {
56 | return ZMoAs.array();
57 | }
58 | // 枚举
59 | else if (mi.isEnum()) {
60 | return ZMoAs.ENUM();
61 | }
62 | // Map
63 | else if (mi.isMap()) {
64 | return ZMoAs.map();
65 | }
66 | // POJO
67 | else if (mi.isPojo()) {
68 | return ZMoAs.pojo();
69 | }
70 | // 错误
71 | throw Lang.makeThrow("fail to found adaptor for type %s", mi.getType());
72 | }
73 |
74 | public static ZMoAdaptor id() {
75 | return _id;
76 | }
77 |
78 | public static ZMoAdaptor dbo() {
79 | return _dbo;
80 | }
81 |
82 | public static ZMoAdaptor collection() {
83 | return _collection;
84 | }
85 |
86 | public static ZMoAdaptor array() {
87 | return _array;
88 | }
89 |
90 | public static ZMoAdaptor ENUM() {
91 | return _enum;
92 | }
93 |
94 | public static ZMoAdaptor map() {
95 | return _map;
96 | }
97 |
98 | public static ZMoAdaptor pojo() {
99 | return _pojo;
100 | }
101 |
102 | public static ZMoAdaptor simple() {
103 | return _simple;
104 | }
105 |
106 | public static ZMoAdaptor smart() {
107 | return _smart;
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/interceptor/MongoInterceptorChain.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.interceptor;
2 |
3 | import java.util.List;
4 |
5 | import org.nutz.lang.Lang;
6 | import org.nutz.lang.util.Context;
7 |
8 | import com.mongodb.ReadPreference;
9 | import com.mongodb.operation.OperationExecutor;
10 | import com.mongodb.operation.ReadOperation;
11 | import com.mongodb.operation.WriteOperation;
12 |
13 | public class MongoInterceptorChain {
14 |
15 | protected ReadOperation readOperation;
16 | protected ReadPreference readPreference;
17 | protected WriteOperation writeOperation;
18 | protected List interceptors;
19 | protected int index;
20 | protected OperationExecutor proxy;
21 | protected T result;
22 | protected Context context;
23 |
24 | public void doChain() {
25 | if (interceptors.size() > index)
26 | interceptors.get(index++).filter(this);
27 | else {
28 | if (readOperation != null) {
29 | result = proxy.execute(readOperation, readPreference);
30 | } else if (writeOperation != null) {
31 | result = proxy.execute(writeOperation);
32 | }
33 | }
34 | }
35 |
36 | public ReadOperation getReadOperation() {
37 | return readOperation;
38 | }
39 |
40 | public void setReadOperation(ReadOperation readOperation) {
41 | this.readOperation = readOperation;
42 | }
43 |
44 | public ReadPreference getReadPreference() {
45 | return readPreference;
46 | }
47 |
48 | public void setReadPreference(ReadPreference readPreference) {
49 | this.readPreference = readPreference;
50 | }
51 |
52 | public WriteOperation getWriteOperation() {
53 | return writeOperation;
54 | }
55 |
56 | public void setWriteOperation(WriteOperation writeOperation) {
57 | this.writeOperation = writeOperation;
58 | }
59 |
60 | public List getInterceptors() {
61 | return interceptors;
62 | }
63 |
64 | public void setInterceptors(List interceptors) {
65 | this.interceptors = interceptors;
66 | }
67 |
68 | public int getIndex() {
69 | return index;
70 | }
71 |
72 | public void setIndex(int index) {
73 | this.index = index;
74 | }
75 |
76 | public OperationExecutor getProxy() {
77 | return proxy;
78 | }
79 |
80 | public void setProxy(OperationExecutor proxy) {
81 | this.proxy = proxy;
82 | }
83 |
84 | public T getResult() {
85 | return result;
86 | }
87 |
88 | public void setResult(T result) {
89 | this.result = result;
90 | }
91 |
92 | public Context getContext() {
93 | if (context == null)
94 | context = Lang.context();
95 | return context;
96 | }
97 |
98 | public void setContext(Context context) {
99 | this.context = context;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/fieldfilter/ZMoFF.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.fieldfilter;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import org.nutz.lang.util.Closer;
7 | import org.nutz.mongo.ZMo;
8 | import org.nutz.mongo.ZMoDoc;
9 | import org.nutz.mongo.entity.ZMoField;
10 |
11 | /**
12 | * 字段过滤器,在 toDoc 的时候生效,通过 ZMo.setFilterFilter 设置
13 | *
14 | * @author zozoh(zozohtnt@gmail.com)
15 | */
16 | public abstract class ZMoFF {
17 |
18 | private static ThreadLocal _field_filters_ = new ThreadLocal();
19 |
20 | public static void set(ZMoFF ff) {
21 | if (null != ff) {
22 | _field_filters_.set(ff);
23 | }
24 | }
25 |
26 | public static ZMoFF get() {
27 | return _field_filters_.get();
28 | }
29 |
30 | public static void remove() {
31 | _field_filters_.remove();
32 | }
33 |
34 | public T run(Closer closer) {
35 | set(this);
36 | try {
37 | return closer.invoke();
38 | }
39 | finally {
40 | remove();
41 | }
42 | }
43 |
44 | public ZMoDoc toDoc(final Object obj) {
45 | return run(new Closer() {
46 | public ZMoDoc invoke() {
47 | return ZMo.me().toDoc(obj);
48 | }
49 | });
50 | }
51 |
52 | /**
53 | * true 表示匹配上的字段忽略,false 表示匹配上的字段不忽略
54 | */
55 | private boolean asIgnore;
56 |
57 | /**
58 | * true 表示匹配Java字段,false 表示匹配Mongo字段
59 | */
60 | private boolean byJava;
61 |
62 | /**
63 | * 是否忽略 null 值
64 | */
65 | private boolean ignoreNull;
66 |
67 | /**
68 | * 对于特殊字段,指定为特殊值的时候忽略
69 | */
70 | private Map ignoreNumber;
71 |
72 | protected ZMoFF() {
73 | asIgnore = false;
74 | byJava = true;
75 | ignoreNull = false;
76 | ignoreNumber = new HashMap();
77 | }
78 |
79 | /**
80 | * @param fld
81 | * 当前字段
82 | * @return 是否忽略这个字段
83 | */
84 | public boolean isIgnore(ZMoField fld, Object v) {
85 | if (null == v && ignoreNull)
86 | return true;
87 |
88 | // 得到名称
89 | String key = byJava ? fld.getJavaName() : fld.getMongoName();
90 |
91 | // 如果是数字,那么看看是否需要忽略
92 | if (null != v && !ignoreNumber.isEmpty() && v instanceof Number) {
93 | Number n = ignoreNumber.get(key);
94 | if (null != n && n.doubleValue() == ((Number) v).doubleValue())
95 | return true;
96 | }
97 |
98 | // 如果匹配上了
99 | if (match(key)) {
100 | return asIgnore;
101 | }
102 | return !asIgnore;
103 | }
104 |
105 | public ZMoFF asIgnore(boolean asActive) {
106 | this.asIgnore = asActive;
107 | return this;
108 | }
109 |
110 | public ZMoFF byJava(boolean byJava) {
111 | this.byJava = byJava;
112 | return this;
113 | }
114 |
115 | public ZMoFF ignoreNull(boolean ignoreNull) {
116 | this.ignoreNull = ignoreNull;
117 | return this;
118 | }
119 |
120 | /**
121 | * @param key
122 | * 根据 byJava 的设定
123 | * @param n
124 | * 值
125 | * @return 自身
126 | */
127 | public ZMoFF ignoreNumber(String key, Number n) {
128 | ignoreNumber.put(key, n);
129 | return this;
130 | }
131 |
132 | /**
133 | * 子类的抽象实现
134 | *
135 | * @param fld
136 | * 字段名
137 | * @return 是否匹配上
138 | */
139 | protected abstract boolean match(String fld);
140 |
141 | }
142 |
--------------------------------------------------------------------------------
/java/test/org/nutz/mongo/pojo/Pet.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.pojo;
2 |
3 | import java.util.Date;
4 |
5 | import org.bson.types.ObjectId;
6 | import org.nutz.castor.Castors;
7 | import org.nutz.lang.Times;
8 | import org.nutz.lang.random.R;
9 | import org.nutz.mongo.annotation.*;
10 |
11 | public class Pet {
12 |
13 | public static Pet NEW(String name) {
14 | return new Pet().setName(name);
15 | }
16 |
17 | public static Pet[] ARR(String... names) {
18 | Pet[] pets = new Pet[names.length];
19 | for (int i = 0; i < names.length; i++) {
20 | pets[i] = NEW(names[i]).setAge(R.random(2, 20))
21 | .setBornAt(Times.now())
22 | .setColor(Castors.me()
23 | .castTo(R.random(0, 6),
24 | PetColor.class))
25 | .setType(Castors.me().castTo(R.random(0, 4),
26 | PetType.class));
27 | }
28 | return pets;
29 | }
30 |
31 | public static final String CNAME = "pet";
32 |
33 | private String _id;
34 |
35 | @MoField("nm")
36 | private String name;
37 |
38 | private int age;
39 |
40 | @MoField("ba")
41 | private Date bornAt;
42 |
43 | @MoField("tp")
44 | private PetType type;
45 |
46 | @MoEnum(str = false)
47 | private PetColor color;
48 |
49 | @MoIgnore
50 | private String comment;
51 |
52 | @MoField("ma")
53 | private Human master;
54 |
55 | private String[] labels;
56 |
57 | @MoField("frs")
58 | private ObjectId[] friends;
59 |
60 | public String[] getLabels() {
61 | return labels;
62 | }
63 |
64 | public Pet setLabels(String[] labels) {
65 | this.labels = labels;
66 | return this;
67 | }
68 |
69 | public String get_id() {
70 | return _id;
71 | }
72 |
73 | public void set_id(String _id) {
74 | this._id = _id;
75 | }
76 |
77 | public String getName() {
78 | return name;
79 | }
80 |
81 | public Pet setName(String name) {
82 | this.name = name;
83 | return this;
84 | }
85 |
86 | public int getAge() {
87 | return age;
88 | }
89 |
90 | public Pet setAge(int age) {
91 | this.age = age;
92 | return this;
93 | }
94 |
95 | public Date getBornAt() {
96 | return bornAt;
97 | }
98 |
99 | public Pet setBornAt(Date bornAt) {
100 | this.bornAt = bornAt;
101 | return this;
102 | }
103 |
104 | public PetType getType() {
105 | return type;
106 | }
107 |
108 | public Pet setType(PetType type) {
109 | this.type = type;
110 | return this;
111 | }
112 |
113 | public PetColor getColor() {
114 | return color;
115 | }
116 |
117 | public Pet setColor(PetColor color) {
118 | this.color = color;
119 | return this;
120 | }
121 |
122 | public String getComment() {
123 | return comment;
124 | }
125 |
126 | public Pet setComment(String comment) {
127 | this.comment = comment;
128 | return this;
129 | }
130 |
131 | public Human getMaster() {
132 | return master;
133 | }
134 |
135 | public void setMaster(Human master) {
136 | this.master = master;
137 | }
138 |
139 | public ObjectId[] getFriends() {
140 | return friends;
141 | }
142 |
143 | public Pet setFriends(ObjectId[] friends) {
144 | this.friends = friends;
145 | return this;
146 | }
147 |
148 | }
149 |
--------------------------------------------------------------------------------
/java/src/org/nutz/mongo/adaptor/ZMoCollectionAdaptor.java:
--------------------------------------------------------------------------------
1 | package org.nutz.mongo.adaptor;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collection;
5 | import java.util.Iterator;
6 |
7 | import org.bson.types.ObjectId;
8 | import org.nutz.lang.Lang;
9 | import org.nutz.lang.Mirror;
10 | import org.nutz.mongo.ZMo;
11 | import org.nutz.mongo.ZMoAdaptor;
12 | import org.nutz.mongo.entity.ZMoEntity;
13 | import org.nutz.mongo.entity.ZMoField;
14 |
15 | import com.mongodb.BasicDBList;
16 | import com.mongodb.DBObject;
17 |
18 | public class ZMoCollectionAdaptor implements ZMoAdaptor {
19 |
20 | ZMoCollectionAdaptor() {}
21 |
22 | @SuppressWarnings("unchecked")
23 | @Override
24 | public Object toJava(ZMoField fld, Object obj) {
25 | if (obj instanceof BasicDBList) {
26 | BasicDBList list = (BasicDBList) obj;
27 |
28 | // 获取元素的实体
29 | ZMoEntity en = null;
30 |
31 | // 创建数组
32 | Collection