/**
 * 
 */
package cn.strong.leke.data.mongo.core;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;

import cn.strong.leke.data.mongo.codec.BeanCodecProvider;

/**
 * MongoCleint 工厂Bean
 * 
 * @author liulongbiao
 *
 */
public class MongoClientFactoryBean implements FactoryBean<MongoClient>,
		InitializingBean, DisposableBean {

	private MongoClient client;

	private String replicaset;
	private String credentials;

	@Override
	public void afterPropertiesSet() throws Exception {
		List<ServerAddress> seeds = buildSeeds();
		List<MongoCredential> credentialsList = buildCredentials();

		// 注册 BeanCodecProvider 为最后一个 Codec
		CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
				MongoClient.getDefaultCodecRegistry(),
				CodecRegistries.fromProviders(new BeanCodecProvider()));
		MongoClientOptions options = new MongoClientOptions.Builder()
				.codecRegistry(codecRegistry).build();

		client = new MongoClient(seeds, credentialsList, options);
	}

	private List<ServerAddress> buildSeeds() throws UnknownHostException {
		List<ServerAddress> seeds = new ArrayList<ServerAddress>();
		if (StringUtils.hasText(replicaset)) {
			String[] uris = replicaset.split(",");
			for (String uri : uris) {
				seeds.add(new ServerAddress(uri));
			}
		} else {
			seeds.add(new ServerAddress());
		}
		return seeds;
	}

	private List<MongoCredential> buildCredentials() {
		if (!StringUtils.hasText(credentials)) {
			return Collections.emptyList();
		}
		List<MongoCredential> result = new ArrayList<MongoCredential>();
		String[] creds = credentials.split(",");
		for (String cred : creds) {
			if (StringUtils.hasText(cred)) {
				String[] triple = cred.split(":");
				if (triple.length != 3) {
					throw new IllegalArgumentException(
							"credential format must confirm to ${username}:${dbname}:${password} ,but actual received :"
									+ cred);
				}
				result.add(MongoCredential.createMongoCRCredential(triple[0],
						triple[1], triple[2].toCharArray()));
			}
		}
		return result;
	}

	@Override
	public MongoClient getObject() throws Exception {
		return this.client;
	}

	@Override
	public Class<?> getObjectType() {
		return MongoClient.class;
	}

	@Override
	public boolean isSingleton() {
		return true;
	}

	@Override
	public void destroy() throws Exception {
		this.client.close();
	}

	public void setReplicaset(String replicaset) {
		this.replicaset = replicaset;
	}

	public void setCredentials(String credentials) {
		this.credentials = credentials;
	}

}

@@ -46,16 +46,71 @@
 .core;%0A%0A
+import static com.mongodb.MongoClientOptions.builder;%0A%0A
 import j
@@ -610,24 +610,71 @@
 entOptions;%0A
+import com.mongodb.MongoClientOptions.Builder;%0A
 import com.m
@@ -1048,16 +1048,53 @@
 entials;
+%0A%09private MongoClientOptions options;
 %0A%0A%09@Over
@@ -1466,34 +1466,33 @@
 ()));%0A%09%09
-MongoClientOptions
+Builder builder =
  options
@@ -1493,21 +1493,57 @@
 ptions =
+=
  n
-ew 
+ull ? builder() : builder(options);%0A%09%09
 MongoCli
@@ -1556,23 +1556,22 @@
 ions
-.Builder()%0A%09%09%09%09
+ ops = builder
 .cod
@@ -1659,20 +1659,16 @@
 List, op
-tion
 s);%0A%09%7D%0A%0A
@@ -3191,10 +3191,94 @@
 ls;%0A%09%7D%0A%0A
+%09public void setOptions(MongoClientOptions options) %7B%0A%09%09this.options = options;%0A%09%7D%0A%0A
 %7D%0A

添加 options 配置