Shade in GSON, BSON and MongoDB.

This commit is contained in:
Olof Larsson 2014-09-12 23:36:17 +02:00
parent 2e589a195e
commit e0656ab9ea
201 changed files with 237 additions and 30711 deletions

View File

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.massivecraft</groupId>
<artifactId>MassiveCore</artifactId>
<name>MassiveCore</name>
<version>7.5.0</version>
<build>
<sourceDirectory>src</sourceDirectory>
<defaultGoal>clean package install</defaultGoal>
<resources>
<resource>
<targetPath>.</targetPath>
<filtering>true</filtering>
<directory>.</directory>
<includes>
<include>*.yml</include>
<include>*.md</include>
<include>*.txt</include>
</includes>
</resource>
</resources>
<finalName>MassiveCore</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.google.code.gson:gson</include>
<include>org.mongodb:mongo-java-driver</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>com.google.gson</pattern>
<shadedPattern>com.massivecraft.massivecore.xlib.gson</shadedPattern>
</relocation>
<relocation>
<pattern>com.mongodb</pattern>
<shadedPattern>com.massivecraft.massivecore.xlib.mongodb</shadedPattern>
</relocation>
<relocation>
<pattern>org.bson</pattern>
<shadedPattern>com.massivecraft.massivecore.xlib.bson</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/groups/public/</url>
</repository>
<repository>
<id>vault-repo</id>
<url>http://nexus.theyeticave.net/content/repositories/pub_releases</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.7.9-R0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>Vault</artifactId>
<version>1.4.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

14
pom.xml
View File

@ -50,6 +50,7 @@
<artifactSet> <artifactSet>
<includes> <includes>
<include>com.google.code.gson:gson</include> <include>com.google.code.gson:gson</include>
<include>org.mongodb:mongo-java-driver</include>
</includes> </includes>
</artifactSet> </artifactSet>
<relocations> <relocations>
@ -57,6 +58,14 @@
<pattern>com.google.gson</pattern> <pattern>com.google.gson</pattern>
<shadedPattern>com.massivecraft.massivecore.xlib.gson</shadedPattern> <shadedPattern>com.massivecraft.massivecore.xlib.gson</shadedPattern>
</relocation> </relocation>
<relocation>
<pattern>com.mongodb</pattern>
<shadedPattern>com.massivecraft.massivecore.xlib.mongodb</shadedPattern>
</relocation>
<relocation>
<pattern>org.bson</pattern>
<shadedPattern>com.massivecraft.massivecore.xlib.bson</shadedPattern>
</relocation>
</relocations> </relocations>
</configuration> </configuration>
</execution> </execution>
@ -82,6 +91,11 @@
<artifactId>gson</artifactId> <artifactId>gson</artifactId>
<version>2.2.4</version> <version>2.2.4</version>
</dependency> </dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>2.12.3</version>
</dependency>
</dependencies> </dependencies>
<repositories> <repositories>

View File

@ -4,8 +4,8 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import com.google.gson.annotations.SerializedName;
import com.massivecraft.massivecore.store.Entity; import com.massivecraft.massivecore.store.Entity;
import com.massivecraft.massivecore.xlib.gson.annotations.SerializedName;
public class Aspect extends Entity<Aspect> public class Aspect extends Entity<Aspect>
{ {

View File

@ -7,11 +7,18 @@ import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import org.bson.types.ObjectId;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.massivecraft.massivecore.adapter.InventoryAdapter; import com.massivecraft.massivecore.adapter.InventoryAdapter;
import com.massivecraft.massivecore.adapter.ItemStackAdapter; import com.massivecraft.massivecore.adapter.ItemStackAdapter;
import com.massivecraft.massivecore.adapter.JsonElementAdapter; import com.massivecraft.massivecore.adapter.JsonElementAdapter;
@ -36,13 +43,6 @@ import com.massivecraft.massivecore.teleport.EngineScheduledTeleport;
import com.massivecraft.massivecore.util.IdUtil; import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.PlayerUtil; import com.massivecraft.massivecore.util.PlayerUtil;
import com.massivecraft.massivecore.util.Txt; import com.massivecraft.massivecore.util.Txt;
import com.massivecraft.massivecore.xlib.bson.types.ObjectId;
import com.massivecraft.massivecore.xlib.gson.Gson;
import com.massivecraft.massivecore.xlib.gson.GsonBuilder;
import com.massivecraft.massivecore.xlib.gson.JsonArray;
import com.massivecraft.massivecore.xlib.gson.JsonNull;
import com.massivecraft.massivecore.xlib.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive;
public class MassiveCore extends MassivePlugin public class MassiveCore extends MassivePlugin
{ {

View File

@ -9,7 +9,7 @@ import org.bukkit.permissions.Permissible;
import com.massivecraft.massivecore.store.Entity; import com.massivecraft.massivecore.store.Entity;
import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.PermUtil; import com.massivecraft.massivecore.util.PermUtil;
import com.massivecraft.massivecore.xlib.mongodb.WriteConcern; import com.mongodb.WriteConcern;
public class MassiveCoreMConf extends Entity<MassiveCoreMConf> public class MassiveCoreMConf extends Entity<MassiveCoreMConf>
{ {

View File

@ -14,8 +14,8 @@ import com.massivecraft.massivecore.integration.IntegrationGlue;
import com.massivecraft.massivecore.integration.Integration; import com.massivecraft.massivecore.integration.Integration;
import com.massivecraft.massivecore.store.Coll; import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.util.Txt; import com.massivecraft.massivecore.util.Txt;
import com.massivecraft.massivecore.xlib.gson.Gson; import com.google.gson.Gson;
import com.massivecraft.massivecore.xlib.gson.GsonBuilder; import com.google.gson.GsonBuilder;
public abstract class MassivePlugin extends JavaPlugin implements Listener public abstract class MassivePlugin extends JavaPlugin implements Listener
{ {

View File

@ -6,7 +6,7 @@ import org.bukkit.plugin.Plugin;
import com.massivecraft.massivecore.store.accessor.Accessor; import com.massivecraft.massivecore.store.accessor.Accessor;
import com.massivecraft.massivecore.util.DiscUtil; import com.massivecraft.massivecore.util.DiscUtil;
import com.massivecraft.massivecore.xlib.gson.Gson; import com.google.gson.Gson;
public class SimpleConfig public class SimpleConfig
{ {

View File

@ -11,10 +11,10 @@ import org.bukkit.FireworkEffect;
import org.bukkit.FireworkEffect.Type; import org.bukkit.FireworkEffect.Type;
import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.xlib.gson.JsonArray; import com.google.gson.JsonArray;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonObject; import com.google.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
public class FireworkEffectAdapter public class FireworkEffectAdapter
{ {

View File

@ -8,14 +8,14 @@ import org.bukkit.inventory.PlayerInventory;
import com.massivecraft.massivecore.MassiveCore; import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.mixin.Mixin; import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonObject; import com.google.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer; import com.google.gson.JsonSerializer;
/** /**
* This is my Gson adapter for Inventories. * This is my Gson adapter for Inventories.

View File

@ -26,15 +26,15 @@ import org.bukkit.inventory.meta.Repairable;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import com.massivecraft.massivecore.xlib.gson.JsonArray; import com.google.gson.JsonArray;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonObject; import com.google.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer; import com.google.gson.JsonSerializer;
/** /**
* This is a GSON serializer/deserializer for the Bukkit ItemStack. Why not use * This is a GSON serializer/deserializer for the Bukkit ItemStack. Why not use

View File

@ -2,12 +2,12 @@ package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer; import com.google.gson.JsonSerializer;
public class JsonElementAdapter implements JsonDeserializer<JsonElement>, JsonSerializer<JsonElement> public class JsonElementAdapter implements JsonDeserializer<JsonElement>, JsonSerializer<JsonElement>
{ {

View File

@ -1,13 +1,13 @@
package com.massivecraft.massivecore.adapter; package com.massivecraft.massivecore.adapter;
import com.massivecraft.massivecore.xlib.gson.Gson; import com.google.gson.Gson;
import com.massivecraft.massivecore.xlib.gson.TypeAdapter; import com.google.gson.TypeAdapter;
import com.massivecraft.massivecore.xlib.gson.TypeAdapterFactory; import com.google.gson.TypeAdapterFactory;
import com.massivecraft.massivecore.xlib.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import com.massivecraft.massivecore.xlib.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.massivecraft.massivecore.xlib.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import com.massivecraft.massivecore.xlib.gson.stream.JsonToken; import com.google.gson.stream.JsonToken;
import com.massivecraft.massivecore.xlib.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;

View File

@ -2,14 +2,15 @@ package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import com.massivecraft.massivecore.xlib.bson.types.ObjectId; import org.bson.types.ObjectId;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer; import com.google.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonParseException; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive; import com.google.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext; import com.google.gson.JsonPrimitive;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer; import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
public class ObjectIdAdapter implements JsonDeserializer<ObjectId>, JsonSerializer<ObjectId> public class ObjectIdAdapter implements JsonDeserializer<ObjectId>, JsonSerializer<ObjectId>
{ {

View File

@ -4,12 +4,12 @@ import java.lang.reflect.Type;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer; import com.google.gson.JsonSerializer;
public class PlayerInventoryAdapter implements JsonDeserializer<PlayerInventory>, JsonSerializer<PlayerInventory> public class PlayerInventoryAdapter implements JsonDeserializer<PlayerInventory>, JsonSerializer<PlayerInventory>
{ {

View File

@ -2,15 +2,15 @@ package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonNull; import com.google.gson.JsonNull;
import com.massivecraft.massivecore.xlib.gson.JsonObject; import com.google.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer; import com.google.gson.JsonSerializer;
public class PolymorphicAdapter<T> implements JsonDeserializer<T>, JsonSerializer<T> public class PolymorphicAdapter<T> implements JsonDeserializer<T>, JsonSerializer<T>
{ {

View File

@ -3,8 +3,8 @@ package com.massivecraft.massivecore.adapter;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonObject; import com.google.gson.JsonObject;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class PotionEffectAdapter public class PotionEffectAdapter

View File

@ -3,13 +3,13 @@ package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.UUID; import java.util.UUID;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer; import com.google.gson.JsonSerializer;
public class UUIDAdapter implements JsonDeserializer<UUID>, JsonSerializer<UUID> public class UUIDAdapter implements JsonDeserializer<UUID>, JsonSerializer<UUID>
{ {

View File

@ -12,7 +12,7 @@ import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.Db; import com.massivecraft.massivecore.store.Db;
import com.massivecraft.massivecore.store.Driver; import com.massivecraft.massivecore.store.Driver;
import com.massivecraft.massivecore.store.MStore; import com.massivecraft.massivecore.store.MStore;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
public class CmdMassiveCoreStoreCopydb extends MassiveCommand public class CmdMassiveCoreStoreCopydb extends MassiveCommand
{ {

View File

@ -15,9 +15,9 @@ import com.massivecraft.massivecore.Aspect;
import com.massivecraft.massivecore.MassiveCore; import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.Multiverse; import com.massivecraft.massivecore.Multiverse;
import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonObject; import com.google.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
/** /**
* # Introduction * # Introduction

View File

@ -2,10 +2,10 @@ package com.massivecraft.massivecore.ps;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonParseException; import com.google.gson.JsonParseException;
public class PSAdapter implements JsonDeserializer<PS> public class PSAdapter implements JsonDeserializer<PS>
{ {

View File

@ -22,9 +22,9 @@ import com.massivecraft.massivecore.NaturalOrderComparator;
import com.massivecraft.massivecore.Predictate; import com.massivecraft.massivecore.Predictate;
import com.massivecraft.massivecore.store.accessor.Accessor; import com.massivecraft.massivecore.store.accessor.Accessor;
import com.massivecraft.massivecore.util.Txt; import com.massivecraft.massivecore.util.Txt;
import com.massivecraft.massivecore.xlib.gson.Gson; import com.google.gson.Gson;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonObject; import com.google.gson.JsonObject;
public class Coll<E> implements CollInterface<E> public class Coll<E> implements CollInterface<E>
{ {

View File

@ -1,6 +1,6 @@
package com.massivecraft.massivecore.store; package com.massivecraft.massivecore.store;
import com.massivecraft.massivecore.xlib.mongodb.DB; import com.mongodb.DB;
public class DbMongo extends DbAbstract public class DbMongo extends DbAbstract
{ {

View File

@ -5,7 +5,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
public interface Driver public interface Driver
{ {

View File

@ -12,8 +12,8 @@ import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
import com.massivecraft.massivecore.util.DiscUtil; import com.massivecraft.massivecore.util.DiscUtil;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonParser; import com.google.gson.JsonParser;
public class DriverFlatfile extends DriverAbstract public class DriverFlatfile extends DriverAbstract
{ {

View File

@ -10,13 +10,13 @@ import java.util.AbstractMap.SimpleEntry;
import java.util.Map.Entry; import java.util.Map.Entry;
import com.massivecraft.massivecore.MassiveCoreMConf; import com.massivecraft.massivecore.MassiveCoreMConf;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.mongodb.BasicDBObject; import com.mongodb.BasicDBObject;
import com.massivecraft.massivecore.xlib.mongodb.DB; import com.mongodb.DB;
import com.massivecraft.massivecore.xlib.mongodb.DBCollection; import com.mongodb.DBCollection;
import com.massivecraft.massivecore.xlib.mongodb.DBCursor; import com.mongodb.DBCursor;
import com.massivecraft.massivecore.xlib.mongodb.MongoClient; import com.mongodb.MongoClient;
import com.massivecraft.massivecore.xlib.mongodb.MongoClientURI; import com.mongodb.MongoClientURI;
public class DriverMongo extends DriverAbstract public class DriverMongo extends DriverAbstract
{ {

View File

@ -3,8 +3,8 @@ package com.massivecraft.massivecore.store;
import com.massivecraft.massivecore.MassiveCore; import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.NaturalOrderComparator; import com.massivecraft.massivecore.NaturalOrderComparator;
import com.massivecraft.massivecore.store.accessor.Accessor; import com.massivecraft.massivecore.store.accessor.Accessor;
import com.massivecraft.massivecore.xlib.gson.Gson; import com.google.gson.Gson;
import com.massivecraft.massivecore.xlib.gson.JsonObject; import com.google.gson.JsonObject;
/** /**
* Usage of this class is highly optional. You may persist anything. If you are * Usage of this class is highly optional. You may persist anything. If you are

View File

@ -3,10 +3,10 @@ package com.massivecraft.massivecore.store;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import com.massivecraft.massivecore.xlib.gson.JsonArray; import com.google.gson.JsonArray;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonNull; import com.google.gson.JsonNull;
import com.massivecraft.massivecore.xlib.gson.JsonObject; import com.google.gson.JsonObject;
public class GsonCloner public class GsonCloner
{ {

View File

@ -4,12 +4,12 @@ import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import com.massivecraft.massivecore.xlib.gson.JsonArray; import com.google.gson.JsonArray;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonNull; import com.google.gson.JsonNull;
import com.massivecraft.massivecore.xlib.gson.JsonObject; import com.google.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import com.massivecraft.massivecore.xlib.gson.internal.LazilyParsedNumber; import com.google.gson.internal.LazilyParsedNumber;
public class GsonEqualsChecker public class GsonEqualsChecker
{ {

View File

@ -3,17 +3,17 @@ package com.massivecraft.massivecore.store;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bson.types.ObjectId;
import com.massivecraft.massivecore.xlib.bson.types.ObjectId; import com.google.gson.JsonArray;
import com.massivecraft.massivecore.xlib.gson.JsonArray; import com.google.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonNull;
import com.massivecraft.massivecore.xlib.gson.JsonNull; import com.google.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonObject; import com.google.gson.JsonPrimitive;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive; import com.google.gson.internal.LazilyParsedNumber;
import com.massivecraft.massivecore.xlib.gson.internal.LazilyParsedNumber; import com.mongodb.BasicDBList;
import com.massivecraft.massivecore.xlib.mongodb.BasicDBList; import com.mongodb.BasicDBObject;
import com.massivecraft.massivecore.xlib.mongodb.BasicDBObject; import com.mongodb.DBObject;
import com.massivecraft.massivecore.xlib.mongodb.DBObject;
public final class GsonMongoConverter public final class GsonMongoConverter
{ {

View File

@ -7,7 +7,7 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
import com.massivecraft.massivecore.ConfServer; import com.massivecraft.massivecore.ConfServer;
import com.massivecraft.massivecore.xlib.gson.JsonElement; import com.google.gson.JsonElement;
public class MStore public class MStore
{ {

View File

@ -37,7 +37,7 @@ import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.store.Coll; import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.SenderColl; import com.massivecraft.massivecore.store.SenderColl;
import com.massivecraft.massivecore.store.SenderEntity; import com.massivecraft.massivecore.store.SenderEntity;
import com.massivecraft.massivecore.xlib.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
/** /**
* Identification of a CommandSender can be done in 4 different ways. * Identification of a CommandSender can be done in 4 different ways.

View File

@ -1,346 +0,0 @@
// BSON.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import com.massivecraft.massivecore.xlib.bson.util.ClassMap;
@SuppressWarnings({"rawtypes"})
public class BSON {
static final Logger LOGGER = Logger.getLogger( "org.bson.BSON" );
// ---- basics ----
public static final byte EOO = 0;
public static final byte NUMBER = 1;
public static final byte STRING = 2;
public static final byte OBJECT = 3;
public static final byte ARRAY = 4;
public static final byte BINARY = 5;
public static final byte UNDEFINED = 6;
public static final byte OID = 7;
public static final byte BOOLEAN = 8;
public static final byte DATE = 9;
public static final byte NULL = 10;
public static final byte REGEX = 11;
public static final byte REF = 12;
public static final byte CODE = 13;
public static final byte SYMBOL = 14;
public static final byte CODE_W_SCOPE = 15;
public static final byte NUMBER_INT = 16;
public static final byte TIMESTAMP = 17;
public static final byte NUMBER_LONG = 18;
public static final byte MINKEY = -1;
public static final byte MAXKEY = 127;
// --- binary types
/*
these are binary types
so the format would look like
<BINARY><name><BINARY_TYPE><...>
*/
public static final byte B_GENERAL = 0;
public static final byte B_FUNC = 1;
public static final byte B_BINARY = 2;
public static final byte B_UUID = 3;
// ---- regular expression handling ----
/** Converts a string of regular expression flags from the database in Java regular
* expression flags.
* @param flags flags from database
* @return the Java flags
*/
public static int regexFlags( String flags ){
int fint = 0;
if ( flags == null || flags.length() == 0 )
return fint;
flags = flags.toLowerCase();
for( int i=0; i<flags.length(); i++ ) {
RegexFlag flag = RegexFlag.getByCharacter( flags.charAt( i ) );
if( flag != null ) {
fint |= flag.javaFlag;
if( flag.unsupported != null )
_warnUnsupportedRegex( flag.unsupported );
}
else {
throw new IllegalArgumentException( "unrecognized flag ["+flags.charAt( i ) + "] " + (int)flags.charAt(i) );
}
}
return fint;
}
public static int regexFlag( char c ){
RegexFlag flag = RegexFlag.getByCharacter( c );
if ( flag == null )
throw new IllegalArgumentException( "unrecognized flag [" + c + "]" );
if ( flag.unsupported != null ){
_warnUnsupportedRegex( flag.unsupported );
return 0;
}
return flag.javaFlag;
}
/** Converts Java regular expression flags into a string of flags for the database
* @param flags Java flags
* @return the flags for the database
*/
public static String regexFlags( int flags ){
StringBuilder buf = new StringBuilder();
for( RegexFlag flag : RegexFlag.values() ) {
if( ( flags & flag.javaFlag ) > 0 ) {
buf.append( flag.flagChar );
flags -= flag.javaFlag;
}
}
if( flags > 0 )
throw new IllegalArgumentException( "some flags could not be recognized." );
return buf.toString();
}
private static enum RegexFlag {
CANON_EQ( Pattern.CANON_EQ, 'c', "Pattern.CANON_EQ" ),
UNIX_LINES(Pattern.UNIX_LINES, 'd', "Pattern.UNIX_LINES" ),
GLOBAL( GLOBAL_FLAG, 'g', null ),
CASE_INSENSITIVE( Pattern.CASE_INSENSITIVE, 'i', null ),
MULTILINE(Pattern.MULTILINE, 'm', null ),
DOTALL( Pattern.DOTALL, 's', "Pattern.DOTALL" ),
LITERAL( Pattern.LITERAL, 't', "Pattern.LITERAL" ),
UNICODE_CASE( Pattern.UNICODE_CASE, 'u', "Pattern.UNICODE_CASE" ),
COMMENTS( Pattern.COMMENTS, 'x', null );
private static final Map<Character, RegexFlag> byCharacter = new HashMap<Character, RegexFlag>();
static {
for (RegexFlag flag : values()) {
byCharacter.put(flag.flagChar, flag);
}
}
public static RegexFlag getByCharacter(char ch) {
return byCharacter.get(ch);
}
public final int javaFlag;
public final char flagChar;
public final String unsupported;
RegexFlag( int f, char ch, String u ) {
javaFlag = f;
flagChar = ch;
unsupported = u;
}
}
private static void _warnUnsupportedRegex( String flag ) {
LOGGER.info( "flag " + flag + " not supported by db." );
}
private static final int GLOBAL_FLAG = 256;
// --- (en|de)coding hooks -----
public static boolean hasDecodeHooks() { return _decodeHooks; }
public static void addEncodingHook( Class c , Transformer t ){
_encodeHooks = true;
List<Transformer> l = _encodingHooks.get( c );
if ( l == null ){
l = new CopyOnWriteArrayList<Transformer>();
_encodingHooks.put( c , l );
}
l.add( t );
}
public static void addDecodingHook( Class c , Transformer t ){
_decodeHooks = true;
List<Transformer> l = _decodingHooks.get( c );
if ( l == null ){
l = new CopyOnWriteArrayList<Transformer>();
_decodingHooks.put( c , l );
}
l.add( t );
}
public static Object applyEncodingHooks( Object o ){
if ( ! _anyHooks() )
return o;
if ( _encodingHooks.size() == 0 || o == null )
return o;
List<Transformer> l = _encodingHooks.get( o.getClass() );
if ( l != null )
for ( Transformer t : l )
o = t.transform( o );
return o;
}
public static Object applyDecodingHooks( Object o ){
if ( ! _anyHooks() || o == null )
return o;
List<Transformer> l = _decodingHooks.get( o.getClass() );
if ( l != null )
for ( Transformer t : l )
o = t.transform( o );
return o;
}
/**
* Returns the encoding hook(s) associated with the specified class
*
*/
public static List<Transformer> getEncodingHooks( Class c ){
return _encodingHooks.get( c );
}
/**
* Clears *all* encoding hooks.
*/
public static void clearEncodingHooks(){
_encodeHooks = false;
_encodingHooks.clear();
}
/**
* Remove all encoding hooks for a specific class.
*/
public static void removeEncodingHooks( Class c ){
_encodingHooks.remove( c );
}
/**
* Remove a specific encoding hook for a specific class.
*/
public static void removeEncodingHook( Class c , Transformer t ){
getEncodingHooks( c ).remove( t );
}
/**
* Returns the decoding hook(s) associated with the specific class
*/
public static List<Transformer> getDecodingHooks( Class c ){
return _decodingHooks.get( c );
}
/**
* Clears *all* decoding hooks.
*/
public static void clearDecodingHooks(){
_decodeHooks = false;
_decodingHooks.clear();
}
/**
* Remove all decoding hooks for a specific class.
*/
public static void removeDecodingHooks( Class c ){
_decodingHooks.remove( c );
}
/**
* Remove a specific encoding hook for a specific class.
*/
public static void removeDecodingHook( Class c , Transformer t ){
getDecodingHooks( c ).remove( t );
}
public static void clearAllHooks(){
clearEncodingHooks();
clearDecodingHooks();
}
/**
* Returns true if any encoding or decoding hooks are loaded.
*/
private static boolean _anyHooks(){
return _encodeHooks || _decodeHooks;
}
private static boolean _encodeHooks = false;
private static boolean _decodeHooks = false;
static ClassMap<List<Transformer>> _encodingHooks =
new ClassMap<List<Transformer>>();
static ClassMap<List<Transformer>> _decodingHooks =
new ClassMap<List<Transformer>>();
static protected Charset _utf8 = Charset.forName( "UTF-8" );
// ----- static encode/decode -----
public static byte[] encode( BSONObject o ){
BSONEncoder e = _staticEncoder.get();
try {
return e.encode( o );
}
finally {
e.done();
}
}
public static BSONObject decode( byte[] b ){
BSONDecoder d = _staticDecoder.get();
return d.readObject( b );
}
static ThreadLocal<BSONEncoder> _staticEncoder = new ThreadLocal<BSONEncoder>(){
protected BSONEncoder initialValue(){
return new BasicBSONEncoder();
}
};
static ThreadLocal<BSONDecoder> _staticDecoder = new ThreadLocal<BSONDecoder>(){
protected BSONDecoder initialValue(){
return new BasicBSONDecoder();
}
};
// --- coercing ---
public static int toInt( Object o ){
if ( o == null )
throw new NullPointerException( "can't be null" );
if ( o instanceof Number )
return ((Number)o).intValue();
if ( o instanceof Boolean )
return ((Boolean)o) ? 1 : 0;
throw new IllegalArgumentException( "can't convert: " + o.getClass().getName() + " to int" );
}
}

View File

@ -1,70 +0,0 @@
// BSONCallback.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import com.massivecraft.massivecore.xlib.bson.types.ObjectId;
public interface BSONCallback {
void objectStart();
void objectStart(String name);
void objectStart(boolean array);
Object objectDone();
void reset();
Object get();
BSONCallback createBSONCallback();
void arrayStart();
void arrayStart(String name);
Object arrayDone();
void gotNull( String name );
void gotUndefined( String name );
void gotMinKey( String name );
void gotMaxKey( String name );
void gotBoolean( String name , boolean v );
void gotDouble( String name , double v );
void gotInt( String name , int v );
void gotLong( String name , long v );
void gotDate( String name , long millis );
void gotString( String name , String v );
void gotSymbol( String name , String v );
void gotRegex( String name , String pattern , String flags );
void gotTimestamp( String name , int time , int inc );
void gotObjectId( String name , ObjectId id );
void gotDBRef( String name , String ns , ObjectId id );
/**
*
*/
@Deprecated
void gotBinaryArray( String name , byte[] data );
void gotBinary( String name , byte type , byte[] data );
/**
* subtype 3
*/
void gotUUID( String name , long part1, long part2);
void gotCode( String name , String code );
void gotCodeWScope( String name , String code , Object scope );
}

View File

@ -1,34 +0,0 @@
// BSONDecoder.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import java.io.IOException;
import java.io.InputStream;
public interface BSONDecoder {
public BSONObject readObject( byte[] b );
public BSONObject readObject( InputStream in ) throws IOException;
public int decode( byte[] b , BSONCallback callback );
public int decode( InputStream in , BSONCallback callback ) throws IOException;
}

View File

@ -1,27 +0,0 @@
/**
* Copyright (c) 2008 - 2011 10gen, Inc. <http://10gen.com>
*
* 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 com.massivecraft.massivecore.xlib.bson;
import com.massivecraft.massivecore.xlib.bson.io.*;
public interface BSONEncoder {
public byte[] encode( BSONObject o );
public int putObject( BSONObject o );
public void done();
void set( OutputBuffer out );
}

View File

@ -1,73 +0,0 @@
/**
* Copyright (C) 2011, 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
/**
* A general runtime exception raised in BSON processing.
*/
public class BSONException extends RuntimeException {
private static final long serialVersionUID = -4415279469780082174L;
/**
* @param msg The error message.
*/
public BSONException( final String msg ) {
super( msg );
}
/**
* @param errorCode The error code.
* @param msg The error message.
*/
public BSONException( final int errorCode, final String msg ) {
super( msg );
_errorCode = errorCode;
}
/**
* @param msg The error message.
* @param t The throwable cause.
*/
public BSONException( final String msg , final Throwable t ) {
super( msg, t );
}
/**
* @param errorCode The error code.
* @param msg The error message.
* @param t The throwable cause.
*/
public BSONException( final int errorCode, final String msg, final Throwable t ) {
super( msg, t );
_errorCode = errorCode;
}
/**
* Returns the error code.
* @return The error code.
*/
public Integer getErrorCode() { return _errorCode; }
/**
* Returns true if the error code is set (i.e., not null).
*/
public boolean hasErrorCode() { return (_errorCode != null); }
private Integer _errorCode = null;
}

View File

@ -1,24 +0,0 @@
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
/**
*
* @author antoine
*/
public class BSONLazyDecoder {
}

View File

@ -1,92 +0,0 @@
// BSONObject.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import java.util.Map;
import java.util.Set;
/**
* A key-value map that can be saved to the database.
*/
@SuppressWarnings({"rawtypes"})
public interface BSONObject {
/**
* Sets a name/value pair in this object.
* @param key Name to set
* @param v Corresponding value
* @return <tt>v</tt>
*/
public Object put( String key , Object v );
/**
* Sets all key/value pairs from an object into this object
* @param o the object
*/
public void putAll( BSONObject o );
/**
* Sets all key/value pairs from a map into this object
* @param m the map
*/
public void putAll( Map m );
/**
* Gets a field from this object by a given name.
* @param key The name of the field fetch
* @return The field, if found
*/
public Object get( String key );
/**
* Returns a map representing this BSONObject.
* @return the map
*/
public Map toMap();
/**
* Removes a field with a given name from this object.
* @param key The name of the field to remove
* @return The value removed from this object
*/
public Object removeField( String key );
/**
* Deprecated
* @param s
* @return True if the key is present
* @deprecated
*/
@Deprecated
public boolean containsKey( String s );
/**
* Checks if this object contains a field with the given name.
* @param s Field name for which to check
* @return True if the field is present
*/
public boolean containsField(String s);
/**
* Returns this object's fields' names
* @return The names of the fields in this object
*/
public Set<String> keySet();
}

View File

@ -1,206 +0,0 @@
// BasicBSONCallback.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import java.util.*;
import java.util.regex.Pattern;
import com.massivecraft.massivecore.xlib.bson.types.*;
public class BasicBSONCallback implements BSONCallback {
public BasicBSONCallback(){
reset();
}
public BSONObject create(){
return new BasicBSONObject();
}
protected BSONObject createList() {
return new BasicBSONList();
}
public BSONCallback createBSONCallback(){
return new BasicBSONCallback();
}
public BSONObject create( boolean array , List<String> path ){
if ( array )
return createList();
return create();
}
public void objectStart(){
if ( _stack.size() > 0 )
throw new IllegalStateException( "something is wrong" );
objectStart(false);
}
public void objectStart(boolean array){
_root = create(array, null);
_stack.add( (BSONObject)_root );
}
public void objectStart(String name){
objectStart( false , name );
}
public void objectStart(boolean array, String name){
_nameStack.addLast( name );
final BSONObject o = create( array , _nameStack );
_stack.getLast().put( name , o);
_stack.addLast( o );
}
public Object objectDone(){
final BSONObject o =_stack.removeLast();
if ( _nameStack.size() > 0 )
_nameStack.removeLast();
else if ( _stack.size() > 0 )
throw new IllegalStateException( "something is wrong" );
return !BSON.hasDecodeHooks() ? o : (BSONObject)BSON.applyDecodingHooks(o);
}
public void arrayStart(){
objectStart( true );
}
public void arrayStart(String name){
objectStart( true , name );
}
public Object arrayDone(){
return objectDone();
}
public void gotNull( String name ){
cur().put( name , null );
}
public void gotUndefined( String name ) { }
public void gotMinKey( String name ){
cur().put( name , new MinKey() );
}
public void gotMaxKey( String name ){
cur().put( name , new MaxKey() );
}
public void gotBoolean( String name , boolean v ){
_put( name , v );
}
public void gotDouble( final String name , final double v ){
_put( name , v );
}
public void gotInt( final String name , final int v ){
_put( name , v );
}
public void gotLong( final String name , final long v ){
_put( name , v );
}
public void gotDate( String name , long millis ){
_put( name , new Date( millis ) );
}
public void gotRegex( String name , String pattern , String flags ){
_put( name , Pattern.compile( pattern , BSON.regexFlags( flags ) ) );
}
public void gotString( final String name , final String v ){
_put( name , v );
}
public void gotSymbol( String name , String v ){
_put( name , v );
}
public void gotTimestamp( String name , int time , int inc ){
_put( name , new BSONTimestamp( time , inc ) );
}
public void gotObjectId( String name , ObjectId id ){
_put( name , id );
}
public void gotDBRef( String name , String ns , ObjectId id ){
_put( name , new BasicBSONObject( "$ns" , ns ).append( "$id" , id ) );
}
@Deprecated
public void gotBinaryArray( String name , byte[] data ){
gotBinary( name, BSON.B_GENERAL, data );
}
public void gotBinary( String name , byte type , byte[] data ){
if( type == BSON.B_GENERAL || type == BSON.B_BINARY )
_put( name , data );
else
_put( name , new Binary( type , data ) );
}
public void gotUUID( String name , long part1, long part2){
_put( name , new UUID(part1, part2) );
}
public void gotCode( String name , String code ){
_put( name , new Code( code ) );
}
public void gotCodeWScope( String name , String code , Object scope ){
_put( name , new CodeWScope( code, (BSONObject)scope ) );
}
protected void _put( final String name , final Object o ){
cur().put( name , !BSON.hasDecodeHooks() ? o : BSON.applyDecodingHooks( o ) );
}
protected BSONObject cur(){
return _stack.getLast();
}
protected String curName(){
return (!_nameStack.isEmpty()) ? _nameStack.getLast() : null;
}
public Object get(){
return _root;
}
protected void setRoot(Object o) {
_root = o;
}
protected boolean isStackEmpty() {
return _stack.size() < 1;
}
public void reset(){
_root = null;
_stack.clear();
_nameStack.clear();
}
private Object _root;
private final LinkedList<BSONObject> _stack = new LinkedList<BSONObject>();
private final LinkedList<String> _nameStack = new LinkedList<String>();
}

View File

@ -1,527 +0,0 @@
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import static com.massivecraft.massivecore.xlib.bson.BSON.*;
import java.io.*;
import com.massivecraft.massivecore.xlib.bson.io.PoolOutputBuffer;
import com.massivecraft.massivecore.xlib.bson.types.ObjectId;
/**
* Basic implementation of BSONDecoder interface that creates BasicBSONObject instances
*/
@SuppressWarnings({"unused"})
public class BasicBSONDecoder implements BSONDecoder {
public BSONObject readObject( byte[] b ){
try {
return readObject( new ByteArrayInputStream( b ) );
}
catch ( IOException ioe ){
throw new BSONException( "should be impossible" , ioe );
}
}
public BSONObject readObject( InputStream in )
throws IOException {
BasicBSONCallback c = new BasicBSONCallback();
decode( in , c );
return (BSONObject)c.get();
}
public int decode( byte[] b , BSONCallback callback ){
try {
return _decode( new BSONInput( new ByteArrayInputStream(b) ) , callback );
}
catch ( IOException ioe ){
throw new BSONException( "should be impossible" , ioe );
}
}
public int decode( InputStream in , BSONCallback callback )
throws IOException {
return _decode( new BSONInput( in ) , callback );
}
private int _decode( BSONInput in , BSONCallback callback )
throws IOException {
if ( _in != null || _callback != null )
throw new IllegalStateException( "not ready" );
_in = in;
_callback = callback;
if ( in.numRead() != 0 )
throw new IllegalArgumentException( "i'm confused" );
try {
final int len = _in.readInt();
_in.setMax(len);
_callback.objectStart();
while ( decodeElement() );
_callback.objectDone();
if ( _in.numRead() != len )
throw new IllegalArgumentException( "bad data. lengths don't match read:" + _in.numRead() + " != len:" + len );
return len;
}
finally {
_in = null;
_callback = null;
}
}
int decode( boolean first )
throws IOException {
final int start = _in.numRead();
final int len = _in.readInt();
if ( first )
_in.setMax(len);
_callback.objectStart();
while ( decodeElement() );
_callback.objectDone();
final int read = _in.numRead() - start;
if ( read != len ){
//throw new IllegalArgumentException( "bad data. lengths don't match " + read + " != " + len );
}
return len;
}
boolean decodeElement()
throws IOException {
final byte type = _in.read();
if ( type == EOO )
return false;
String name = _in.readCStr();
switch ( type ){
case NULL:
_callback.gotNull( name );
break;
case UNDEFINED:
_callback.gotUndefined( name );
break;
case BOOLEAN:
_callback.gotBoolean( name , _in.read() > 0 );
break;
case NUMBER:
_callback.gotDouble( name , _in.readDouble() );
break;
case NUMBER_INT:
_callback.gotInt( name , _in.readInt() );
break;
case NUMBER_LONG:
_callback.gotLong( name , _in.readLong() );
break;
case SYMBOL:
_callback.gotSymbol( name , _in.readUTF8String() );
break;
case STRING:
_callback.gotString(name, _in.readUTF8String() );
break;
case OID:
// OID is stored as big endian
_callback.gotObjectId( name , new ObjectId( _in.readIntBE() , _in.readIntBE() , _in.readIntBE() ) );
break;
case REF:
_in.readInt(); // length of ctring that follows
String ns = _in.readCStr();
ObjectId theOID = new ObjectId( _in.readInt() , _in.readInt() , _in.readInt() );
_callback.gotDBRef( name , ns , theOID );
break;
case DATE:
_callback.gotDate( name , _in.readLong() );
break;
case REGEX:
_callback.gotRegex( name , _in.readCStr() , _in.readCStr() );
break;
case BINARY:
_binary( name );
break;
case CODE:
_callback.gotCode( name , _in.readUTF8String() );
break;
case CODE_W_SCOPE:
_in.readInt();
_callback.gotCodeWScope( name , _in.readUTF8String() , _readBasicObject() );
break;
case ARRAY:
_in.readInt(); // total size - we don't care....
_callback.arrayStart( name );
while ( decodeElement() );
_callback.arrayDone();
break;
case OBJECT:
_in.readInt(); // total size - we don't care....
_callback.objectStart( name );
while ( decodeElement() );
_callback.objectDone();
break;
case TIMESTAMP:
int i = _in.readInt();
int time = _in.readInt();
_callback.gotTimestamp( name , time , i );
break;
case MINKEY:
_callback.gotMinKey( name );
break;
case MAXKEY:
_callback.gotMaxKey( name );
break;
default:
throw new UnsupportedOperationException( "BSONDecoder doesn't understand type : " + type + " name: " + name );
}
return true;
}
protected void _binary( final String name )
throws IOException {
final int totalLen = _in.readInt();
final byte bType = _in.read();
switch ( bType ){
case B_GENERAL: {
final byte[] data = new byte[totalLen];
_in.fill( data );
_callback.gotBinary( name, bType, data );
return;
}
case B_BINARY:
final int len = _in.readInt();
if ( len + 4 != totalLen )
throw new IllegalArgumentException( "bad data size subtype 2 len: " + len + " totalLen: " + totalLen );
final byte [] data = new byte[len];
_in.fill( data );
_callback.gotBinary( name , bType , data );
return;
case B_UUID:
if ( totalLen != 16 )
throw new IllegalArgumentException( "bad data size subtype 3 len: " + totalLen + " != 16");
final long part1 = _in.readLong();
final long part2 = _in.readLong();
_callback.gotUUID(name, part1, part2);
return;
}
final byte [] data = new byte[totalLen];
_in.fill( data );
_callback.gotBinary( name , bType , data );
}
Object _readBasicObject()
throws IOException {
_in.readInt();
final BSONCallback save = _callback;
final BSONCallback _basic = _callback.createBSONCallback();
_callback = _basic;
_basic.reset();
_basic.objectStart(false);
while( decodeElement() );
_callback = save;
return _basic.get();
}
protected class BSONInput {
public BSONInput(final InputStream in){
_raw = in;
_read = 0;
_pos = 0;
_len = 0;
}
/**
* ensure that there are num bytes to read
* _pos is where to start reading from
* @return where to start reading from
*/
protected int _need( final int num )
throws IOException {
//System.out.println( "p: " + _pos + " l: " + _len + " want: " + num );
if ( _len - _pos >= num ){
final int ret = _pos;
_pos += num;
_read += num;
return ret;
}
if ( num >= _inputBuffer.length )
throw new IllegalArgumentException( "you can't need that much" );
final int remaining = _len - _pos;
if ( _pos > 0 ){
System.arraycopy( _inputBuffer , _pos , _inputBuffer , 0 , remaining );
_pos = 0;
_len = remaining;
}
// read as much as possible into buffer
int maxToRead = Math.min( _max - _read - remaining , _inputBuffer.length - _len );
while ( maxToRead > 0 ){
int x = _raw.read( _inputBuffer , _len , maxToRead);
if ( x <= 0 )
throw new IOException( "unexpected EOF" );
maxToRead -= x;
_len += x;
}
int ret = _pos;
_pos += num;
_read += num;
return ret;
}
public int readInt()
throws IOException {
return com.massivecraft.massivecore.xlib.bson.io.Bits.readInt( _inputBuffer , _need(4) );
}
public int readIntBE()
throws IOException {
return com.massivecraft.massivecore.xlib.bson.io.Bits.readIntBE( _inputBuffer , _need(4) );
}
public long readLong()
throws IOException {
return com.massivecraft.massivecore.xlib.bson.io.Bits.readLong( _inputBuffer , _need(8) );
}
public double readDouble()
throws IOException {
return Double.longBitsToDouble( readLong() );
}
public byte read()
throws IOException {
if ( _pos < _len ){
++_read;
return _inputBuffer[_pos++];
}
return _inputBuffer[_need(1)];
}
public void fill( byte b[] )
throws IOException {
fill( b , b.length );
}
public void fill( byte b[] , int len )
throws IOException {
// first use what we have
final int have = _len - _pos;
final int tocopy = Math.min( len , have );
System.arraycopy( _inputBuffer , _pos , b , 0 , tocopy );
_pos += tocopy;
_read += tocopy;
len -= tocopy;
int off = tocopy;
while ( len > 0 ){
final int x = _raw.read( b , off , len );
if (x <= 0)
throw new IOException( "unexpected EOF" );
_read += x;
off += x;
len -= x;
}
}
protected boolean _isAscii( byte b ){
return b >=0 && b <= 127;
}
public String readCStr() throws IOException {
boolean isAscii = true;
// short circuit 1 byte strings
_random[0] = read();
if (_random[0] == 0) {
return "";
}
_random[1] = read();
if (_random[1] == 0) {
final String out = ONE_BYTE_STRINGS[_random[0]];
return (out != null) ? out : new String(_random, 0, 1, DEFAULT_ENCODING);
}
_stringBuffer.reset();
_stringBuffer.write(_random, 0, 2);
isAscii = _isAscii(_random[0]) && _isAscii(_random[1]);
byte b;
while ((b = read()) != 0) {
_stringBuffer.write( b );
isAscii = isAscii && _isAscii( b );
}
String out = null;
if ( isAscii ){
out = _stringBuffer.asAscii();
}
else {
try {
out = _stringBuffer.asString( DEFAULT_ENCODING );
}
catch ( UnsupportedOperationException e ){
throw new BSONException( "impossible" , e );
}
}
_stringBuffer.reset();
return out;
}
public String readUTF8String()
throws IOException {
final int size = readInt();
// this is just protection in case it's corrupted, to avoid huge strings
if ( size <= 0 || size > MAX_STRING )
throw new BSONException( "bad string size: " + size );
if ( size < _inputBuffer.length / 2 ){
if ( size == 1 ){
read();
return "";
}
return new String( _inputBuffer , _need(size) , size - 1 , DEFAULT_ENCODING );
}
final byte [] b = size < _random.length ? _random : new byte[size];
fill( b , size );
try {
return new String( b , 0 , size - 1 , DEFAULT_ENCODING );
}
catch ( java.io.UnsupportedEncodingException uee ){
throw new BSONException( "impossible" , uee );
}
}
public int numRead() {
return _read;
}
public int getPos() {
return _pos;
}
public int getMax() {
return _max;
}
public void setMax(int _max) {
this._max = _max;
}
int _read;
final InputStream _raw;
int _max = 4; // max number of total bytes allowed to ready
}
protected BSONInput _in;
protected BSONCallback _callback;
private byte [] _random = new byte[1024]; // has to be used within a single function
private byte [] _inputBuffer = new byte[1024];
private PoolOutputBuffer _stringBuffer = new PoolOutputBuffer();
protected int _pos; // current offset into _inputBuffer
protected int _len; // length of valid data in _inputBuffer
private static final int MAX_STRING = ( 32 * 1024 * 1024 );
private static final String DEFAULT_ENCODING = "UTF-8";
private static final boolean _isAscii( final byte b ){
return b >=0 && b <= 127;
}
static final String[] ONE_BYTE_STRINGS = new String[128];
static void _fillRange( byte min, byte max ){
while ( min < max ){
String s = "";
s += (char)min;
ONE_BYTE_STRINGS[(int)min] = s;
min++;
}
}
static {
_fillRange( (byte)'0' , (byte)'9' );
_fillRange( (byte)'a' , (byte)'z' );
_fillRange( (byte)'A' , (byte)'Z' );
}
}

View File

@ -1,524 +0,0 @@
// BSONEncoder.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import static com.massivecraft.massivecore.xlib.bson.BSON.ARRAY;
import static com.massivecraft.massivecore.xlib.bson.BSON.BINARY;
import static com.massivecraft.massivecore.xlib.bson.BSON.BOOLEAN;
import static com.massivecraft.massivecore.xlib.bson.BSON.B_BINARY;
import static com.massivecraft.massivecore.xlib.bson.BSON.B_GENERAL;
import static com.massivecraft.massivecore.xlib.bson.BSON.B_UUID;
import static com.massivecraft.massivecore.xlib.bson.BSON.CODE;
import static com.massivecraft.massivecore.xlib.bson.BSON.CODE_W_SCOPE;
import static com.massivecraft.massivecore.xlib.bson.BSON.DATE;
import static com.massivecraft.massivecore.xlib.bson.BSON.EOO;
import static com.massivecraft.massivecore.xlib.bson.BSON.MAXKEY;
import static com.massivecraft.massivecore.xlib.bson.BSON.MINKEY;
import static com.massivecraft.massivecore.xlib.bson.BSON.NULL;
import static com.massivecraft.massivecore.xlib.bson.BSON.NUMBER;
import static com.massivecraft.massivecore.xlib.bson.BSON.NUMBER_INT;
import static com.massivecraft.massivecore.xlib.bson.BSON.NUMBER_LONG;
import static com.massivecraft.massivecore.xlib.bson.BSON.OBJECT;
import static com.massivecraft.massivecore.xlib.bson.BSON.OID;
import static com.massivecraft.massivecore.xlib.bson.BSON.REGEX;
import static com.massivecraft.massivecore.xlib.bson.BSON.STRING;
import static com.massivecraft.massivecore.xlib.bson.BSON.SYMBOL;
import static com.massivecraft.massivecore.xlib.bson.BSON.TIMESTAMP;
import static com.massivecraft.massivecore.xlib.bson.BSON.UNDEFINED;
import static com.massivecraft.massivecore.xlib.bson.BSON.regexFlags;
import java.lang.reflect.Array;
import java.nio.Buffer;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;
import com.massivecraft.massivecore.xlib.bson.io.BasicOutputBuffer;
import com.massivecraft.massivecore.xlib.bson.io.OutputBuffer;
import com.massivecraft.massivecore.xlib.bson.types.BSONTimestamp;
import com.massivecraft.massivecore.xlib.bson.types.Binary;
import com.massivecraft.massivecore.xlib.bson.types.Code;
import com.massivecraft.massivecore.xlib.bson.types.CodeWScope;
import com.massivecraft.massivecore.xlib.bson.types.MaxKey;
import com.massivecraft.massivecore.xlib.bson.types.MinKey;
import com.massivecraft.massivecore.xlib.bson.types.ObjectId;
import com.massivecraft.massivecore.xlib.bson.types.Symbol;
import com.massivecraft.massivecore.xlib.mongodb.DBRefBase;
/**
* this is meant to be pooled or cached
* there is some per instance memory for string conversion, etc...
*/
@SuppressWarnings({"unchecked", "rawtypes", "unused"})
public class BasicBSONEncoder implements BSONEncoder {
static final boolean DEBUG = false;
public BasicBSONEncoder(){
}
public byte[] encode( BSONObject o ){
BasicOutputBuffer buf = new BasicOutputBuffer();
set( buf );
putObject( o );
done();
return buf.toByteArray();
}
public void set( OutputBuffer out ){
if ( _buf != null )
throw new IllegalStateException( "in the middle of something" );
_buf = out;
}
public void done(){
_buf = null;
}
/**
* @return true if object was handled
*/
protected boolean handleSpecialObjects( String name , BSONObject o ){
return false;
}
protected boolean putSpecial( String name , Object o ){
return false;
}
/** Encodes a <code>BSONObject</code>.
* This is for the higher level api calls
* @param o the object to encode
* @return the number of characters in the encoding
*/
public int putObject( BSONObject o ){
return putObject( null , o );
}
/**
* this is really for embedded objects
*/
protected int putObject( String name , BSONObject o ){
if ( o == null )
throw new NullPointerException( "can't save a null object" );
if ( DEBUG ) System.out.println( "putObject : " + name + " [" + o.getClass() + "]" + " # keys " + o.keySet().size() );
final int start = _buf.getPosition();
byte myType = OBJECT;
if ( o instanceof List )
myType = ARRAY;
if ( handleSpecialObjects( name , o ) )
return _buf.getPosition() - start;
if ( name != null ){
_put( myType , name );
}
final int sizePos = _buf.getPosition();
_buf.writeInt( 0 ); // leaving space for this. set it at the end
List transientFields = null;
boolean rewriteID = myType == OBJECT && name == null;
if ( myType == OBJECT ) {
if ( rewriteID && o.containsField( "_id" ) )
_putObjectField( "_id" , o.get( "_id" ) );
{
Object temp = o.get( "_transientFields" );
if ( temp instanceof List )
transientFields = (List)temp;
}
}
//TODO: reduce repeated code below.
if ( o instanceof Map ){
for ( Entry<String, Object> e : ((Map<String, Object>)o).entrySet() ){
if ( rewriteID && e.getKey().equals( "_id" ) )
continue;
if ( transientFields != null && transientFields.contains( e.getKey() ) )
continue;
_putObjectField( e.getKey() , e.getValue() );
}
} else {
for ( String s : o.keySet() ){
if ( rewriteID && s.equals( "_id" ) )
continue;
if ( transientFields != null && transientFields.contains( s ) )
continue;
Object val = o.get( s );
_putObjectField( s , val );
}
}
_buf.write( EOO );
_buf.writeInt( sizePos , _buf.getPosition() - sizePos );
return _buf.getPosition() - start;
}
protected void _putObjectField( String name , Object val ){
if ( name.equals( "_transientFields" ) )
return;
if ( DEBUG ) System.out.println( "\t put thing : " + name );
if ( name.equals( "$where") && val instanceof String ){
_put( CODE , name );
_putValueString( val.toString() );
return;
}
val = BSON.applyEncodingHooks( val );
if ( val == null )
putNull(name);
else if ( val instanceof Date )
putDate( name , (Date)val );
else if ( val instanceof Number )
putNumber(name, (Number)val );
else if ( val instanceof Character )
putString(name, val.toString() );
else if ( val instanceof String )
putString(name, val.toString() );
else if ( val instanceof ObjectId )
putObjectId(name, (ObjectId)val );
else if ( val instanceof BSONObject )
putObject(name, (BSONObject)val );
else if ( val instanceof Boolean )
putBoolean(name, (Boolean)val );
else if ( val instanceof Pattern )
putPattern(name, (Pattern)val );
else if ( val instanceof Map )
putMap( name , (Map)val );
else if ( val instanceof Iterable)
putIterable( name , (Iterable)val );
else if ( val instanceof byte[] )
putBinary( name , (byte[])val );
else if ( val instanceof Binary )
putBinary( name , (Binary)val );
else if ( val instanceof UUID )
putUUID( name , (UUID)val );
else if ( val.getClass().isArray() )
putArray( name , val );
else if (val instanceof Symbol) {
putSymbol(name, (Symbol) val);
}
else if (val instanceof BSONTimestamp) {
putTimestamp( name , (BSONTimestamp)val );
}
else if (val instanceof CodeWScope) {
putCodeWScope( name , (CodeWScope)val );
}
else if (val instanceof Code) {
putCode( name , (Code)val );
}
else if (val instanceof DBRefBase) {
BSONObject temp = new BasicBSONObject();
temp.put("$ref", ((DBRefBase)val).getRef());
temp.put("$id", ((DBRefBase)val).getId());
putObject( name, temp );
}
else if ( val instanceof MinKey )
putMinKey( name );
else if ( val instanceof MaxKey )
putMaxKey( name );
else if ( putSpecial( name , val ) ){
// no-op
}
else {
throw new IllegalArgumentException( "can't serialize " + val.getClass() );
}
}
private void putArray( String name , Object array ) {
_put( ARRAY , name );
final int sizePos = _buf.getPosition();
_buf.writeInt( 0 );
int size = Array.getLength(array);
for ( int i = 0; i < size; i++ )
_putObjectField( String.valueOf( i ) , Array.get( array, i ) );
_buf.write( EOO );
_buf.writeInt( sizePos , _buf.getPosition() - sizePos );
}
private void putIterable( String name , Iterable l ){
_put( ARRAY , name );
final int sizePos = _buf.getPosition();
_buf.writeInt( 0 );
int i=0;
for ( Object obj: l ) {
_putObjectField( String.valueOf( i ) , obj );
i++;
}
_buf.write( EOO );
_buf.writeInt( sizePos , _buf.getPosition() - sizePos );
}
private void putMap( String name , Map m ){
_put( OBJECT , name );
final int sizePos = _buf.getPosition();
_buf.writeInt( 0 );
for ( Map.Entry entry : (Set<Map.Entry>)m.entrySet() )
_putObjectField( entry.getKey().toString() , entry.getValue() );
_buf.write( EOO );
_buf.writeInt( sizePos , _buf.getPosition() - sizePos );
}
protected void putNull( String name ){
_put( NULL , name );
}
protected void putUndefined(String name){
_put(UNDEFINED, name);
}
protected void putTimestamp(String name, BSONTimestamp ts ){
_put( TIMESTAMP , name );
_buf.writeInt( ts.getInc() );
_buf.writeInt( ts.getTime() );
}
protected void putCodeWScope( String name , CodeWScope code ){
_put( CODE_W_SCOPE , name );
int temp = _buf.getPosition();
_buf.writeInt( 0 );
_putValueString( code.getCode() );
putObject( code.getScope() );
_buf.writeInt( temp , _buf.getPosition() - temp );
}
protected void putCode( String name , Code code ){
_put( CODE , name );
int temp = _buf.getPosition();
_putValueString( code.getCode() );
}
protected void putBoolean( String name , Boolean b ){
_put( BOOLEAN , name );
_buf.write( b ? (byte)0x1 : (byte)0x0 );
}
protected void putDate( String name , Date d ){
_put( DATE , name );
_buf.writeLong( d.getTime() );
}
protected void putNumber( String name , Number n ){
if ( n instanceof Integer ||
n instanceof Short ||
n instanceof Byte ||
n instanceof AtomicInteger ){
_put( NUMBER_INT , name );
_buf.writeInt( n.intValue() );
}
else if ( n instanceof Long || n instanceof AtomicLong ) {
_put( NUMBER_LONG , name );
_buf.writeLong( n.longValue() );
}
else if ( n instanceof Float || n instanceof Double ) {
_put( NUMBER , name );
_buf.writeDouble( n.doubleValue() );
}
else {
throw new IllegalArgumentException( "can't serialize " + n.getClass() );
}
}
protected void putBinary( String name , byte[] data ){
putBinary( name, B_GENERAL, data );
}
protected void putBinary( String name , Binary val ){
putBinary( name, val.getType(), val.getData() );
}
private void putBinary( String name , int type , byte[] data ){
_put( BINARY , name );
int totalLen = data.length;
if (type == B_BINARY)
totalLen += 4;
_buf.writeInt( totalLen );
_buf.write( type );
if (type == B_BINARY)
_buf.writeInt( totalLen -4 );
int before = _buf.getPosition();
_buf.write( data );
int after = _buf.getPosition();
com.massivecraft.massivecore.xlib.mongodb.util.MyAsserts.assertEquals( after - before , data.length );
}
protected void putUUID( String name , UUID val ){
_put( BINARY , name );
_buf.writeInt( 16 );
_buf.write( B_UUID );
_buf.writeLong( val.getMostSignificantBits());
_buf.writeLong( val.getLeastSignificantBits());
}
protected void putSymbol( String name , Symbol s ){
_putString(name, s.getSymbol(), SYMBOL);
}
protected void putString(String name, String s) {
_putString(name, s, STRING);
}
private void _putString( String name , String s, byte type ){
_put( type , name );
_putValueString( s );
}
protected void putObjectId( String name , ObjectId oid ){
_put( OID , name );
// according to spec, values should be stored big endian
_buf.writeIntBE( oid._time() );
_buf.writeIntBE( oid._machine() );
_buf.writeIntBE( oid._inc() );
}
private void putPattern( String name, Pattern p ) {
_put( REGEX , name );
_put( p.pattern() );
_put( regexFlags( p.flags() ) );
}
private void putMinKey( String name ) {
_put( MINKEY , name );
}
private void putMaxKey( String name ) {
_put( MAXKEY , name );
}
// ----------------------------------------------
/**
* Encodes the type and key.
*
*/
protected void _put( byte type , String name ){
_buf.write( type );
_put( name );
}
protected void _putValueString( String s ){
int lenPos = _buf.getPosition();
_buf.writeInt( 0 ); // making space for size
int strLen = _put( s );
_buf.writeInt( lenPos , strLen );
}
void _reset( Buffer b ){
b.position(0);
b.limit( b.capacity() );
}
/**
* puts as utf-8 string
*/
protected int _put( String str ){
final int len = str.length();
int total = 0;
for ( int i=0; i<len; ){
int c = Character.codePointAt( str , i );
if ( c < 0x80 ){
_buf.write( (byte)c );
total += 1;
}
else if ( c < 0x800 ){
_buf.write( (byte)(0xc0 + (c >> 6) ) );
_buf.write( (byte)(0x80 + (c & 0x3f) ) );
total += 2;
}
else if (c < 0x10000){
_buf.write( (byte)(0xe0 + (c >> 12) ) );
_buf.write( (byte)(0x80 + ((c >> 6) & 0x3f) ) );
_buf.write( (byte)(0x80 + (c & 0x3f) ) );
total += 3;
}
else {
_buf.write( (byte)(0xf0 + (c >> 18)) );
_buf.write( (byte)(0x80 + ((c >> 12) & 0x3f)) );
_buf.write( (byte)(0x80 + ((c >> 6) & 0x3f)) );
_buf.write( (byte)(0x80 + (c & 0x3f)) );
total += 4;
}
i += Character.charCount(c);
}
_buf.write( (byte)0 );
total++;
return total;
}
public void writeInt( int x ){
_buf.writeInt( x );
}
public void writeLong( long x ){
_buf.writeLong( x );
}
public void writeCString( String s ){
_put( s );
}
protected OutputBuffer _buf;
}

View File

@ -1,354 +0,0 @@
// BasicBSONObject.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
// BSON
import com.massivecraft.massivecore.xlib.bson.types.ObjectId;
// Java
import java.util.Map;
import java.util.Set;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.regex.Pattern;
/**
* A simple implementation of <code>DBObject</code>.
* A <code>DBObject</code> can be created as follows, using this class:
* <blockquote><pre>
* DBObject obj = new BasicBSONObject();
* obj.put( "foo", "bar" );
* </pre></blockquote>
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class BasicBSONObject extends LinkedHashMap<String,Object> implements BSONObject {
private static final long serialVersionUID = -4415279469780082174L;
/**
* Creates an empty object.
*/
public BasicBSONObject(){
}
public BasicBSONObject(int size){
super(size);
}
/**
* Convenience CTOR
* @param key key under which to store
* @param value value to stor
*/
public BasicBSONObject(String key, Object value){
put(key, value);
}
/**
* Creates a DBObject from a map.
* @param m map to convert
*/
public BasicBSONObject(Map m) {
super(m);
}
/**
* Converts a DBObject to a map.
* @return the DBObject
*/
public Map toMap() {
return new LinkedHashMap<String,Object>(this);
}
/** Deletes a field from this object.
* @param key the field name to remove
* @return the object removed
*/
public Object removeField( String key ){
return remove( key );
}
/** Checks if this object contains a given field
* @param field field name
* @return if the field exists
*/
public boolean containsField( String field ){
return super.containsKey(field);
}
/**
* @deprecated
*/
@Deprecated
public boolean containsKey( String key ){
return containsField(key);
}
/** Gets a value from this object
* @param key field name
* @return the value
*/
public Object get( String key ){
return super.get(key);
}
/** Returns the value of a field as an <code>int</code>.
* @param key the field to look for
* @return the field value (or default)
*/
public int getInt( String key ){
Object o = get(key);
if ( o == null )
throw new NullPointerException( "no value for: " + key );
return BSON.toInt( o );
}
/** Returns the value of a field as an <code>int</code>.
* @param key the field to look for
* @param def the default to return
* @return the field value (or default)
*/
public int getInt( String key , int def ){
Object foo = get( key );
if ( foo == null )
return def;
return BSON.toInt( foo );
}
/**
* Returns the value of a field as a <code>long</code>.
*
* @param key the field to return
* @return the field value
*/
public long getLong( String key){
Object foo = get( key );
return ((Number)foo).longValue();
}
/**
* Returns the value of a field as an <code>long</code>.
* @param key the field to look for
* @param def the default to return
* @return the field value (or default)
*/
public long getLong( String key , long def ) {
Object foo = get( key );
if ( foo == null )
return def;
return ((Number)foo).longValue();
}
/**
* Returns the value of a field as a <code>double</code>.
*
* @param key the field to return
* @return the field value
*/
public double getDouble( String key){
Object foo = get( key );
return ((Number)foo).doubleValue();
}
/**
* Returns the value of a field as an <code>double</code>.
* @param key the field to look for
* @param def the default to return
* @return the field value (or default)
*/
public double getDouble( String key , double def ) {
Object foo = get( key );
if ( foo == null )
return def;
return ((Number)foo).doubleValue();
}
/** Returns the value of a field as a string
* @param key the field to look up
* @return the value of the field, converted to a string
*/
public String getString( String key ){
Object foo = get( key );
if ( foo == null )
return null;
return foo.toString();
}
/**
* Returns the value of a field as a string
* @param key the field to look up
* @param def the default to return
* @return the value of the field, converted to a string
*/
public String getString( String key, final String def ) {
Object foo = get( key );
if ( foo == null )
return def;
return foo.toString();
}
/** Returns the value of a field as a boolean.
* @param key the field to look up
* @return the value of the field, or false if field does not exist
*/
public boolean getBoolean( String key ){
return getBoolean(key, false);
}
/** Returns the value of a field as a boolean
* @param key the field to look up
* @param def the default value in case the field is not found
* @return the value of the field, converted to a string
*/
public boolean getBoolean( String key , boolean def ){
Object foo = get( key );
if ( foo == null )
return def;
if ( foo instanceof Number )
return ((Number)foo).intValue() > 0;
if ( foo instanceof Boolean )
return ((Boolean)foo).booleanValue();
throw new IllegalArgumentException( "can't coerce to bool:" + foo.getClass() );
}
/**
* Returns the object id or null if not set.
* @param field The field to return
* @return The field object value or null if not found (or if null :-^).
*/
public ObjectId getObjectId( final String field ) {
return (ObjectId) get( field );
}
/**
* Returns the object id or def if not set.
* @param field The field to return
* @param def the default value in case the field is not found
* @return The field object value or def if not set.
*/
public ObjectId getObjectId( final String field, final ObjectId def ) {
final Object foo = get( field );
return (foo != null) ? (ObjectId)foo : def;
}
/**
* Returns the date or null if not set.
* @param field The field to return
* @return The field object value or null if not found.
*/
public Date getDate( final String field ) {
return (Date) get( field );
}
/**
* Returns the date or def if not set.
* @param field The field to return
* @param def the default value in case the field is not found
* @return The field object value or def if not set.
*/
public Date getDate( final String field, final Date def ) {
final Object foo = get( field );
return (foo != null) ? (Date)foo : def;
}
/** Add a key/value pair to this object
* @param key the field name
* @param val the field value
* @return the <code>val</code> parameter
*/
public Object put( String key , Object val ){
return super.put( key , val );
}
public void putAll( Map m ){
for ( Map.Entry entry : (Set<Map.Entry>)m.entrySet() ){
put( entry.getKey().toString() , entry.getValue() );
}
}
public void putAll( BSONObject o ){
for ( String k : o.keySet() ){
put( k , o.get( k ) );
}
}
/** Add a key/value pair to this object
* @param key the field name
* @param val the field value
* @return <code>this</code>
*/
public BasicBSONObject append( String key , Object val ){
put( key , val );
return this;
}
/** Returns a JSON serialization of this object
* @return JSON serialization
*/
public String toString(){
return com.massivecraft.massivecore.xlib.mongodb.util.JSON.serialize( this );
}
public boolean equals( Object o ){
if ( ! ( o instanceof BSONObject ) )
return false;
BSONObject other = (BSONObject)o;
if ( ! keySet().equals( other.keySet() ) )
return false;
for ( String key : keySet() ){
Object a = get( key );
Object b = other.get( key );
if ( a == null ){
if ( b != null )
return false;
}
if ( b == null ){
if ( a != null )
return false;
}
else if ( a instanceof Number && b instanceof Number ){
if ( ((Number)a).doubleValue() !=
((Number)b).doubleValue() )
return false;
}
else if ( a instanceof Pattern && b instanceof Pattern ){
Pattern p1 = (Pattern) a;
Pattern p2 = (Pattern) b;
if (!p1.pattern().equals(p2.pattern()) || p1.flags() != p2.flags())
return false;
}
else {
if ( ! a.equals( b ) )
return false;
}
}
return true;
}
}

View File

@ -1,143 +0,0 @@
/**
* Copyright (C) 2011 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import com.massivecraft.massivecore.xlib.bson.types.ObjectId;
public class EmptyBSONCallback implements BSONCallback {
public void objectStart(){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void objectStart( String name ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void objectStart( boolean array ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public Object objectDone(){
throw new UnsupportedOperationException( "Not supported yet." );
}
public BSONCallback createBSONCallback(){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void arrayStart(){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void arrayStart( String name ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public Object arrayDone(){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotNull( String name ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotUndefined( String name ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotMinKey( String name ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotMaxKey( String name ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotBoolean( String name , boolean v ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotDouble( String name , double v ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotInt( String name , int v ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotLong( String name , long v ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotDate( String name , long millis ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotString( String name , String v ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotSymbol( String name , String v ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotRegex( String name , String pattern , String flags ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotTimestamp( String name , int time , int inc ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotObjectId( String name , ObjectId id ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotDBRef( String name , String ns , ObjectId id ){
throw new UnsupportedOperationException( "Not supported yet." );
}
@Deprecated
public void gotBinaryArray( String name , byte[] data ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotUUID( String name , long part1 , long part2 ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotCode( String name , String code ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotCodeWScope( String name , String code , Object scope ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void reset(){
throw new UnsupportedOperationException( "Not supported yet." );
}
public Object get(){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void gotBinary( String name , byte type , byte[] data ){
throw new UnsupportedOperationException( "Not supported yet." );
}
}

View File

@ -1,70 +0,0 @@
/**
* Copyright (C) 2011 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import java.util.HashMap;
import com.massivecraft.massivecore.xlib.bson.io.BSONByteBuffer;
/**
* @author brendan
* @author scotthernandez
*/
public class KeyCachingLazyBSONObject extends LazyBSONObject {
public KeyCachingLazyBSONObject(byte[] data , LazyBSONCallback cbk) { super( data , cbk ); }
public KeyCachingLazyBSONObject(byte[] data , int offset , LazyBSONCallback cbk) { super( data , offset , cbk ); }
public KeyCachingLazyBSONObject( BSONByteBuffer buffer, LazyBSONCallback callback ){ super( buffer, callback ); }
public KeyCachingLazyBSONObject( BSONByteBuffer buffer, int offset, LazyBSONCallback callback ){ super( buffer, offset, callback ); }
@Override
public Object get( String key ) {
ensureFieldList();
return super.get( key );
}
@Override
public boolean containsField( String s ) {
ensureFieldList();
if (! fieldIndex.containsKey( s ) )
return false;
else
return super.containsField( s );
}
synchronized private void ensureFieldList() {
//only run once
if (fieldIndex == null) return;
try {
int offset = _doc_start_offset + FIRST_ELMT_OFFSET;
while ( !isElementEmpty( offset ) ){
int fieldSize = sizeCString( offset );
int elementSize = getElementBSONSize( offset++ );
String name = _input.getCString( offset );
ElementRecord _t_record = new ElementRecord( name, offset );
fieldIndex.put( name, _t_record );
offset += ( fieldSize + elementSize );
}
} catch (Exception e) {
fieldIndex = new HashMap<String, ElementRecord>();
}
}
private HashMap<String, ElementRecord> fieldIndex = new HashMap<String, ElementRecord>();
}

View File

@ -1,87 +0,0 @@
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import java.util.List;
import java.util.logging.Logger;
import com.massivecraft.massivecore.xlib.bson.types.ObjectId;
import com.massivecraft.massivecore.xlib.mongodb.LazyDBObject;
/**
*
*/
@SuppressWarnings({"rawtypes", "unused"})
public class LazyBSONCallback extends EmptyBSONCallback {
public void objectStart(){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void objectStart( String name ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void objectStart( boolean array ){
throw new UnsupportedOperationException( "Not supported yet." );
}
public Object objectDone(){
throw new UnsupportedOperationException( "Not supported yet." );
}
public void reset(){
_root = null;
}
public Object get(){
return _root;
}
public void gotBinary( String name, byte type, byte[] data ){
setRootObject( createObject( data, 0 ) );
}
public void setRootObject( Object root ){
_root = root;
}
public Object createObject( byte[] data, int offset ){
return new LazyDBObject( data, offset, this );
}
public List createArray( byte[] data, int offset ){
return new LazyDBList( data, offset, this );
}
public Object createDBRef( String ns, ObjectId id ){
return new BasicBSONObject( "$ns", ns ).append( "$id", id );
}
/* public Object createObject(InputStream input, int offset) {
try {
return new LazyBSONObject(input, offset, this);
}
catch ( IOException e ) {
e.printStackTrace();
return null;
}
}*/
private Object _root;
private static final Logger log = Logger.getLogger( "org.bson.LazyBSONCallback" );
}

View File

@ -1,70 +0,0 @@
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import com.massivecraft.massivecore.xlib.bson.io.Bits;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;
/**
* implementation of BSONDecoder that creates LazyBSONObject instances
*/
public class LazyBSONDecoder implements BSONDecoder {
static final Logger LOG = Logger.getLogger( LazyBSONDecoder.class.getName() );
public BSONObject readObject(byte[] b) {
try {
return readObject( new ByteArrayInputStream( b ) );
}
catch ( IOException ioe ){
throw new BSONException( "should be impossible" , ioe );
}
}
public BSONObject readObject(InputStream in) throws IOException {
BSONCallback c = new LazyBSONCallback();
decode( in , c );
return (BSONObject)c.get();
}
public int decode(byte[] b, BSONCallback callback) {
try {
return decode( new ByteArrayInputStream( b ), callback );
}
catch ( IOException ioe ) {
throw new BSONException( "should be impossible" , ioe );
}
}
public int decode(InputStream in, BSONCallback callback) throws IOException {
byte[] objSizeBuffer = new byte[BYTES_IN_INTEGER];
Bits.readFully(in, objSizeBuffer, 0, BYTES_IN_INTEGER);
int objSize = Bits.readInt(objSizeBuffer);
byte[] data = new byte[objSize];
System.arraycopy(objSizeBuffer, 0, data, 0, BYTES_IN_INTEGER);
Bits.readFully(in, data, BYTES_IN_INTEGER, objSize - BYTES_IN_INTEGER);
// note that we are handing off ownership of the data byte array to the callback
callback.gotBinary(null, (byte) 0, data);
return objSize;
}
private static int BYTES_IN_INTEGER = 4;
}

View File

@ -1,177 +0,0 @@
package com.massivecraft.massivecore.xlib.bson;
import com.massivecraft.massivecore.xlib.bson.io.BSONByteBuffer;
import java.util.*;
@SuppressWarnings( "rawtypes" )
public class LazyBSONList extends LazyBSONObject implements List {
public LazyBSONList(byte[] data , LazyBSONCallback callback) { super( data , callback ); }
public LazyBSONList(byte[] data , int offset , LazyBSONCallback callback) { super( data , offset , callback ); }
public LazyBSONList(BSONByteBuffer buffer , LazyBSONCallback callback) { super( buffer , callback ); }
public LazyBSONList(BSONByteBuffer buffer , int offset , LazyBSONCallback callback) { super( buffer , offset , callback ); }
@Override
public boolean contains( Object arg0 ){
return indexOf(arg0) > -1;
}
@Override
public boolean containsAll( Collection arg0 ){
for ( Object obj : arg0 ) {
if ( !contains( obj ) )
return false;
}
return true;
}
@Override
public Object get( int pos ){
return get("" + pos);
}
@Override
public Iterator iterator(){
return new LazyBSONListIterator();
}
@Override
public int indexOf( Object arg0 ){
int pos = 0;
Iterator it = iterator();
while ( it.hasNext() ) {
Object curr = it.next();
if ( arg0.equals( curr ) )
return pos;
pos++;
}
return -1;
}
@Override
public int lastIndexOf( Object arg0 ){
int pos = 0;
int lastFound = -1;
Iterator it = iterator();
while(it.hasNext()) {
Object curr = it.next();
if(arg0.equals( curr ))
lastFound = pos;
pos++;
}
return lastFound;
}
@Override
public int size(){
//TODO check the last one and get the key/field name to see the ordinal position in case the array is stored with missing elements.
return getElements().size();
}
public class LazyBSONListIterator implements Iterator {
List<ElementRecord> elements;
int pos=0;
public LazyBSONListIterator() {
elements = getElements();
}
@Override
public boolean hasNext(){
return pos < elements.size();
}
@Override
public Object next(){
return getElementValue(elements.get(pos++));
}
@Override
public void remove(){
throw new UnsupportedOperationException( "Read Only" );
}
}
@Override
public ListIterator listIterator( int arg0 ){
throw new UnsupportedOperationException( "Not Supported" );
}
@Override
public ListIterator listIterator(){
throw new UnsupportedOperationException( "Not Supported" );
}
@Override
public boolean add( Object arg0 ){
throw new UnsupportedOperationException( "Read Only" );
}
@Override
public void add( int arg0 , Object arg1 ){
throw new UnsupportedOperationException( "Read Only" );
}
@Override
public boolean addAll( Collection arg0 ){
throw new UnsupportedOperationException( "Read Only" );
}
@Override
public boolean addAll( int arg0 , Collection arg1 ){
throw new UnsupportedOperationException( "Read Only" );
}
@Override
public void clear(){
throw new UnsupportedOperationException( "Read Only" );
}
@Override
public boolean remove( Object arg0 ){
throw new UnsupportedOperationException( "Read Only" );
}
@Override
public Object remove( int arg0 ){
throw new UnsupportedOperationException( "Read Only" );
}
@Override
public boolean removeAll( Collection arg0 ){
throw new UnsupportedOperationException( "Read Only" );
}
@Override
public boolean retainAll( Collection arg0 ){
throw new UnsupportedOperationException( "Read Only" );
}
@Override
public Object set( int arg0 , Object arg1 ){
throw new UnsupportedOperationException( "Read Only" );
}
@Override
public List subList( int arg0 , int arg1 ){
throw new UnsupportedOperationException( "Not Supported" );
}
@Override
public Object[] toArray(){
throw new UnsupportedOperationException( "Not Supported" );
}
@Override
public Object[] toArray( Object[] arg0 ){
throw new UnsupportedOperationException( "Not Supported" );
}
}

View File

@ -1,685 +0,0 @@
/**
* Copyright (C) 2008-2011 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import com.massivecraft.massivecore.xlib.bson.io.BSONByteBuffer;
import com.massivecraft.massivecore.xlib.bson.types.*;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
import java.util.logging.Logger;
import java.util.regex.Pattern;
/**
* @author antoine
* @author brendan
* @author scotthernandez
* @author Kilroy Wuz Here
*/
@SuppressWarnings({"unchecked", "rawtypes", "unused"})
public class LazyBSONObject implements BSONObject {
public LazyBSONObject( byte[] data, LazyBSONCallback callback ){
this( BSONByteBuffer.wrap( data ), callback );
}
public LazyBSONObject( byte[] data, int offset, LazyBSONCallback callback ){
this( BSONByteBuffer.wrap( data, offset, data.length - offset ), offset, callback );
}
public LazyBSONObject( BSONByteBuffer buffer, LazyBSONCallback callback ){
this( buffer, 0, callback );
}
public LazyBSONObject( BSONByteBuffer buffer, int offset, LazyBSONCallback callback ){
_callback = callback;
_input = buffer;
_doc_start_offset = offset;
}
class ElementRecord {
ElementRecord( final String name, final int offset ){
this.name = name;
this.offset = offset;
this.type = getElementType( offset - 1 );
this.fieldNameSize = sizeCString( offset );
this.valueOffset = offset + fieldNameSize;
}
final String name;
/**
* The offset the record begins at.
*/
final byte type;
final int fieldNameSize;
final int valueOffset;
final int offset;
}
class LazyBSONKeyIterator implements Iterator<String> {
public boolean hasNext(){
return !isElementEmpty( offset );
}
public String next(){
int fieldSize = sizeCString( offset + 1);
int elementSize = getElementBSONSize( offset );
String key = _input.getCString( offset + 1);
offset += fieldSize + elementSize + 1;
return key;
}
public void remove(){
throw new UnsupportedOperationException( "Read only" );
}
int offset = _doc_start_offset + FIRST_ELMT_OFFSET;
}
public class LazyBSONKeySet extends ReadOnlySet<String> {
/**
* This method runs in time linear to the total size of all keys in the document.
*
* @return the number of keys in the document
*/
@Override
public int size(){
int size = 0;
Iterator<String> iter = iterator();
while(iter.hasNext()) {
iter.next();
++size;
}
return size;
}
@Override
public boolean isEmpty(){
return LazyBSONObject.this.isEmpty();
}
@Override
public boolean contains( Object o ){
for ( String key : this ){
if ( key.equals( o ) ){
return true;
}
}
return false;
}
@Override
public Iterator<String> iterator(){
return new LazyBSONKeyIterator();
}
@Override
public String[] toArray(){
String[] a = new String[size()];
return toArray(a);
}
@Override
public <T> T[] toArray(T[] a) {
int size = size();
T[] localArray = a.length >= size ? a :
(T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
int i = 0;
for ( String key : this ){
localArray[i++] = (T) key;
}
if (localArray.length > i) {
localArray[i] = null;
}
return localArray;
}
@Override
public boolean add( String e ){
throw new UnsupportedOperationException( "Not supported yet." );
}
@Override
public boolean remove( Object o ){
throw new UnsupportedOperationException( "Not supported yet." );
}
@Override
public boolean containsAll( Collection<?> collection ){
for ( Object item : collection ){
if ( !contains( item ) ){
return false;
}
}
return true;
}
}
class LazyBSONEntryIterator implements Iterator<Map.Entry<String, Object>> {
public boolean hasNext(){
return !isElementEmpty( offset );
}
public Map.Entry<String, Object> next(){
int fieldSize = sizeCString(offset + 1);
int elementSize = getElementBSONSize(offset);
String key = _input.getCString(offset + 1);
final ElementRecord nextElementRecord = new ElementRecord(key, ++offset);
offset += fieldSize + elementSize;
return new Map.Entry<String, Object>() {
@Override
public String getKey() {
return nextElementRecord.name;
}
@Override
public Object getValue() {
return getElementValue(nextElementRecord);
}
@Override
public Object setValue(Object value) {
throw new UnsupportedOperationException("Read only");
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry e = (Map.Entry) o;
return getKey().equals(e.getKey()) && getValue().equals(e.getValue());
}
@Override
public int hashCode() {
return getKey().hashCode() ^ getValue().hashCode();
}
@Override
public String toString() {
return getKey() + "=" + getValue();
}
};
}
public void remove(){
throw new UnsupportedOperationException( "Read only" );
}
int offset = _doc_start_offset + FIRST_ELMT_OFFSET;
}
class LazyBSONEntrySet extends ReadOnlySet<Map.Entry<String, Object>> {
@Override
public int size() {
return LazyBSONObject.this.keySet().size();
}
@Override
public boolean isEmpty() {
return LazyBSONObject.this.isEmpty();
}
@Override
public boolean contains(Object o) {
Iterator<Map.Entry<String, Object>> iter = iterator();
while (iter.hasNext()) {
if (iter.next().equals(o)) {
return true;
}
}
return false;
}
@Override
public boolean containsAll(Collection<?> c) {
for (Object cur : c) {
if (!contains(cur)) {
return false;
}
}
return true;
}
@Override
public Iterator<Map.Entry<String, Object>> iterator() {
return new LazyBSONEntryIterator();
}
@Override
public Object[] toArray() {
Map.Entry[] array = new Map.Entry[size()];
return toArray(array);
}
@Override
public <T> T[] toArray(T[] a) {
int size = size();
T[] localArray = a.length >= size ? a :
(T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
Iterator<Map.Entry<String, Object>> iter = iterator();
int i = 0;
while(iter.hasNext()) {
localArray[i++] = (T) iter.next();
}
if (localArray.length > i) {
localArray[i] = null;
}
return localArray;
}
}
// Base class that throws UnsupportedOperationException for any method that writes to the Set
abstract class ReadOnlySet<E> implements Set<E> {
@Override
public boolean add(E e) {
throw new UnsupportedOperationException("Read-only Set");
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException("Read-only Set");
}
@Override
public boolean addAll(Collection<? extends E> c) {
throw new UnsupportedOperationException("Read-only Set");
}
@Override
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException("Read-only Set");
}
@Override
public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException("Read-only Set");
}
@Override
public void clear() {
throw new UnsupportedOperationException("Read-only Set");
}
}
public Object put( String key, Object v ){
throw new UnsupportedOperationException( "Object is read only" );
}
public void putAll( BSONObject o ){
throw new UnsupportedOperationException( "Object is read only" );
}
public void putAll( Map m ){
throw new UnsupportedOperationException( "Object is read only" );
}
public Object get( String key ){
//get element up to the key
ElementRecord element = getElement(key);
//no found if null/empty
if (element == null) {
return null;
}
return getElementValue(element);
}
/**
* returns the ElementRecord for the given key, or null if not found
* @param key the field/key to find
* @return ElementRecord for key, or null
*/
ElementRecord getElement(String key){
int offset = _doc_start_offset + FIRST_ELMT_OFFSET;
while ( !isElementEmpty( offset ) ){
int fieldSize = sizeCString( offset + 1 );
int elementSize = getElementBSONSize( offset );
String name = _input.getCString( ++offset);
if (name.equals(key)) {
return new ElementRecord( name, offset );
}
offset += ( fieldSize + elementSize);
}
return null;
}
/**
* returns all the ElementRecords in this document
* @return list of ElementRecord
*/
List<ElementRecord> getElements(){
int offset = _doc_start_offset + FIRST_ELMT_OFFSET;
ArrayList<ElementRecord> elements = new ArrayList<LazyBSONObject.ElementRecord>();
while ( !isElementEmpty( offset ) ){
int fieldSize = sizeCString( offset + 1 );
int elementSize = getElementBSONSize( offset );
String name = _input.getCString( ++offset );
ElementRecord rec = new ElementRecord( name, offset );
elements.add( rec );
offset += ( fieldSize + elementSize );
}
return elements;
}
public Map toMap(){
throw new UnsupportedOperationException( "Not Supported" );
}
public Object removeField( String key ){
throw new UnsupportedOperationException( "Object is read only" );
}
@Deprecated
public boolean containsKey( String s ){
return containsField( s );
}
public boolean containsField( String s ){
return keySet().contains( s );
}
/**
*
* @return the set of all keys in the document
*/
public Set<String> keySet(){
return new LazyBSONKeySet();
}
/**
* This method will be more efficient than using a combination of keySet() and get(String key)
* @return the set of entries (key, value) in the document
*/
public Set<Map.Entry<String, Object>> entrySet(){
return new LazyBSONEntrySet();
}
protected boolean isElementEmpty( int offset ){
return getElementType( offset ) == BSON.EOO;
}
public boolean isEmpty(){
return isElementEmpty( _doc_start_offset + FIRST_ELMT_OFFSET );
}
private int getBSONSize( final int offset ){
return _input.getInt( offset );
}
public int getBSONSize(){
return getBSONSize( _doc_start_offset );
}
public int pipe(OutputStream os) throws IOException {
os.write(_input.array(), _doc_start_offset, getBSONSize());
return getBSONSize();
}
private String getElementFieldName( final int offset ){
return _input.getCString( offset );
}
protected byte getElementType( final int offset ){
return _input.get( offset );
}
protected int getElementBSONSize( int offset ){
int x = 0;
byte type = getElementType( offset++ );
int n = sizeCString( offset );
int valueOffset = offset + n;
switch ( type ){
case BSON.EOO:
case BSON.UNDEFINED:
case BSON.NULL:
case BSON.MAXKEY:
case BSON.MINKEY:
break;
case BSON.BOOLEAN:
x = 1;
break;
case BSON.NUMBER_INT:
x = 4;
break;
case BSON.TIMESTAMP:
case BSON.DATE:
case BSON.NUMBER_LONG:
case BSON.NUMBER:
x = 8;
break;
case BSON.OID:
x = 12;
break;
case BSON.SYMBOL:
case BSON.CODE:
case BSON.STRING:
x = _input.getInt( valueOffset ) + 4;
break;
case BSON.CODE_W_SCOPE:
x = _input.getInt( valueOffset );
break;
case BSON.REF:
x = _input.getInt( valueOffset ) + 4 + 12;
break;
case BSON.OBJECT:
case BSON.ARRAY:
x = _input.getInt( valueOffset );
break;
case BSON.BINARY:
x = _input.getInt( valueOffset ) + 4 + 1/*subtype*/;
break;
case BSON.REGEX:
// 2 cstrs
int part1 = sizeCString( valueOffset );
int part2 = sizeCString( valueOffset + part1 );
x = part1 + part2;
break;
default:
throw new BSONException( "Invalid type " + type + " for field " + getElementFieldName( offset ) );
}
return x;
}
/**
* Returns the size of the BSON cstring at the given offset in the buffer
* @param offset the offset into the buffer
* @return the size of the BSON cstring, including the null terminator
*/
protected int sizeCString( int offset ){
int end = offset;
while ( true ){
byte b = _input.get( end );
if ( b == 0 )
break;
else
end++;
}
return end - offset + 1;
}
protected Object getElementValue( ElementRecord record ){
switch ( record.type ){
case BSON.EOO:
case BSON.UNDEFINED:
case BSON.NULL:
return null;
case BSON.MAXKEY:
return new MaxKey();
case BSON.MINKEY:
return new MinKey();
case BSON.BOOLEAN:
return ( _input.get( record.valueOffset ) != 0 );
case BSON.NUMBER_INT:
return _input.getInt( record.valueOffset );
case BSON.TIMESTAMP:
int inc = _input.getInt( record.valueOffset );
int time = _input.getInt( record.valueOffset + 4 );
return new BSONTimestamp( time, inc );
case BSON.DATE:
return new Date( _input.getLong( record.valueOffset ) );
case BSON.NUMBER_LONG:
return _input.getLong( record.valueOffset );
case BSON.NUMBER:
return Double.longBitsToDouble( _input.getLong( record.valueOffset ) );
case BSON.OID:
return new ObjectId( _input.getIntBE( record.valueOffset ),
_input.getIntBE( record.valueOffset + 4 ),
_input.getIntBE( record.valueOffset + 8 ) );
case BSON.SYMBOL:
return new Symbol( _input.getUTF8String( record.valueOffset ) );
case BSON.CODE:
return new Code( _input.getUTF8String( record.valueOffset ) );
case BSON.STRING:
return _input.getUTF8String( record.valueOffset );
case BSON.CODE_W_SCOPE:
int strsize = _input.getInt( record.valueOffset + 4 );
String code = _input.getUTF8String( record.valueOffset + 4 );
BSONObject scope =
(BSONObject) _callback.createObject( _input.array(), record.valueOffset + 4 + 4 + strsize );
return new CodeWScope( code, scope );
case BSON.REF:
int csize = _input.getInt( record.valueOffset );
String ns = _input.getCString( record.valueOffset + 4 );
int oidOffset = record.valueOffset + csize + 4;
ObjectId oid = new ObjectId( _input.getIntBE( oidOffset ),
_input.getIntBE( oidOffset + 4 ),
_input.getIntBE( oidOffset + 8 ) );
return _callback.createDBRef( ns, oid );
case BSON.OBJECT:
return _callback.createObject( _input.array(), record.valueOffset );
case BSON.ARRAY:
return _callback.createArray( _input.array(), record.valueOffset );
case BSON.BINARY:
return readBinary( record.valueOffset );
case BSON.REGEX:
int patternCStringSize = sizeCString( record.valueOffset );
String pattern = _input.getCString( record.valueOffset );
String flags = _input.getCString( record.valueOffset + patternCStringSize + 1 );
return Pattern.compile( pattern, BSON.regexFlags( flags ) );
default:
throw new BSONException(
"Invalid type " + record.type + " for field " + getElementFieldName( record.offset ) );
}
}
private Object readBinary( int valueOffset ){
final int totalLen = _input.getInt( valueOffset );
valueOffset += 4;
final byte bType = _input.get( valueOffset );
valueOffset += 1;
byte[] bin;
switch ( bType ){
case BSON.B_GENERAL:{
bin = new byte[totalLen];
for ( int n = 0; n < totalLen; n++ ){
bin[n] = _input.get( valueOffset + n );
}
return bin;
}
case BSON.B_BINARY:
final int len = _input.getInt( valueOffset );
if ( len + 4 != totalLen )
throw new IllegalArgumentException(
"Bad Data Size; Binary Subtype 2. { actual len: " + len + " expected totalLen: " + totalLen
+ "}" );
valueOffset += 4;
bin = new byte[len];
for ( int n = 0; n < len; n++ ){
bin[n] = _input.get( valueOffset + n );
}
return bin;
case BSON.B_UUID:
if ( totalLen != 16 )
throw new IllegalArgumentException(
"Bad Data Size; Binary Subtype 3 (UUID). { total length: " + totalLen + " != 16" );
long part1 = _input.getLong( valueOffset );
valueOffset += 8;
long part2 = _input.getLong( valueOffset );
return new UUID( part1, part2 );
}
bin = new byte[totalLen];
for ( int n = 0; n < totalLen; n++ ){
bin[n] = _input.get( valueOffset + n );
}
return bin;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
LazyBSONObject that = (LazyBSONObject) o;
return Arrays.equals(this._input.array(), that._input.array());
}
@Override
public int hashCode() {
return Arrays.hashCode(_input.array());
}
/**
* Returns a JSON serialization of this object
*
* @return JSON serialization
*/
public String toString(){
return com.massivecraft.massivecore.xlib.mongodb.util.JSON.serialize( this );
}
/**
* In a "normal" (aka not embedded) doc, this will be the offset of the first element.
*
* In an embedded doc because we use ByteBuffers to avoid unecessary copying the offset must be manually set in
* _doc_start_offset
*/
final static int FIRST_ELMT_OFFSET = 4;
protected final int _doc_start_offset;
protected final BSONByteBuffer _input; // TODO - Guard this with synchronicity?
// callback is kept to create sub-objects on the fly
protected final LazyBSONCallback _callback;
private static final Logger log = Logger.getLogger( "org.bson.LazyBSONObject" );
}

View File

@ -1,42 +0,0 @@
/**
*
*/
package com.massivecraft.massivecore.xlib.bson;
import com.massivecraft.massivecore.xlib.bson.io.BSONByteBuffer;
import com.massivecraft.massivecore.xlib.mongodb.DBObject;
import com.massivecraft.massivecore.xlib.mongodb.util.JSON;
/**
* @author scotthernandez
*
*/
@SuppressWarnings({"unused"})
public class LazyDBList extends LazyBSONList implements DBObject {
private static final long serialVersionUID = -4415279469780082174L;
public LazyDBList(byte[] data, LazyBSONCallback callback) { super(data, callback); }
public LazyDBList(byte[] data, int offset, LazyBSONCallback callback) { super(data, offset, callback); }
public LazyDBList(BSONByteBuffer buffer, LazyBSONCallback callback) { super(buffer, callback); }
public LazyDBList(BSONByteBuffer buffer, int offset, LazyBSONCallback callback) { super(buffer, offset, callback); }
/**
* Returns a JSON serialization of this object
* @return JSON serialization
*/
@Override
public String toString(){
return JSON.serialize( this );
}
public boolean isPartialObject(){
return _isPartialObject;
}
public void markAsPartialObject(){
_isPartialObject = true;
}
private boolean _isPartialObject;
}

View File

@ -1,305 +0,0 @@
/**
* Copyright (C) 2012 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
import com.massivecraft.massivecore.xlib.bson.io.Bits;
import com.massivecraft.massivecore.xlib.bson.types.ObjectId;
import static com.massivecraft.massivecore.xlib.bson.BSON.*;
// Java
import java.io.IOException;
import java.io.InputStream;
import java.io.DataInputStream;
import java.io.UnsupportedEncodingException;
/**
* A new implementation of the bson decoder.
*/
public class NewBSONDecoder implements BSONDecoder {
@Override
public BSONObject readObject(final byte [] pData) {
_length = pData.length;
final BasicBSONCallback c = new BasicBSONCallback();
decode(pData, c);
return (BSONObject)c.get();
}
@Override
public BSONObject readObject(final InputStream pIn) throws IOException {
// Slurp in the data and convert to a byte array.
_length = Bits.readInt(pIn);
if (_data == null || _data.length < _length) {
_data = new byte[_length];
}
(new DataInputStream(pIn)).readFully(_data, 4, (_length - 4));
return readObject(_data);
}
@Override
public int decode(final byte [] pData, final BSONCallback pCallback) {
_data = pData;
_pos = 4;
_callback = pCallback;
_decode();
return _length;
}
@Override
public int decode(final InputStream pIn, final BSONCallback pCallback) throws IOException {
_length = Bits.readInt(pIn);
if (_data == null || _data.length < _length) {
_data = new byte[_length];
}
(new DataInputStream(pIn)).readFully(_data, 4, (_length - 4));
return decode(_data, pCallback);
}
private final void _decode() {
_callback.objectStart();
while (decodeElement());
_callback.objectDone();
}
private final String readCstr() {
int length = 0;
final int offset = _pos;
while (_data[_pos++] != 0) length++;
try {
return new String(_data, offset, length, DEFAULT_ENCODING);
} catch (final UnsupportedEncodingException uee) {
return new String(_data, offset, length);
}
}
private final String readUtf8Str() {
final int length = Bits.readInt(_data, _pos);
_pos += 4;
if (length <= 0 || length > MAX_STRING) throw new BSONException("String invalid - corruption");
try {
final String str = new String(_data, _pos, (length - 1), DEFAULT_ENCODING);
_pos += length;
return str;
} catch (final UnsupportedEncodingException uee) {
throw new BSONException("What is in the db", uee);
}
}
private final Object _readBasicObject() {
_pos += 4;
final BSONCallback save = _callback;
final BSONCallback _basic = _callback.createBSONCallback();
_callback = _basic;
_basic.reset();
_basic.objectStart(false);
while( decodeElement() );
_callback = save;
return _basic.get();
}
private final void _binary(final String pName) {
final int totalLen = Bits.readInt(_data, _pos);
_pos += 4;
final byte bType = _data[_pos];
_pos += 1;
switch ( bType ){
case B_GENERAL: {
final byte [] data = new byte[totalLen];
System.arraycopy(_data, _pos, data, 0, totalLen);
_pos += totalLen;
_callback.gotBinary(pName, bType, data);
return;
}
case B_BINARY: {
final int len = Bits.readInt(_data, _pos);
_pos += 4;
if ( len + 4 != totalLen )
throw new IllegalArgumentException( "bad data size subtype 2 len: " + len + " totalLen: " + totalLen );
final byte [] data = new byte[len];
System.arraycopy(_data, _pos, data, 0, len);
_pos += len;
_callback.gotBinary(pName, bType, data);
return;
}
case B_UUID: {
if ( totalLen != 16 )
throw new IllegalArgumentException( "bad data size subtype 3 len: " + totalLen + " != 16");
final long part1 = Bits.readLong(_data, _pos);
_pos += 8;
final long part2 = Bits.readLong(_data, _pos);
_pos += 8;
_callback.gotUUID(pName, part1, part2);
return;
}
}
final byte [] data = new byte[totalLen];
System.arraycopy(_data, _pos, data, 0, totalLen);
_pos += totalLen;
_callback.gotBinary(pName, bType, data);
}
private final boolean decodeElement() {
final byte type = _data[_pos];
_pos += 1;
if (type == EOO) return false;
final String name = readCstr();
switch (type) {
case NULL: { _callback.gotNull(name); return true; }
case UNDEFINED: { _callback.gotUndefined(name); return true; }
case BOOLEAN: { _callback.gotBoolean(name, (_data[_pos] > 0)); _pos += 1; return true; }
case NUMBER: { _callback.gotDouble(name, Double.longBitsToDouble(Bits.readLong(_data, _pos))); _pos += 8; return true; }
case NUMBER_INT: { _callback.gotInt(name, Bits.readInt(_data, _pos)); _pos += 4; return true; }
case NUMBER_LONG: {
_callback.gotLong(name, Bits.readLong(_data, _pos));
_pos += 8;
return true;
}
case SYMBOL: { _callback.gotSymbol(name, readUtf8Str()); return true; }
case STRING: { _callback.gotString(name, readUtf8Str()); return true; }
case OID: {
// OID is stored as big endian
final int p1 = Bits.readIntBE(_data, _pos);
_pos += 4;
final int p2 = Bits.readIntBE(_data, _pos);
_pos += 4;
final int p3 = Bits.readIntBE(_data, _pos);
_pos += 4;
_callback.gotObjectId(name , new ObjectId(p1, p2, p3));
return true;
}
case REF: {
_pos += 4;
final String ns = readCstr();
final int p1 = Bits.readInt(_data, _pos);
_pos += 4;
final int p2 = Bits.readInt(_data, _pos);
_pos += 4;
final int p3 = Bits.readInt(_data, _pos);
_pos += 4;
_callback.gotDBRef(name , ns, new ObjectId(p1, p2, p3));
return true;
}
case DATE: { _callback.gotDate(name , Bits.readLong(_data, _pos)); _pos += 8; return true; }
case REGEX: {
_callback.gotRegex(name, readCstr(), readCstr());
return true;
}
case BINARY: { _binary(name); return true; }
case CODE: { _callback.gotCode(name, readUtf8Str()); return true; }
case CODE_W_SCOPE: {
_pos += 4;
_callback.gotCodeWScope(name, readUtf8Str(), _readBasicObject());
return true;
}
case ARRAY:
_pos += 4;
_callback.arrayStart(name);
while (decodeElement());
_callback.arrayDone();
return true;
case OBJECT:
_pos += 4;
_callback.objectStart(name);
while (decodeElement());
_callback.objectDone();
return true;
case TIMESTAMP:
int i = Bits.readInt(_data, _pos);
_pos += 4;
int time = Bits.readInt(_data, _pos);
_pos += 4;
_callback.gotTimestamp(name, time, i);
return true;
case MINKEY: _callback.gotMinKey(name); return true;
case MAXKEY: _callback.gotMaxKey(name); return true;
default: throw new UnsupportedOperationException( "BSONDecoder doesn't understand type : " + type + " name: " + name );
}
}
private static final int MAX_STRING = ( 32 * 1024 * 1024 );
private static final String DEFAULT_ENCODING = "UTF-8";
private byte [] _data;
private int _length;
private int _pos = 0;
private BSONCallback _callback;
}

View File

@ -1,27 +0,0 @@
// Transformer.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson;
public interface Transformer {
/**
* @return the new object. return passed in object if no change
*/
public Object transform( Object o );
}

View File

@ -1,143 +0,0 @@
/**
* Copyright (C) 2008-2011 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.io;
import com.massivecraft.massivecore.xlib.bson.*;
import java.io.*;
import java.nio.*;
/**
* Pseudo byte buffer, delegates as it is too hard to properly override / extend the ByteBuffer API
*
* @author brendan
*/
public class BSONByteBuffer {
private BSONByteBuffer( ByteBuffer buf ){
this.buf = buf;
buf.order( ByteOrder.LITTLE_ENDIAN );
}
public static BSONByteBuffer wrap( byte[] bytes, int offset, int length ){
return new BSONByteBuffer( ByteBuffer.wrap( bytes, offset, length ) );
}
public static BSONByteBuffer wrap( byte[] bytes ){
return new BSONByteBuffer( ByteBuffer.wrap( bytes ) );
}
public byte get( int i ){
return buf.get(i);
}
public ByteBuffer get( byte[] bytes, int offset, int length ){
return buf.get(bytes, offset, length);
}
public ByteBuffer get( byte[] bytes ){
return buf.get(bytes);
}
public byte[] array(){
return buf.array();
}
public String toString(){
return buf.toString();
}
public int hashCode(){
return buf.hashCode();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
BSONByteBuffer that = (BSONByteBuffer) o;
if (buf != null ? !buf.equals(that.buf) : that.buf != null) return false;
return true;
}
/**
* Gets a Little Endian Integer
*
* @param i Index to read from
*
* @return
*/
public int getInt( int i ){
return getIntLE( i );
}
public int getIntLE( int i ){
int x = 0;
x |= ( 0xFF & buf.get( i + 0 ) ) << 0;
x |= ( 0xFF & buf.get( i + 1 ) ) << 8;
x |= ( 0xFF & buf.get( i + 2 ) ) << 16;
x |= ( 0xFF & buf.get( i + 3 ) ) << 24;
return x;
}
public int getIntBE( int i ){
int x = 0;
x |= ( 0xFF & buf.get( i + 0 ) ) << 24;
x |= ( 0xFF & buf.get( i + 1 ) ) << 16;
x |= ( 0xFF & buf.get( i + 2 ) ) << 8;
x |= ( 0xFF & buf.get( i + 3 ) ) << 0;
return x;
}
public long getLong( int i ){
return buf.getLong( i );
}
public String getCString(int offset) {
int end = offset;
while (get(end) != 0) {
++end;
}
int len = end - offset;
return new String(array(), offset, len);
}
public String getUTF8String(int valueOffset) {
int size = getInt(valueOffset) - 1;
try {
return new String(array(), valueOffset + 4, size, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new BSONException( "Cannot decode string as UTF-8." );
}
}
public Buffer position( int i ){
return buf.position(i);
}
public Buffer reset(){
return buf.reset();
}
public int size(){
return getInt( 0 );
}
protected ByteBuffer buf;
}

View File

@ -1,119 +0,0 @@
// BasicOutputBuffer.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.io;
import java.io.*;
public class BasicOutputBuffer extends OutputBuffer {
@Override
public void write(byte[] b){
write( b , 0 , b.length );
}
@Override
public void write(byte[] b, int off, int len){
_ensure( len );
System.arraycopy( b , off , _buffer , _cur , len );
_cur += len;
_size = Math.max( _cur , _size );
}
@Override
public void write(int b){
_ensure(1);
_buffer[_cur++] = (byte)(0xFF&b);
_size = Math.max( _cur , _size );
}
@Override
public int getPosition(){
return _cur;
}
@Override
public void setPosition( int position ){
_cur = position;
}
@Override
public void seekEnd(){
_cur = _size;
}
@Override
public void seekStart(){
_cur = 0;
}
/**
* @return size of data so far
*/
@Override
public int size(){
return _size;
}
/**
* @return bytes written
*/
@Override
public int pipe( OutputStream out )
throws IOException {
out.write( _buffer , 0 , _size );
return _size;
}
/**
* @return bytes written
*/
public int pipe( DataOutput out )
throws IOException {
out.write( _buffer , 0 , _size );
return _size;
}
void _ensure( int more ){
final int need = _cur + more;
if ( need < _buffer.length )
return;
int newSize = _buffer.length*2;
if ( newSize <= need )
newSize = need + 128;
byte[] n = new byte[newSize];
System.arraycopy( _buffer , 0 , n , 0 , _size );
_buffer = n;
}
@Override
public String asString(){
return new String( _buffer , 0 , _size );
}
@Override
public String asString( String encoding )
throws UnsupportedEncodingException {
return new String( _buffer , 0 , _size , encoding );
}
private int _cur;
private int _size;
private byte[] _buffer = new byte[512];
}

View File

@ -1,115 +0,0 @@
// Bits.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.io;
import java.io.*;
public class Bits {
public static void readFully( InputStream in, byte[] b )
throws IOException {
readFully( in , b , b.length );
}
public static void readFully( InputStream in, byte[] b, int length )
throws IOException {
readFully(in, b, 0, length);
}
public static void readFully( InputStream in, byte[] b, int startOffset, int length )
throws IOException {
if (b.length - startOffset > length) {
throw new IllegalArgumentException("Buffer is too small");
}
int offset = startOffset;
int toRead = length;
while ( toRead > 0 ){
int bytesRead = in.read( b, offset , toRead );
if ( bytesRead < 0 )
throw new EOFException();
toRead -= bytesRead;
offset += bytesRead;
}
}
public static int readInt( InputStream in )
throws IOException {
return readInt( in , new byte[4] );
}
public static int readInt( InputStream in , byte[] data )
throws IOException {
readFully(in, data, 4);
return readInt(data);
}
public static int readInt( byte[] data ) {
return readInt( data , 0 );
}
public static int readInt( byte[] data , int offset ) {
int x = 0;
x |= ( 0xFF & data[offset+0] ) << 0;
x |= ( 0xFF & data[offset+1] ) << 8;
x |= ( 0xFF & data[offset+2] ) << 16;
x |= ( 0xFF & data[offset+3] ) << 24;
return x;
}
public static int readIntBE( byte[] data , int offset ) {
int x = 0;
x |= ( 0xFF & data[offset+0] ) << 24;
x |= ( 0xFF & data[offset+1] ) << 16;
x |= ( 0xFF & data[offset+2] ) << 8;
x |= ( 0xFF & data[offset+3] ) << 0;
return x;
}
public static long readLong( InputStream in )
throws IOException {
return readLong( in , new byte[8] );
}
public static long readLong( InputStream in , byte[] data )
throws IOException {
readFully(in, data, 8);
return readLong(data);
}
public static long readLong( byte[] data ) {
return readLong( data , 0 );
}
public static long readLong( byte[] data , int offset ) {
long x = 0;
x |= ( 0xFFL & data[offset+0] ) << 0;
x |= ( 0xFFL & data[offset+1] ) << 8;
x |= ( 0xFFL & data[offset+2] ) << 16;
x |= ( 0xFFL & data[offset+3] ) << 24;
x |= ( 0xFFL & data[offset+4] ) << 32;
x |= ( 0xFFL & data[offset+5] ) << 40;
x |= ( 0xFFL & data[offset+6] ) << 48;
x |= ( 0xFFL & data[offset+7] ) << 56;
return x;
}
}

View File

@ -1,159 +0,0 @@
// OutputBuffer.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.io;
import java.io.*;
import java.security.*;
public abstract class OutputBuffer extends OutputStream {
public abstract void write(byte[] b);
public abstract void write(byte[] b, int off, int len);
public abstract void write(int b);
public abstract int getPosition();
public abstract void setPosition( int position );
public abstract void seekEnd();
public abstract void seekStart();
/**
* @return size of data so far
*/
public abstract int size();
/**
* @return bytes written
*/
public abstract int pipe( OutputStream out )
throws IOException;
/**
* mostly for testing
*/
public byte [] toByteArray(){
try {
final ByteArrayOutputStream bout = new ByteArrayOutputStream( size() );
pipe( bout );
return bout.toByteArray();
}
catch ( IOException ioe ){
throw new RuntimeException( "should be impossible" , ioe );
}
}
public String asString(){
return new String( toByteArray() );
}
public String asString( String encoding )
throws UnsupportedEncodingException {
return new String( toByteArray() , encoding );
}
public String hex(){
final StringBuilder buf = new StringBuilder();
try {
pipe( new OutputStream(){
public void write( int b ){
String s = Integer.toHexString(0xff & b);
if (s.length() < 2)
buf.append("0");
buf.append(s);
}
}
);
}
catch ( IOException ioe ){
throw new RuntimeException( "impossible" );
}
return buf.toString();
}
public String md5(){
final MessageDigest md5 ;
try {
md5 = MessageDigest.getInstance("MD5");
}
catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Error - this implementation of Java doesn't support MD5.");
}
md5.reset();
try {
pipe( new OutputStream(){
public void write( byte[] b , int off , int len ){
md5.update( b , off , len );
}
public void write( int b ){
md5.update( (byte)(b&0xFF) );
}
}
);
}
catch ( IOException ioe ){
throw new RuntimeException( "impossible" );
}
return com.massivecraft.massivecore.xlib.mongodb.util.Util.toHex( md5.digest() );
}
public void writeInt( int x ){
write( x >> 0 );
write( x >> 8 );
write( x >> 16 );
write( x >> 24 );
}
public void writeIntBE( int x ){
write( x >> 24 );
write( x >> 16 );
write( x >> 8 );
write( x );
}
public void writeInt( int pos , int x ){
final int save = getPosition();
setPosition( pos );
writeInt( x );
setPosition( save );
}
public void writeLong( long x ){
write( (byte)(0xFFL & ( x >> 0 ) ) );
write( (byte)(0xFFL & ( x >> 8 ) ) );
write( (byte)(0xFFL & ( x >> 16 ) ) );
write( (byte)(0xFFL & ( x >> 24 ) ) );
write( (byte)(0xFFL & ( x >> 32 ) ) );
write( (byte)(0xFFL & ( x >> 40 ) ) );
write( (byte)(0xFFL & ( x >> 48 ) ) );
write( (byte)(0xFFL & ( x >> 56 ) ) );
}
public void writeDouble( double x ){
writeLong( Double.doubleToRawLongBits( x ) );
}
public String toString(){
return getClass().getName() + " size: " + size() + " pos: " + getPosition() ;
}
}

View File

@ -1,238 +0,0 @@
// PoolOutputBuffer.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.io;
import java.io.*;
import java.util.*;
public class PoolOutputBuffer extends OutputBuffer {
public static final int BUF_SIZE = 1024 * 16;
public PoolOutputBuffer(){
reset();
}
public void reset(){
_cur.reset();
_end.reset();
for ( int i=0; i<_fromPool.size(); i++ )
_extra.done( _fromPool.get(i) );
_fromPool.clear();
}
public int getPosition(){
return _cur.pos();
}
public void setPosition( int position ){
_cur.reset( position );
}
public void seekEnd(){
_cur.reset( _end );
}
public void seekStart(){
_cur.reset();
}
public int size(){
return _end.pos();
}
public void write(byte[] b){
write( b , 0 , b.length );
}
public void write(byte[] b, int off, int len){
while ( len > 0 ){
byte[] bs = _cur();
int space = Math.min( bs.length - _cur.y , len );
System.arraycopy( b , off , bs , _cur.y , space );
_cur.inc( space );
len -= space;
off += space;
_afterWrite();
}
}
public void write(int b){
byte[] bs = _cur();
bs[_cur.getAndInc()] = (byte)(b&0xFF);
_afterWrite();
}
void _afterWrite(){
if ( _cur.pos() < _end.pos() ){
// we're in the middle of the total space
// just need to make sure we're not at the end of a buffer
if ( _cur.y == BUF_SIZE )
_cur.nextBuffer();
return;
}
_end.reset( _cur );
if ( _end.y < BUF_SIZE )
return;
_fromPool.add( _extra.get() );
_end.nextBuffer();
_cur.reset( _end );
}
byte[] _cur(){
return _get( _cur.x );
}
byte[] _get( int z ){
if ( z < 0 )
return _mine;
return _fromPool.get(z);
}
public int pipe( final OutputStream out )
throws IOException {
if ( out == null )
throw new NullPointerException( "out is null" );
int total = 0;
for ( int i=-1; i<_fromPool.size(); i++ ){
final byte[] b = _get( i );
final int amt = _end.len( i );
out.write( b , 0 , amt );
total += amt;
}
return total;
}
static class Position {
Position(){
reset();
}
void reset(){
x = -1;
y = 0;
}
void reset( Position other ){
x = other.x;
y = other.y;
}
void reset( int pos ){
x = ( pos / BUF_SIZE ) - 1;
y = pos % BUF_SIZE;
}
int pos(){
return ( ( x + 1 ) * BUF_SIZE ) + y;
}
int getAndInc(){
return y++;
}
void inc( int amt ){
y += amt;
if ( y > BUF_SIZE )
throw new IllegalArgumentException( "something is wrong" );
}
void nextBuffer(){
if ( y != BUF_SIZE )
throw new IllegalArgumentException( "broken" );
x++;
y = 0;
}
int len( int which ){
if ( which < x )
return BUF_SIZE;
return y;
}
public String toString(){
return x + "," + y;
}
int x; // which buffer -1 == _mine
int y; // position in buffer
}
public String asAscii(){
if ( _fromPool.size() > 0 )
return super.asString();
final int m = size();
final char c[] = m < _chars.length ? _chars : new char[m];
for ( int i=0; i<m; i++ )
c[i] = (char)_mine[i];
return new String( c , 0 , m );
}
public String asString( String encoding )
throws UnsupportedEncodingException {
if ( _fromPool.size() > 0 )
return super.asString( encoding );
if ( encoding.equals( DEFAULT_ENCODING_1 ) || encoding.equals( DEFAULT_ENCODING_2) ){
try {
return _encoding.decode( _mine , 0 , size() );
}
catch ( IOException ioe ){
// we failed, fall back
}
}
return new String( _mine , 0 , size() , encoding );
}
final byte[] _mine = new byte[BUF_SIZE];
final char[] _chars = new char[BUF_SIZE];
final List<byte[]> _fromPool = new ArrayList<byte[]>();
final UTF8Encoding _encoding = new UTF8Encoding();
private static final String DEFAULT_ENCODING_1 = "UTF-8";
private static final String DEFAULT_ENCODING_2 = "UTF8";
private final Position _cur = new Position();
private final Position _end = new Position();
private static com.massivecraft.massivecore.xlib.bson.util.SimplePool<byte[]> _extra =
new com.massivecraft.massivecore.xlib.bson.util.SimplePool<byte[]>( ( 1024 * 1024 * 10 ) / BUF_SIZE ){
protected byte[] createNew(){
return new byte[BUF_SIZE];
}
};
}

View File

@ -1,202 +0,0 @@
// UTF8Encoding.java
/**
* from postgresql jdbc driver:
* postgresql-jdbc-9.0-801.src
Copyright (c) 1997-2008, PostgreSQL Global Development Group
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the PostgreSQL Global Development Group nor the names
of its contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*-------------------------------------------------------------------------
*
* Copyright (c) 2003-2008, PostgreSQL Global Development Group
*
* IDENTIFICATION
*
*
*-------------------------------------------------------------------------
*/
//package org.postgresql.core;
package com.massivecraft.massivecore.xlib.bson.io;
import java.io.IOException;
import java.text.MessageFormat;
class UTF8Encoding {
private static final int MIN_2_BYTES = 0x80;
private static final int MIN_3_BYTES = 0x800;
private static final int MIN_4_BYTES = 0x10000;
private static final int MAX_CODE_POINT = 0x10ffff;
private char[] decoderArray = new char[1024];
// helper for decode
private final static void checkByte(int ch, int pos, int len) throws IOException {
if ((ch & 0xc0) != 0x80)
throw new IOException(MessageFormat.format("Illegal UTF-8 sequence: byte {0} of {1} byte sequence is not 10xxxxxx: {2}",
new Object[] { new Integer(pos), new Integer(len), new Integer(ch) }));
}
private final static void checkMinimal(int ch, int minValue) throws IOException {
if (ch >= minValue)
return;
int actualLen;
switch (minValue) {
case MIN_2_BYTES:
actualLen = 2;
break;
case MIN_3_BYTES:
actualLen = 3;
break;
case MIN_4_BYTES:
actualLen = 4;
break;
default:
throw new IllegalArgumentException("unexpected minValue passed to checkMinimal: " + minValue);
}
int expectedLen;
if (ch < MIN_2_BYTES)
expectedLen = 1;
else if (ch < MIN_3_BYTES)
expectedLen = 2;
else if (ch < MIN_4_BYTES)
expectedLen = 3;
else
throw new IllegalArgumentException("unexpected ch passed to checkMinimal: " + ch);
throw new IOException(MessageFormat.format("Illegal UTF-8 sequence: {0} bytes used to encode a {1} byte value: {2}",
new Object[] { new Integer(actualLen), new Integer(expectedLen), new Integer(ch) }));
}
/**
* Custom byte[] -> String conversion routine for UTF-8 only.
* This is about twice as fast as using the String(byte[],int,int,String)
* ctor, at least under JDK 1.4.2. The extra checks for illegal representations
* add about 10-15% overhead, but they seem worth it given the number of SQL_ASCII
* databases out there.
*
* @param data the array containing UTF8-encoded data
* @param offset the offset of the first byte in <code>data</code> to decode from
* @param length the number of bytes to decode
* @return a decoded string
* @throws IOException if something goes wrong
*/
public synchronized String decode(byte[] data, int offset, int length) throws IOException {
char[] cdata = decoderArray;
if (cdata.length < length)
cdata = decoderArray = new char[length];
int in = offset;
int out = 0;
int end = length + offset;
try
{
while (in < end)
{
int ch = data[in++] & 0xff;
// Convert UTF-8 to 21-bit codepoint.
if (ch < 0x80) {
// 0xxxxxxx -- length 1.
} else if (ch < 0xc0) {
// 10xxxxxx -- illegal!
throw new IOException(MessageFormat.format("Illegal UTF-8 sequence: initial byte is {0}: {1}",
new Object[] { "10xxxxxx", new Integer(ch) }));
} else if (ch < 0xe0) {
// 110xxxxx 10xxxxxx
ch = ((ch & 0x1f) << 6);
checkByte(data[in], 2, 2);
ch = ch | (data[in++] & 0x3f);
checkMinimal(ch, MIN_2_BYTES);
} else if (ch < 0xf0) {
// 1110xxxx 10xxxxxx 10xxxxxx
ch = ((ch & 0x0f) << 12);
checkByte(data[in], 2, 3);
ch = ch | ((data[in++] & 0x3f) << 6);
checkByte(data[in], 3, 3);
ch = ch | (data[in++] & 0x3f);
checkMinimal(ch, MIN_3_BYTES);
} else if (ch < 0xf8) {
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
ch = ((ch & 0x07) << 18);
checkByte(data[in], 2, 4);
ch = ch | ((data[in++] & 0x3f) << 12);
checkByte(data[in], 3, 4);
ch = ch | ((data[in++] & 0x3f) << 6);
checkByte(data[in], 4, 4);
ch = ch | (data[in++] & 0x3f);
checkMinimal(ch, MIN_4_BYTES);
} else {
throw new IOException(MessageFormat.format("Illegal UTF-8 sequence: initial byte is {0}: {1}",
new Object[] { "11111xxx", new Integer(ch) }));
}
if (ch > MAX_CODE_POINT)
throw new IOException(MessageFormat.format("Illegal UTF-8 sequence: final value is out of range: {0}",
new Integer(ch)));
// Convert 21-bit codepoint to Java chars:
// 0..ffff are represented directly as a single char
// 10000..10ffff are represented as a "surrogate pair" of two chars
// See: http://java.sun.com/developer/technicalArticles/Intl/Supplementary/
if (ch > 0xffff) {
// Use a surrogate pair to represent it.
ch -= 0x10000; // ch is now 0..fffff (20 bits)
cdata[out++] = (char) (0xd800 + (ch >> 10)); // top 10 bits
cdata[out++] = (char) (0xdc00 + (ch & 0x3ff)); // bottom 10 bits
} else if (ch >= 0xd800 && ch < 0xe000) {
// Not allowed to encode the surrogate range directly.
throw new IOException(MessageFormat.format("Illegal UTF-8 sequence: final value is a surrogate value: {0}",
new Integer(ch)));
} else {
// Normal case.
cdata[out++] = (char) ch;
}
}
}
catch (ArrayIndexOutOfBoundsException a)
{
throw new IOException("Illegal UTF-8 sequence: multibyte sequence was truncated");
}
// Check if we ran past the end without seeing an exception.
if (in > end)
throw new IOException("Illegal UTF-8 sequence: multibyte sequence was truncated");
return new String(cdata, 0, out);
}
}

View File

@ -1,3 +0,0 @@
<body>
<p>Contains classes implementing I/O operations used by BSON objects.</p>
</body>

View File

@ -1,3 +0,0 @@
<body>
<p>Contains the base BSON classes and Encoder/Decoder.</p>
</body>

View File

@ -1,96 +0,0 @@
// BSONTimestamp.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.types;
import java.io.Serializable;
import java.util.Date;
/**
* this is used for internal increment values.
* for storing normal dates in MongoDB, you should use java.util.Date
* <b>time</b> is seconds since epoch
* <b>inc<b> is an ordinal
*/
public class BSONTimestamp implements Comparable<BSONTimestamp>, Serializable {
private static final long serialVersionUID = -3268482672267936464L;
static final boolean D = Boolean.getBoolean( "DEBUG.DBTIMESTAMP" );
public BSONTimestamp(){
_inc = 0;
_time = null;
}
public BSONTimestamp(int time, int inc ){
_time = new Date( time * 1000L );
_inc = inc;
}
/**
* @return get time in seconds since epoch
*/
public int getTime(){
if ( _time == null )
return 0;
return (int)(_time.getTime() / 1000);
}
public int getInc(){
return _inc;
}
public String toString(){
return "TS time:" + _time + " inc:" + _inc;
}
@Override
public int compareTo(BSONTimestamp ts) {
if(getTime() != ts.getTime()) {
return getTime() - ts.getTime();
}
else{
return getInc() - ts.getInc();
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + _inc;
result = prime * result + getTime();
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj instanceof BSONTimestamp) {
BSONTimestamp t2 = (BSONTimestamp) obj;
return getTime() == t2.getTime() && getInc() == t2.getInc();
}
return false;
}
final int _inc;
final Date _time;
}

View File

@ -1,164 +0,0 @@
// BasicBSONList.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.types;
import com.massivecraft.massivecore.xlib.bson.*;
import com.massivecraft.massivecore.xlib.bson.util.StringRangeSet;
import java.util.*;
/**
* Utility class to allow array <code>DBObject</code>s to be created.
* <p>
* Note: MongoDB will also create arrays from <code>java.util.List</code>s.
* </p>
* <p>
* <blockquote><pre>
* DBObject obj = new BasicBSONList();
* obj.put( "0", value1 );
* obj.put( "4", value2 );
* obj.put( 2, value3 );
* </pre></blockquote>
* This simulates the array [ value1, null, value3, null, value2 ] by creating the
* <code>DBObject</code> <code>{ "0" : value1, "1" : null, "2" : value3, "3" : null, "4" : value2 }</code>.
* </p>
* <p>
* BasicBSONList only supports numeric keys. Passing strings that cannot be converted to ints will cause an
* IllegalArgumentException.
* <blockquote><pre>
* BasicBSONList list = new BasicBSONList();
* list.put("1", "bar"); // ok
* list.put("1E1", "bar"); // throws exception
* </pre></blockquote>
* </p>
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class BasicBSONList extends ArrayList<Object> implements BSONObject {
private static final long serialVersionUID = -4415279469780082174L;
public BasicBSONList() { }
/**
* Puts a value at an index.
* For interface compatibility. Must be passed a String that is parsable to an int.
* @param key the index at which to insert the value
* @param v the value to insert
* @return the value
* @throws IllegalArgumentException if <code>key</code> cannot be parsed into an <code>int</code>
*/
public Object put( String key , Object v ){
return put(_getInt( key ), v);
}
/**
* Puts a value at an index.
* This will fill any unset indexes less than <code>index</code> with <code>null</code>.
* @param key the index at which to insert the value
* @param v the value to insert
* @return the value
*/
public Object put( int key, Object v ) {
while ( key >= size() )
add( null );
set( key , v );
return v;
}
public void putAll( Map m ){
for ( Map.Entry entry : (Set<Map.Entry>)m.entrySet() ){
put( entry.getKey().toString() , entry.getValue() );
}
}
public void putAll( BSONObject o ){
for ( String k : o.keySet() ){
put( k , o.get( k ) );
}
}
/**
* Gets a value at an index.
* For interface compatibility. Must be passed a String that is parsable to an int.
* @param key the index
* @return the value, if found, or null
* @throws IllegalArgumentException if <code>key</code> cannot be parsed into an <code>int</code>
*/
public Object get( String key ){
int i = _getInt( key );
if ( i < 0 )
return null;
if ( i >= size() )
return null;
return get( i );
}
public Object removeField( String key ){
int i = _getInt( key );
if ( i < 0 )
return null;
if ( i >= size() )
return null;
return remove( i );
}
/**
* @deprecated
*/
@Deprecated
public boolean containsKey( String key ){
return containsField(key);
}
public boolean containsField( String key ){
int i = _getInt( key , false );
if ( i < 0 )
return false;
return i >= 0 && i < size();
}
public Set<String> keySet(){
return new StringRangeSet(size());
}
public Map toMap() {
Map m = new HashMap();
Iterator i = this.keySet().iterator();
while (i.hasNext()) {
Object s = i.next();
m.put(s, this.get(String.valueOf(s)));
}
return m;
}
int _getInt( String s ){
return _getInt( s , true );
}
int _getInt( String s , boolean err ){
try {
return Integer.parseInt( s );
}
catch ( Exception e ){
if ( err )
throw new IllegalArgumentException( "BasicBSONList can only work with numeric keys, not: [" + s + "]" );
return -1;
}
}
}

View File

@ -1,98 +0,0 @@
// Binary.java
/**
* See the NOTICE.txt file distributed with this work for
* information regarding copyright ownership.
*
* The authors license this file to you 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 com.massivecraft.massivecore.xlib.bson.types;
import com.massivecraft.massivecore.xlib.bson.BSON;
import java.io.Serializable;
import java.util.Arrays;
/**
* generic binary holder
*/
public class Binary implements Serializable {
private static final long serialVersionUID = 7902997490338209467L;
/**
* Creates a Binary object with the default binary type of 0
*
* @param data raw data
*/
public Binary(byte[] data) {
this(BSON.B_GENERAL, data);
}
/**
* Creates a Binary object
*
* @param type type of the field as encoded in BSON
* @param data raw data
*/
public Binary(byte type, byte[] data) {
_type = type;
_data = data;
}
public byte getType() {
return _type;
}
public byte[] getData() {
return _data;
}
public int length() {
return _data.length;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Binary)) {
return false;
}
Binary binary = (Binary) o;
if (_type != binary._type) {
return false;
}
if (!Arrays.equals(_data, binary._data)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = (int) _type;
result = 31 * result + (_data != null ? Arrays.hashCode(_data) : 0);
return result;
}
final byte _type;
final byte[] _data;
}

View File

@ -1,58 +0,0 @@
// Code.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.types;
import java.io.Serializable;
/**
* for using the Code type
*/
public class Code implements Serializable {
private static final long serialVersionUID = 475535263314046697L;
public Code( String code ){
_code = code;
}
public String getCode(){
return _code;
}
public boolean equals( Object o ){
if ( ! ( o instanceof Code ) )
return false;
Code c = (Code)o;
return _code.equals( c._code );
}
public int hashCode(){
return _code.hashCode();
}
@Override
public String toString() {
return getCode();
}
final String _code;
}

View File

@ -1,53 +0,0 @@
// CodeWScope.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.types;
import com.massivecraft.massivecore.xlib.bson.*;
/**
* for using the CodeWScope type
*/
public class CodeWScope extends Code {
private static final long serialVersionUID = -6284832275113680002L;
public CodeWScope( String code , BSONObject scope ){
super( code );
_scope = scope;
}
public BSONObject getScope(){
return _scope;
}
public boolean equals( Object o ){
if ( ! ( o instanceof CodeWScope ) )
return false;
CodeWScope c = (CodeWScope)o;
return _code.equals( c._code ) && _scope.equals( c._scope );
}
public int hashCode(){
return _code.hashCode() ^ _scope.hashCode();
}
final BSONObject _scope;
}

View File

@ -1,47 +0,0 @@
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.types;
import java.io.Serializable;
/**
* Represent the maximum key value regardless of the key's type
*/
public class MaxKey implements Serializable {
private static final long serialVersionUID = 5123414776151687185L;
public MaxKey() {
}
@Override
public boolean equals(Object o) {
return o instanceof MaxKey;
}
@Override
public int hashCode() {
return 0;
}
@Override
public String toString() {
return "MaxKey";
}
}

View File

@ -1,47 +0,0 @@
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.types;
import java.io.Serializable;
/**
* Represent the minimum key value regardless of the key's type
*/
public class MinKey implements Serializable {
private static final long serialVersionUID = 4075901136671855684L;
public MinKey() {
}
@Override
public boolean equals(Object o) {
return o instanceof MinKey;
}
@Override
public int hashCode() {
return 0;
}
@Override
public String toString() {
return "MinKey";
}
}

View File

@ -1,401 +0,0 @@
// ObjectId.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.types;
import java.net.*;
import java.nio.*;
import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.logging.*;
/**
* A globally unique identifier for objects.
* <p>Consists of 12 bytes, divided as follows:
* <blockquote><pre>
* <table border="1">
* <tr><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td>
* <td>7</td><td>8</td><td>9</td><td>10</td><td>11</td></tr>
* <tr><td colspan="4">time</td><td colspan="3">machine</td>
* <td colspan="2">pid</td><td colspan="3">inc</td></tr>
* </table>
* </pre></blockquote>
*
* @dochub objectids
*/
public class ObjectId implements Comparable<ObjectId> , java.io.Serializable {
private static final long serialVersionUID = -4415279469780082174L;
static final Logger LOGGER = Logger.getLogger( "org.bson.ObjectId" );
/** Gets a new object id.
* @return the new id
*/
public static ObjectId get(){
return new ObjectId();
}
/** Checks if a string could be an <code>ObjectId</code>.
* @return whether the string could be an object id
*/
public static boolean isValid( String s ){
if ( s == null )
return false;
final int len = s.length();
if ( len != 24 )
return false;
for ( int i=0; i<len; i++ ){
char c = s.charAt( i );
if ( c >= '0' && c <= '9' )
continue;
if ( c >= 'a' && c <= 'f' )
continue;
if ( c >= 'A' && c <= 'F' )
continue;
return false;
}
return true;
}
/** Turn an object into an <code>ObjectId</code>, if possible.
* Strings will be converted into <code>ObjectId</code>s, if possible, and <code>ObjectId</code>s will
* be cast and returned. Passing in <code>null</code> returns <code>null</code>.
* @param o the object to convert
* @return an <code>ObjectId</code> if it can be massaged, null otherwise
*/
public static ObjectId massageToObjectId( Object o ){
if ( o == null )
return null;
if ( o instanceof ObjectId )
return (ObjectId)o;
if ( o instanceof String ){
String s = o.toString();
if ( isValid( s ) )
return new ObjectId( s );
}
return null;
}
public ObjectId( Date time ){
this(time, _genmachine, _nextInc.getAndIncrement());
}
public ObjectId( Date time , int inc ){
this( time , _genmachine , inc );
}
public ObjectId( Date time , int machine , int inc ){
_time = (int)(time.getTime() / 1000);
_machine = machine;
_inc = inc;
_new = false;
}
/** Creates a new instance from a string.
* @param s the string to convert
* @throws IllegalArgumentException if the string is not a valid id
*/
public ObjectId( String s ){
this( s , false );
}
public ObjectId( String s , boolean babble ){
if ( ! isValid( s ) )
throw new IllegalArgumentException( "invalid ObjectId [" + s + "]" );
if ( babble )
s = babbleToMongod( s );
byte b[] = new byte[12];
for ( int i=0; i<b.length; i++ ){
b[i] = (byte)Integer.parseInt( s.substring( i*2 , i*2 + 2) , 16 );
}
ByteBuffer bb = ByteBuffer.wrap( b );
_time = bb.getInt();
_machine = bb.getInt();
_inc = bb.getInt();
_new = false;
}
public ObjectId( byte[] b ){
if ( b.length != 12 )
throw new IllegalArgumentException( "need 12 bytes" );
ByteBuffer bb = ByteBuffer.wrap( b );
_time = bb.getInt();
_machine = bb.getInt();
_inc = bb.getInt();
_new = false;
}
/**
* Creates an ObjectId
* @param time time in seconds
* @param machine machine ID
* @param inc incremental value
*/
public ObjectId( int time , int machine , int inc ){
_time = time;
_machine = machine;
_inc = inc;
_new = false;
}
/** Create a new object id.
*/
public ObjectId(){
_time = (int) (System.currentTimeMillis() / 1000);
_machine = _genmachine;
_inc = _nextInc.getAndIncrement();
_new = true;
}
public int hashCode(){
int x = _time;
x += ( _machine * 111 );
x += ( _inc * 17 );
return x;
}
public boolean equals( Object o ){
if ( this == o )
return true;
ObjectId other = massageToObjectId( o );
if ( other == null )
return false;
return
_time == other._time &&
_machine == other._machine &&
_inc == other._inc;
}
public String toStringBabble(){
return babbleToMongod( toStringMongod() );
}
public String toStringMongod(){
byte b[] = toByteArray();
StringBuilder buf = new StringBuilder(24);
for ( int i=0; i<b.length; i++ ){
int x = b[i] & 0xFF;
String s = Integer.toHexString( x );
if ( s.length() == 1 )
buf.append( "0" );
buf.append( s );
}
return buf.toString();
}
public byte[] toByteArray(){
byte b[] = new byte[12];
ByteBuffer bb = ByteBuffer.wrap( b );
// by default BB is big endian like we need
bb.putInt( _time );
bb.putInt( _machine );
bb.putInt( _inc );
return b;
}
static String _pos( String s , int p ){
return s.substring( p * 2 , ( p * 2 ) + 2 );
}
public static String babbleToMongod( String b ){
if ( ! isValid( b ) )
throw new IllegalArgumentException( "invalid object id: " + b );
StringBuilder buf = new StringBuilder( 24 );
for ( int i=7; i>=0; i-- )
buf.append( _pos( b , i ) );
for ( int i=11; i>=8; i-- )
buf.append( _pos( b , i ) );
return buf.toString();
}
public String toString(){
return toStringMongod();
}
int _compareUnsigned( int i , int j ){
long li = 0xFFFFFFFFL;
li = i & li;
long lj = 0xFFFFFFFFL;
lj = j & lj;
long diff = li - lj;
if (diff < Integer.MIN_VALUE)
return Integer.MIN_VALUE;
if (diff > Integer.MAX_VALUE)
return Integer.MAX_VALUE;
return (int) diff;
}
public int compareTo( ObjectId id ){
if ( id == null )
return -1;
int x = _compareUnsigned( _time , id._time );
if ( x != 0 )
return x;
x = _compareUnsigned( _machine , id._machine );
if ( x != 0 )
return x;
return _compareUnsigned( _inc , id._inc );
}
public int getMachine(){
return _machine;
}
/**
* Gets the time of this ID, in milliseconds
*/
public long getTime(){
return _time * 1000L;
}
/**
* Gets the time of this ID, in seconds
*/
public int getTimeSecond(){
return _time;
}
public int getInc(){
return _inc;
}
public int _time(){
return _time;
}
public int _machine(){
return _machine;
}
public int _inc(){
return _inc;
}
public boolean isNew(){
return _new;
}
public void notNew(){
_new = false;
}
/**
* Gets the generated machine ID, identifying the machine / process / class loader
*/
public static int getGenMachineId() {
return _genmachine;
}
/**
* Gets the current value of the auto increment
*/
public static int getCurrentInc() {
return _nextInc.get();
}
final int _time;
final int _machine;
final int _inc;
boolean _new;
public static int _flip( int x ){
int z = 0;
z |= ( ( x << 24 ) & 0xFF000000 );
z |= ( ( x << 8 ) & 0x00FF0000 );
z |= ( ( x >> 8 ) & 0x0000FF00 );
z |= ( ( x >> 24 ) & 0x000000FF );
return z;
}
private static AtomicInteger _nextInc = new AtomicInteger( (new java.util.Random()).nextInt() );
private static final int _genmachine;
static {
try {
// build a 2-byte machine piece based on NICs info
int machinePiece;
{
try {
StringBuilder sb = new StringBuilder();
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
while ( e.hasMoreElements() ){
NetworkInterface ni = e.nextElement();
sb.append( ni.toString() );
}
machinePiece = sb.toString().hashCode() << 16;
} catch (Throwable e) {
// exception sometimes happens with IBM JVM, use random
LOGGER.log(Level.WARNING, e.getMessage(), e);
machinePiece = (new Random().nextInt()) << 16;
}
LOGGER.fine( "machine piece post: " + Integer.toHexString( machinePiece ) );
}
// add a 2 byte process piece. It must represent not only the JVM but the class loader.
// Since static var belong to class loader there could be collisions otherwise
final int processPiece;
{
int processId = new java.util.Random().nextInt();
try {
processId = java.lang.management.ManagementFactory.getRuntimeMXBean().getName().hashCode();
}
catch ( Throwable t ){
}
ClassLoader loader = ObjectId.class.getClassLoader();
int loaderId = loader != null ? System.identityHashCode(loader) : 0;
StringBuilder sb = new StringBuilder();
sb.append(Integer.toHexString(processId));
sb.append(Integer.toHexString(loaderId));
processPiece = sb.toString().hashCode() & 0xFFFF;
LOGGER.fine( "process piece: " + Integer.toHexString( processPiece ) );
}
_genmachine = machinePiece | processPiece;
LOGGER.fine( "machine : " + Integer.toHexString( _genmachine ) );
}
catch ( Exception e ){
throw new RuntimeException( e );
}
}
}

View File

@ -1,74 +0,0 @@
// Symbol.java
/**
* Copyright (C) 2009 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.types;
import java.io.Serializable;
/**
* Class to hold a BSON symbol object, which is an interned string in Ruby
*/
public class Symbol implements Serializable {
private static final long serialVersionUID = 1326269319883146072L;
public Symbol(String s) {
_symbol = s;
}
public String getSymbol(){
return _symbol;
}
/**
* Will compare equal to a String that is equal to the String that this holds
* @param o
* @return
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
String otherSymbol;
if (o instanceof Symbol) {
otherSymbol = ((Symbol) o)._symbol;
}
else if (o instanceof String) {
otherSymbol = (String) o;
}
else {
return false;
}
if (_symbol != null ? !_symbol.equals(otherSymbol) : otherSymbol != null) return false;
return true;
}
@Override
public int hashCode() {
return _symbol != null ? _symbol.hashCode() : 0;
}
public String toString(){
return _symbol;
}
private final String _symbol;
}

View File

@ -1,3 +0,0 @@
<body>
<p>Contains classes implementing various BSON types.</p>
</body>

View File

@ -1,631 +0,0 @@
/**
* Copyright 2008 Atlassian Pty Ltd
*
* 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 com.massivecraft.massivecore.xlib.bson.util;
import static com.massivecraft.massivecore.xlib.bson.util.Assertions.notNull;
import static java.util.Collections.unmodifiableCollection;
import static java.util.Collections.unmodifiableSet;
import com.massivecraft.massivecore.xlib.bson.util.annotations.GuardedBy;
import com.massivecraft.massivecore.xlib.bson.util.annotations.ThreadSafe;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Abstract base class for COW {@link Map} implementations that delegate to an
* internal map.
*
* @param <K> The key type
* @param <V> The value type
* @param <M> the internal {@link Map} or extension for things like sorted and
* navigable maps.
*/
@ThreadSafe
abstract class AbstractCopyOnWriteMap<K, V, M extends Map<K, V>> implements ConcurrentMap<K, V>, Serializable {
private static final long serialVersionUID = 4508989182041753878L;
@GuardedBy("lock")
private volatile M delegate;
// import edu.umd.cs.findbugs.annotations.@SuppressWarnings
private final transient Lock lock = new ReentrantLock();
// private final transient EntrySet entrySet = new EntrySet();
// private final transient KeySet keySet = new KeySet();
// private final transient Values values = new Values();
// private final View.Type viewType;
private final View<K, V> view;
/**
* Create a new {@link CopyOnWriteMap} with the supplied {@link Map} to
* initialize the values.
*
* @param map the initial map to initialize with
* @param viewType for writable or read-only key, value and entrySet views
*/
protected <N extends Map<? extends K, ? extends V>> AbstractCopyOnWriteMap(final N map, final View.Type viewType) {
this.delegate = notNull("delegate", copy(notNull("map", map)));
this.view = notNull("viewType", viewType).get(this);
}
/**
* Copy function, implemented by sub-classes.
*
* @param <N> the map to copy and return.
* @param map the initial values of the newly created map.
* @return a new map. Will never be modified after construction.
*/
@GuardedBy("lock")
abstract <N extends Map<? extends K, ? extends V>> M copy(N map);
//
// mutable operations
//
public final void clear() {
lock.lock();
try {
set(copy(Collections.<K, V> emptyMap()));
} finally {
lock.unlock();
}
}
public final V remove(final Object key) {
lock.lock();
try {
// short circuit if key doesn't exist
if (!delegate.containsKey(key)) {
return null;
}
final M map = copy();
try {
return map.remove(key);
} finally {
set(map);
}
} finally {
lock.unlock();
}
}
public boolean remove(final Object key, final Object value) {
lock.lock();
try {
if (delegate.containsKey(key) && equals(value, delegate.get(key))) {
final M map = copy();
map.remove(key);
set(map);
return true;
} else {
return false;
}
} finally {
lock.unlock();
}
}
public boolean replace(final K key, final V oldValue, final V newValue) {
lock.lock();
try {
if (!delegate.containsKey(key) || !equals(oldValue, delegate.get(key))) {
return false;
}
final M map = copy();
map.put(key, newValue);
set(map);
return true;
} finally {
lock.unlock();
}
}
public V replace(final K key, final V value) {
lock.lock();
try {
if (!delegate.containsKey(key)) {
return null;
}
final M map = copy();
try {
return map.put(key, value);
} finally {
set(map);
}
} finally {
lock.unlock();
}
}
public final V put(final K key, final V value) {
lock.lock();
try {
final M map = copy();
try {
return map.put(key, value);
} finally {
set(map);
}
} finally {
lock.unlock();
}
}
public V putIfAbsent(final K key, final V value) {
lock.lock();
try {
if (!delegate.containsKey(key)) {
final M map = copy();
try {
return map.put(key, value);
} finally {
set(map);
}
}
return delegate.get(key);
} finally {
lock.unlock();
}
}
public final void putAll(final Map<? extends K, ? extends V> t) {
lock.lock();
try {
final M map = copy();
map.putAll(t);
set(map);
} finally {
lock.unlock();
}
}
protected M copy() {
lock.lock();
try {
return copy(delegate);
} finally {
lock.unlock();
}
}
@GuardedBy("lock")
protected void set(final M map) {
delegate = map;
}
//
// Collection views
//
public final Set<Map.Entry<K, V>> entrySet() {
return view.entrySet();
}
public final Set<K> keySet() {
return view.keySet();
}
public final Collection<V> values() {
return view.values();
}
//
// delegate operations
//
public final boolean containsKey(final Object key) {
return delegate.containsKey(key);
}
public final boolean containsValue(final Object value) {
return delegate.containsValue(value);
}
public final V get(final Object key) {
return delegate.get(key);
}
public final boolean isEmpty() {
return delegate.isEmpty();
}
public final int size() {
return delegate.size();
}
@Override
public final boolean equals(final Object o) {
return delegate.equals(o);
}
@Override
public final int hashCode() {
return delegate.hashCode();
}
protected final M getDelegate() {
return delegate;
}
@Override
public String toString() {
return delegate.toString();
}
//
// inner classes
//
private class KeySet extends CollectionView<K> implements Set<K> {
@Override
Collection<K> getDelegate() {
return delegate.keySet();
}
//
// mutable operations
//
public void clear() {
lock.lock();
try {
final M map = copy();
map.keySet().clear();
set(map);
} finally {
lock.unlock();
}
}
public boolean remove(final Object o) {
return AbstractCopyOnWriteMap.this.remove(o) != null;
}
public boolean removeAll(final Collection<?> c) {
lock.lock();
try {
final M map = copy();
try {
return map.keySet().removeAll(c);
} finally {
set(map);
}
} finally {
lock.unlock();
}
}
public boolean retainAll(final Collection<?> c) {
lock.lock();
try {
final M map = copy();
try {
return map.keySet().retainAll(c);
} finally {
set(map);
}
} finally {
lock.unlock();
}
}
}
private final class Values extends CollectionView<V> {
@Override
Collection<V> getDelegate() {
return delegate.values();
}
public void clear() {
lock.lock();
try {
final M map = copy();
map.values().clear();
set(map);
} finally {
lock.unlock();
}
}
public boolean remove(final Object o) {
lock.lock();
try {
if (!contains(o)) {
return false;
}
final M map = copy();
try {
return map.values().remove(o);
} finally {
set(map);
}
} finally {
lock.unlock();
}
}
public boolean removeAll(final Collection<?> c) {
lock.lock();
try {
final M map = copy();
try {
return map.values().removeAll(c);
} finally {
set(map);
}
} finally {
lock.unlock();
}
}
public boolean retainAll(final Collection<?> c) {
lock.lock();
try {
final M map = copy();
try {
return map.values().retainAll(c);
} finally {
set(map);
}
} finally {
lock.unlock();
}
}
}
private class EntrySet extends CollectionView<Entry<K, V>> implements Set<Map.Entry<K, V>> {
@Override
Collection<java.util.Map.Entry<K, V>> getDelegate() {
return delegate.entrySet();
}
public void clear() {
lock.lock();
try {
final M map = copy();
map.entrySet().clear();
set(map);
} finally {
lock.unlock();
}
}
public boolean remove(final Object o) {
lock.lock();
try {
if (!contains(o)) {
return false;
}
final M map = copy();
try {
return map.entrySet().remove(o);
} finally {
set(map);
}
} finally {
lock.unlock();
}
}
public boolean removeAll(final Collection<?> c) {
lock.lock();
try {
final M map = copy();
try {
return map.entrySet().removeAll(c);
} finally {
set(map);
}
} finally {
lock.unlock();
}
}
public boolean retainAll(final Collection<?> c) {
lock.lock();
try {
final M map = copy();
try {
return map.entrySet().retainAll(c);
} finally {
set(map);
}
} finally {
lock.unlock();
}
}
}
private static class UnmodifiableIterator<T> implements Iterator<T> {
private final Iterator<T> delegate;
public UnmodifiableIterator(final Iterator<T> delegate) {
this.delegate = delegate;
}
public boolean hasNext() {
return delegate.hasNext();
}
public T next() {
return delegate.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
protected static abstract class CollectionView<E> implements Collection<E> {
abstract Collection<E> getDelegate();
//
// delegate operations
//
public final boolean contains(final Object o) {
return getDelegate().contains(o);
}
public final boolean containsAll(final Collection<?> c) {
return getDelegate().containsAll(c);
}
public final Iterator<E> iterator() {
return new UnmodifiableIterator<E>(getDelegate().iterator());
}
public final boolean isEmpty() {
return getDelegate().isEmpty();
}
public final int size() {
return getDelegate().size();
}
public final Object[] toArray() {
return getDelegate().toArray();
}
public final <T> T[] toArray(final T[] a) {
return getDelegate().toArray(a);
}
@Override
public int hashCode() {
return getDelegate().hashCode();
}
@Override
public boolean equals(final Object obj) {
return getDelegate().equals(obj);
}
@Override
public String toString() {
return getDelegate().toString();
}
//
// unsupported operations
//
public final boolean add(final E o) {
throw new UnsupportedOperationException();
}
public final boolean addAll(final Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
}
private boolean equals(final Object o1, final Object o2) {
if (o1 == null) {
return o2 == null;
}
return o1.equals(o2);
}
/**
* Provides access to the views of the underlying key, value and entry
* collections.
*/
public static abstract class View<K, V> {
View() {}
abstract Set<K> keySet();
abstract Set<Entry<K, V>> entrySet();
abstract Collection<V> values();
/**
* The different types of {@link View} available
*/
public enum Type {
STABLE {
@Override
<K, V, M extends Map<K, V>> View<K, V> get(final AbstractCopyOnWriteMap<K, V, M> host) {
return host.new Immutable();
}
},
LIVE {
@Override
<K, V, M extends Map<K, V>> View<K, V> get(final AbstractCopyOnWriteMap<K, V, M> host) {
return host.new Mutable();
}
};
abstract <K, V, M extends Map<K, V>> View<K, V> get(AbstractCopyOnWriteMap<K, V, M> host);
}
}
final class Immutable extends View<K, V> implements Serializable {
private static final long serialVersionUID = -4158727180429303818L;
@Override
public Set<K> keySet() {
return unmodifiableSet(delegate.keySet());
}
@Override
public Set<Entry<K, V>> entrySet() {
return unmodifiableSet(delegate.entrySet());
}
@Override
public Collection<V> values() {
return unmodifiableCollection(delegate.values());
}
}
final class Mutable extends View<K, V> implements Serializable {
private static final long serialVersionUID = 1624520291194797634L;
private final transient KeySet keySet = new KeySet();
private final transient EntrySet entrySet = new EntrySet();
private final transient Values values = new Values();
@Override
public Set<K> keySet() {
return keySet;
}
@Override
public Set<Entry<K, V>> entrySet() {
return entrySet;
}
@Override
public Collection<V> values() {
return values;
}
}
}

View File

@ -1,48 +0,0 @@
/**
* Copyright 2008 Atlassian Pty Ltd
*
* 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 com.massivecraft.massivecore.xlib.bson.util;
/**
* Design by contract assertions.
*/
public class Assertions {
public static <T> T notNull(final String name, final T notNull) throws IllegalArgumentException {
if (notNull == null) {
throw new NullArgumentException(name);
}
return notNull;
}
public static void isTrue(final String name, final boolean check) throws IllegalArgumentException {
if (!check) {
throw new IllegalArgumentException(name);
}
}
// /CLOVER:OFF
private Assertions() {}
// /CLOVER:ON
static class NullArgumentException extends IllegalArgumentException {
private static final long serialVersionUID = 6178592463723624585L;
NullArgumentException(final String name) {
super(name + " should not be null!");
}
}
}

View File

@ -1,72 +0,0 @@
package com.massivecraft.massivecore.xlib.bson.util;
import static com.massivecraft.massivecore.xlib.bson.util.CopyOnWriteMap.newHashMap;
import static java.util.Collections.unmodifiableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
class ClassAncestry {
/**
* getAncestry
*
* Walks superclass and interface graph, superclasses first, then
* interfaces, to compute an ancestry list. Supertypes are visited left to
* right. Duplicates are removed such that no Class will appear in the list
* before one of its subtypes.
*
* Does not need to be synchronized, races are harmless as the Class graph
* does not change at runtime.
*/
public static <T> List<Class<?>> getAncestry(Class<T> c) {
final ConcurrentMap<Class<?>, List<Class<?>>> cache = getClassAncestryCache();
while (true) {
List<Class<?>> cachedResult = cache.get(c);
if (cachedResult != null) {
return cachedResult;
}
cache.putIfAbsent(c, computeAncestry(c));
}
}
/**
* computeAncestry, starting with children and going back to parents
*/
private static List<Class<?>> computeAncestry(Class<?> c) {
final List<Class<?>> result = new ArrayList<Class<?>>();
result.add(Object.class);
computeAncestry(c, result);
Collections.reverse(result);
return unmodifiableList(new ArrayList<Class<?>>(result));
}
private static <T> void computeAncestry(Class<T> c, List<Class<?>> result) {
if ((c == null) || (c == Object.class)) {
return;
}
// first interfaces (looks backwards but is not)
Class<?>[] interfaces = c.getInterfaces();
for (int i = interfaces.length - 1; i >= 0; i--) {
computeAncestry(interfaces[i], result);
}
// next superclass
computeAncestry(c.getSuperclass(), result);
if (!result.contains(c))
result.add(c);
}
/**
* classAncestryCache
*/
private static ConcurrentMap<Class<?>, List<Class<?>>> getClassAncestryCache() {
return (_ancestryCache);
}
private static final ConcurrentMap<Class<?>, List<Class<?>>> _ancestryCache = newHashMap();
}

View File

@ -1,100 +0,0 @@
// ClassMap.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.util;
import java.util.List;
import java.util.Map;
/**
* Maps Class objects to values. A ClassMap is different from a regular Map in
* that get(c) does not only look to see if 'c' is a key in the Map, but also
* walks the up superclass and interface graph of 'c' to find matches. Derived
* matches of this sort are then "cached" in the registry so that matches are
* faster on future gets.
*
* This is a very useful class for Class based registries.
*
* Example:
*
* ClassMap<String> m = new ClassMap<String>(); m.put(Animal.class, "Animal");
* m.put(Fox.class, "Fox"); m.Fox.class) --> "Fox" m.get(Dog.class) --> "Animal"
*
* (assuming Dog.class &lt; Animal.class)
*/
public class ClassMap<T> {
/**
* Walks superclass and interface graph, superclasses first, then
* interfaces, to compute an ancestry list. Supertypes are visited left to
* right. Duplicates are removed such that no Class will appear in the list
* before one of its subtypes.
*/
public static <T> List<Class<?>> getAncestry(Class<T> c) {
return ClassAncestry.getAncestry(c);
}
private final class ComputeFunction implements Function<Class<?>, T> {
@Override
public T apply(Class<?> a) {
for (Class<?> cls : getAncestry(a)) {
T result = map.get(cls);
if (result != null) {
return result;
}
}
return null;
}
};
private final Map<Class<?>, T> map = CopyOnWriteMap.newHashMap();
private final Map<Class<?>, T> cache = ComputingMap.create(new ComputeFunction());
public T get(Object key) {
return cache.get(key);
}
public T put(Class<?> key, T value) {
try {
return map.put(key, value);
} finally {
cache.clear();
}
}
public T remove(Object key) {
try {
return map.remove(key);
} finally {
cache.clear();
}
}
public void clear() {
map.clear();
cache.clear();
}
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.isEmpty();
}
}

View File

@ -1,109 +0,0 @@
package com.massivecraft.massivecore.xlib.bson.util;
import static com.massivecraft.massivecore.xlib.bson.util.Assertions.notNull;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
final class ComputingMap<K, V> implements Map<K, V>, Function<K, V> {
public static <K, V> Map<K, V> create(Function<K, V> function) {
return new ComputingMap<K, V>(CopyOnWriteMap.<K, V> newHashMap(), function);
}
private final ConcurrentMap<K, V> map;
private final Function<K, V> function;
ComputingMap(ConcurrentMap<K, V> map, Function<K, V> function) {
this.map = notNull("map", map);
this.function = notNull("function", function);
}
public V get(Object key) {
while (true) {
V v = map.get(key);
if (v != null)
return v;
@SuppressWarnings("unchecked")
K k = (K) key;
V value = function.apply(k);
if (value == null)
return null;
map.putIfAbsent(k, value);
}
}
public V apply(K k) {
return get(k);
}
public V putIfAbsent(K key, V value) {
return map.putIfAbsent(key, value);
}
public boolean remove(Object key, Object value) {
return map.remove(key, value);
}
public boolean replace(K key, V oldValue, V newValue) {
return map.replace(key, oldValue, newValue);
}
public V replace(K key, V value) {
return map.replace(key, value);
}
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.isEmpty();
}
public boolean containsKey(Object key) {
return map.containsKey(key);
}
public boolean containsValue(Object value) {
return map.containsValue(value);
}
public V put(K key, V value) {
return map.put(key, value);
}
public V remove(Object key) {
return map.remove(key);
}
public void putAll(Map<? extends K, ? extends V> m) {
map.putAll(m);
}
public void clear() {
map.clear();
}
public Set<K> keySet() {
return map.keySet();
}
public Collection<V> values() {
return map.values();
}
public Set<java.util.Map.Entry<K, V>> entrySet() {
return map.entrySet();
}
public boolean equals(Object o) {
return map.equals(o);
}
public int hashCode() {
return map.hashCode();
}
}

View File

@ -1,272 +0,0 @@
/**
* Copyright 2008 Atlassian Pty Ltd
*
* 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 com.massivecraft.massivecore.xlib.bson.util;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.WeakHashMap;
import com.massivecraft.massivecore.xlib.bson.util.AbstractCopyOnWriteMap.View.Type;
import com.massivecraft.massivecore.xlib.bson.util.annotations.GuardedBy;
import com.massivecraft.massivecore.xlib.bson.util.annotations.ThreadSafe;
/**
* A thread-safe variant of {@link Map} in which all mutative operations (the
* "destructive" operations described by {@link Map} put, remove and so on) are
* implemented by making a fresh copy of the underlying map.
* <p>
* This is ordinarily too costly, but may be <em>more</em> efficient than
* alternatives when traversal operations vastly out-number mutations, and is
* useful when you cannot or don't want to synchronize traversals, yet need to
* preclude interference among concurrent threads. The "snapshot" style
* iterators on the collections returned by {@link #entrySet()},
* {@link #keySet()} and {@link #values()} use a reference to the internal map
* at the point that the iterator was created. This map never changes during the
* lifetime of the iterator, so interference is impossible and the iterator is
* guaranteed not to throw <tt>ConcurrentModificationException</tt>. The
* iterators will not reflect additions, removals, or changes to the list since
* the iterator was created. Removing elements via these iterators is not
* supported. The mutable operations on these collections (remove, retain etc.)
* are supported but as with the {@link Map} interface, add and addAll are not
* and throw {@link UnsupportedOperationException}.
* <p>
* The actual copy is performed by an abstract {@link #copy(Map)} method. The
* method is responsible for the underlying Map implementation (for instance a
* {@link HashMap}, {@link TreeMap}, {@link LinkedHashMap} etc.) and therefore
* the semantics of what this map will cope with as far as null keys and values,
* iteration ordering etc. See the note below about suitable candidates for
* underlying Map implementations
* <p>
* There are supplied implementations for the common j.u.c {@link Map}
* implementations via the {@link CopyOnWriteMap} static {@link Builder}.
* <p>
* Collection views of the keys, values and entries are optionally
* {@link View.Type.LIVE live} or {@link View.Type.STABLE stable}. Live views
* are modifiable will cause a copy if a modifying method is called on them.
* Methods on these will reflect the current state of the collection, although
* iterators will be snapshot style. If the collection views are stable they are
* unmodifiable, and will be a snapshot of the state of the map at the time the
* collection was asked for.
* <p>
* <strong>Please note</strong> that the thread-safety guarantees are limited to
* the thread-safety of the non-mutative (non-destructive) operations of the
* underlying map implementation. For instance some implementations such as
* {@link WeakHashMap} and {@link LinkedHashMap} with access ordering are
* actually structurally modified by the {@link #get(Object)} method and are
* therefore not suitable candidates as delegates for this class.
*
* @param <K> the key type
* @param <V> the value type
* @author Jed Wesley-Smith
*/
@ThreadSafe
abstract class CopyOnWriteMap<K, V> extends AbstractCopyOnWriteMap<K, V, Map<K, V>> {
private static final long serialVersionUID = 7935514534647505917L;
/**
* Get a {@link Builder} for a {@link CopyOnWriteMap} instance.
*
* @param <K> key type
* @param <V> value type
* @return a fresh builder
*/
public static <K, V> Builder<K, V> builder() {
return new Builder<K, V>();
}
/**
* Build a {@link CopyOnWriteMap} and specify all the options.
*
* @param <K> key type
* @param <V> value type
*/
public static class Builder<K, V> {
private View.Type viewType = View.Type.STABLE;
private final Map<K, V> initialValues = new HashMap<K, V>();
Builder() {}
/**
* Views are stable (fixed in time) and unmodifiable.
*/
public Builder<K, V> stableViews() {
viewType = View.Type.STABLE;
return this;
}
/**
* Views are live (reflecting concurrent updates) and mutator methods
* are supported.
*/
public Builder<K, V> addAll(final Map<? extends K, ? extends V> values) {
initialValues.putAll(values);
return this;
}
/**
* Views are live (reflecting concurrent updates) and mutator methods
* are supported.
*/
public Builder<K, V> liveViews() {
viewType = View.Type.LIVE;
return this;
}
public CopyOnWriteMap<K, V> newHashMap() {
return new Hash<K, V>(initialValues, viewType);
}
public CopyOnWriteMap<K, V> newLinkedMap() {
return new Linked<K, V>(initialValues, viewType);
}
}
/**
* Creates a new {@link CopyOnWriteMap} with an underlying {@link HashMap}.
* <p>
* This map has {@link View.Type.STABLE stable} views.
*/
public static <K, V> CopyOnWriteMap<K, V> newHashMap() {
final Builder<K, V> builder = builder();
return builder.newHashMap();
}
/**
* Creates a new {@link CopyOnWriteMap} with an underlying {@link HashMap}
* using the supplied map as the initial values.
* <p>
* This map has {@link View.Type.STABLE stable} views.
*/
public static <K, V> CopyOnWriteMap<K, V> newHashMap(final Map<? extends K, ? extends V> map) {
final Builder<K, V> builder = builder();
return builder.addAll(map).newHashMap();
}
/**
* Creates a new {@link CopyOnWriteMap} with an underlying
* {@link LinkedHashMap}. Iterators for this map will be return elements in
* insertion order.
* <p>
* This map has {@link View.Type.STABLE stable} views.
*/
public static <K, V> CopyOnWriteMap<K, V> newLinkedMap() {
final Builder<K, V> builder = builder();
return builder.newLinkedMap();
}
/**
* Creates a new {@link CopyOnWriteMap} with an underlying
* {@link LinkedHashMap} using the supplied map as the initial values.
* Iterators for this map will be return elements in insertion order.
* <p>
* This map has {@link View.Type.STABLE stable} views.
*/
public static <K, V> CopyOnWriteMap<K, V> newLinkedMap(final Map<? extends K, ? extends V> map) {
final Builder<K, V> builder = builder();
return builder.addAll(map).newLinkedMap();
}
//
// constructors
//
/**
* Create a new {@link CopyOnWriteMap} with the supplied {@link Map} to
* initialize the values.
*
* @param map the initial map to initialize with
* @deprecated since 0.0.12 use the versions that explicitly specify
* View.Type
*/
@Deprecated
protected CopyOnWriteMap(final Map<? extends K, ? extends V> map) {
this(map, View.Type.LIVE);
}
/**
* Create a new empty {@link CopyOnWriteMap}.
*
* @deprecated since 0.0.12 use the versions that explicitly specify
* View.Type
*/
@Deprecated
protected CopyOnWriteMap() {
this(Collections.<K, V> emptyMap(), View.Type.LIVE);
}
/**
* Create a new {@link CopyOnWriteMap} with the supplied {@link Map} to
* initialize the values. This map may be optionally modified using any of
* the key, entry or value views
*
* @param map the initial map to initialize with
*/
protected CopyOnWriteMap(final Map<? extends K, ? extends V> map, final View.Type viewType) {
super(map, viewType);
}
/**
* Create a new empty {@link CopyOnWriteMap}. This map may be optionally
* modified using any of the key, entry or value views
*/
protected CopyOnWriteMap(final View.Type viewType) {
super(Collections.<K, V> emptyMap(), viewType);
}
@Override
@GuardedBy("internal-lock")
protected abstract <N extends Map<? extends K, ? extends V>> Map<K, V> copy(N map);
//
// inner classes
//
/**
* Uses {@link HashMap} instances as its internal storage.
*/
static class Hash<K, V> extends CopyOnWriteMap<K, V> {
private static final long serialVersionUID = 5221824943734164497L;
Hash(final Map<? extends K, ? extends V> map, final Type viewType) {
super(map, viewType);
}
@Override
public <N extends Map<? extends K, ? extends V>> Map<K, V> copy(final N map) {
return new HashMap<K, V>(map);
}
}
/**
* Uses {@link LinkedHashMap} instances as its internal storage.
*/
static class Linked<K, V> extends CopyOnWriteMap<K, V> {
private static final long serialVersionUID = -8659999465009072124L;
Linked(final Map<? extends K, ? extends V> map, final Type viewType) {
super(map, viewType);
}
@Override
public <N extends Map<? extends K, ? extends V>> Map<K, V> copy(final N map) {
return new LinkedHashMap<K, V>(map);
}
}
}

View File

@ -1,5 +0,0 @@
package com.massivecraft.massivecore.xlib.bson.util;
interface Function<A, B> {
B apply(A a);
}

View File

@ -1,58 +0,0 @@
// SimplePool.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.util;
import java.util.*;
import java.util.concurrent.*;
public abstract class SimplePool<T> {
public SimplePool( int max ){
_max = max;
}
public SimplePool(){
_max = 1000;
}
protected abstract T createNew();
protected boolean ok( T t ){
return true;
}
public T get(){
T t = _stored.poll();
if ( t != null )
return t;
return createNew();
}
public void done( T t ){
if ( ! ok( t ) )
return;
if ( _stored.size() > _max )
return;
_stored.add( t );
}
final int _max;
private Queue<T> _stored = new ConcurrentLinkedQueue<T>();
}

View File

@ -1,130 +0,0 @@
/**
* Copyright (C) 2010 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.bson.util;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
public class StringRangeSet implements Set<String> {
private final int size;
private final static int NUMSTR_LEN = 100;
private final static String[] NUMSTRS = new String[100];
static {
for (int i = 0; i < NUMSTR_LEN; ++i)
NUMSTRS[i] = String.valueOf(i);
}
public StringRangeSet(int size) {
this.size = size;
}
public int size() {
return size;
}
public Iterator<String> iterator() {
return new Iterator<String>() {
int index = 0;
public boolean hasNext() {
return index < size;
}
public String next() {
if (index < NUMSTR_LEN)
return NUMSTRS[index++];
return String.valueOf(index++);
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public boolean add(String e) {
throw new UnsupportedOperationException();
}
@Override
public boolean addAll(Collection<? extends String> c) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
@Override
public boolean contains(Object o) {
int t = Integer.parseInt(String.valueOf(o));
return t >= 0 && t < size;
}
@Override
public boolean containsAll(Collection<?> c) {
for (Object o : c) {
if (!contains(o)) {
return false;
}
}
return true;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public Object[] toArray() {
String[] array = new String[size()];
for (int i = 0; i < size; ++i) {
if (i < NUMSTR_LEN) {
array[i] = NUMSTRS[i];
} else {
array[i] = String.valueOf(i);
}
}
return array;
}
@Override
public <T> T[] toArray(T[] a) {
throw new UnsupportedOperationException();
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 2005 Brian Goetz and Tim Peierls
* Released under the Creative Commons Attribution License
* (http://creativecommons.org/licenses/by/2.5)
* Official home: http://www.jcip.net
*
* Any republication or derived work distributed in source code form
* must include this copyright and license notice.
*/
package com.massivecraft.massivecore.xlib.bson.util.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* The field or method to which this annotation is applied can only be accessed
* when holding a particular lock, which may be a built-in (synchronization) lock,
* or may be an explicit java.util.concurrent.Lock.
*
* The argument determines which lock guards the annotated field or method:
* <ul>
* <li>
* <code>this</code> : The intrinsic lock of the object in whose class the field is defined.
* </li>
* <li>
* <code>class-name.this</code> : For inner classes, it may be necessary to disambiguate 'this';
* the <em>class-name.this</em> designation allows you to specify which 'this' reference is intended
* </li>
* <li>
* <code>itself</code> : For reference fields only; the object to which the field refers.
* </li>
* <li>
* <code>field-name</code> : The lock object is referenced by the (instance or static) field
* specified by <em>field-name</em>.
* </li>
* <li>
* <code>class-name.field-name</code> : The lock object is reference by the static field specified
* by <em>class-name.field-name</em>.
* </li>
* <li>
* <code>method-name()</code> : The lock object is returned by calling the named nil-ary method.
* </li>
* <li>
* <code>class-name.class</code> : The Class object for the specified class should be used as the lock object.
* </li>
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface GuardedBy {
String value();
}

View File

@ -1,35 +0,0 @@
/*
* Copyright (c) 2005 Brian Goetz and Tim Peierls
* Released under the Creative Commons Attribution License
* (http://creativecommons.org/licenses/by/2.5)
* Official home: http://www.jcip.net
*
* Any republication or derived work distributed in source code form
* must include this copyright and license notice.
*/
package com.massivecraft.massivecore.xlib.bson.util.annotations;
import java.lang.annotation.*;
/**
* The class to which this annotation is applied is immutable. This means that
* its state cannot be seen to change by callers, which implies that
* <ul>
* <li> all public fields are final, </li>
* <li> all public final reference fields refer to other immutable objects, and </li>
* <li> constructors and methods do not publish references to any internal state
* which is potentially mutable by the implementation. </li>
* </ul>
* Immutable objects may still have internal mutable state for purposes of performance
* optimization; some state variables may be lazily computed, so long as they are computed
* from immutable state and that callers cannot tell the difference.
* <p>
* Immutable objects are inherently thread-safe; they may be passed between threads or
* published without synchronization.
*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Immutable {
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2005 Brian Goetz and Tim Peierls
* Released under the Creative Commons Attribution License
* (http://creativecommons.org/licenses/by/2.5)
* Official home: http://www.jcip.net
*
* Any republication or derived work distributed in source code form
* must include this copyright and license notice.
*/
package com.massivecraft.massivecore.xlib.bson.util.annotations;
import java.lang.annotation.*;
/**
* The class to which this annotation is applied is not thread-safe.
* This annotation primarily exists for clarifying the non-thread-safety of a class
* that might otherwise be assumed to be thread-safe, despite the fact that it is a bad
* idea to assume a class is thread-safe without good reason.
* @see ThreadSafe
*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface NotThreadSafe {
}

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2005 Brian Goetz and Tim Peierls
* Released under the Creative Commons Attribution License
* (http://creativecommons.org/licenses/by/2.5)
* Official home: http://www.jcip.net
*
* Any republication or derived work distributed in source code form
* must include this copyright and license notice.
*/
package com.massivecraft.massivecore.xlib.bson.util.annotations;
import java.lang.annotation.*;
/**
* The class to which this annotation is applied is thread-safe. This means that
* no sequences of accesses (reads and writes to public fields, calls to public methods)
* may put the object into an invalid state, regardless of the interleaving of those actions
* by the runtime, and without requiring any additional synchronization or coordination on the
* part of the caller.
*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ThreadSafe {
}

View File

@ -1,3 +0,0 @@
<body>
<p>Misc utils used by BSON.</p>
</body>

View File

@ -1,58 +0,0 @@
package com.massivecraft.massivecore.xlib.mongodb;
public class AggregationOutput {
/**
* returns an iterator to the results of the aggregation
* @return
*/
public Iterable<DBObject> results() {
return _resultSet;
}
/**
* returns the command result of the aggregation
* @return
*/
public CommandResult getCommandResult(){
return _commandResult;
}
/**
* returns the original aggregation command
* @return
*/
public DBObject getCommand() {
return _cmd;
}
/**
* returns the address of the server used to execute the aggregation
* @return
*/
public ServerAddress getServerUsed() {
return _commandResult.getServerUsed();
}
/**
* string representation of the aggregation command
*/
public String toString(){
return _commandResult.toString();
}
@SuppressWarnings("unchecked")
public AggregationOutput(DBObject cmd, CommandResult raw) {
_commandResult = raw;
_cmd = cmd;
if(raw.containsField("result"))
_resultSet = (Iterable<DBObject>) raw.get( "result" );
else
throw new IllegalArgumentException("result undefined");
}
protected final CommandResult _commandResult;
protected final DBObject _cmd;
protected final Iterable<DBObject> _resultSet;
}

View File

@ -1,67 +0,0 @@
// BasicDBList.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
import com.massivecraft.massivecore.xlib.bson.types.BasicBSONList;
import com.massivecraft.massivecore.xlib.mongodb.util.JSON;
/**
* a basic implementation of bson list that is mongo specific
* @author antoine
*/
public class BasicDBList extends BasicBSONList implements DBObject {
private static final long serialVersionUID = -4415279469780082174L;
/**
* Returns a JSON serialization of this object
* @return JSON serialization
*/
@Override
public String toString(){
return JSON.serialize( this );
}
public boolean isPartialObject(){
return _isPartialObject;
}
public void markAsPartialObject(){
_isPartialObject = true;
}
public Object copy() {
// copy field values into new object
BasicDBList newobj = new BasicDBList();
// need to clone the sub obj
for (int i = 0; i < size(); ++i) {
Object val = get(i);
if (val instanceof BasicDBObject) {
val = ((BasicDBObject)val).copy();
} else if (val instanceof BasicDBList) {
val = ((BasicDBList)val).copy();
}
newobj.add(val);
}
return newobj;
}
private boolean _isPartialObject;
}

View File

@ -1,109 +0,0 @@
// BasicDBObject.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
import com.massivecraft.massivecore.xlib.bson.BasicBSONObject;
import com.massivecraft.massivecore.xlib.mongodb.util.JSON;
import java.util.Map;
/**
* a basic implementation of bson object that is mongo specific.
* A <code>DBObject</code> can be created as follows, using this class:
* <blockquote><pre>
* DBObject obj = new BasicDBObject();
* obj.put( "foo", "bar" );
* </pre></blockquote>
*/
@SuppressWarnings({"rawtypes"})
public class BasicDBObject extends BasicBSONObject implements DBObject {
private static final long serialVersionUID = -4415279469780082174L;
/**
* Creates an empty object.
*/
public BasicDBObject(){
}
/**
* creates an empty object
* @param size an estimate of number of fields that will be inserted
*/
public BasicDBObject(int size){
super(size);
}
/**
* creates an object with the given key/value
* @param key key under which to store
* @param value value to stor
*/
public BasicDBObject(String key, Object value){
super(key, value);
}
/**
* Creates an object from a map.
* @param m map to convert
*/
public BasicDBObject(Map m) {
super(m);
}
public boolean isPartialObject(){
return _isPartialObject;
}
public void markAsPartialObject(){
_isPartialObject = true;
}
/**
* Returns a JSON serialization of this object
* @return JSON serialization
*/
@Override
public String toString(){
return JSON.serialize( this );
}
@Override
public BasicDBObject append( String key , Object val ){
put( key , val );
return this;
}
public Object copy() {
// copy field values into new object
BasicDBObject newobj = new BasicDBObject(this.toMap());
// need to clone the sub obj
for (String field : keySet()) {
Object val = get(field);
if (val instanceof BasicDBObject) {
newobj.put(field, ((BasicDBObject)val).copy());
} else if (val instanceof BasicDBList) {
newobj.put(field, ((BasicDBList)val).copy());
}
}
return newobj;
}
private boolean _isPartialObject;
}

View File

@ -1,142 +0,0 @@
// BasicDBObjectBuilder.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
/**
* utility for building complex objects
* example:
* BasicDBObjectBuilder.start().add( "name" , "eliot" ).add( "number" , 17 ).get()
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class BasicDBObjectBuilder {
/**
* creates an empty object
*/
public BasicDBObjectBuilder(){
_stack = new LinkedList<DBObject>();
_stack.add( new BasicDBObject() );
}
/**
* Creates an empty object
* @return The new empty builder
*/
public static BasicDBObjectBuilder start(){
return new BasicDBObjectBuilder();
}
/**
* creates an object with the given key/value
* @param k The field name
* @param val The value
*/
public static BasicDBObjectBuilder start( String k , Object val ){
return (new BasicDBObjectBuilder()).add( k , val );
}
/**
* Creates an object builder from an existing map.
* @param m map to use
* @return the new builder
*/
public static BasicDBObjectBuilder start(Map m){
BasicDBObjectBuilder b = new BasicDBObjectBuilder();
Iterator<Map.Entry> i = m.entrySet().iterator();
while (i.hasNext()) {
Map.Entry entry = i.next();
b.add(entry.getKey().toString(), entry.getValue());
}
return b;
}
/**
* appends the key/value to the active object
* @param key
* @param val
* @return returns itself so you can chain
*/
public BasicDBObjectBuilder append( String key , Object val ){
_cur().put( key , val );
return this;
}
/**
* same as appends
* @see #append(String, Object)
* @param key
* @param val
* @return returns itself so you can chain
*/
public BasicDBObjectBuilder add( String key , Object val ){
return append( key, val );
}
/**
* creates an new empty object and inserts it into the current object with the given key.
* The new child object becomes the active one.
* @param key
* @return returns itself so you can chain
*/
public BasicDBObjectBuilder push( String key ){
BasicDBObject o = new BasicDBObject();
_cur().put( key , o );
_stack.addLast( o );
return this;
}
/**
* pops the active object, which means that the parent object becomes active
* @return returns itself so you can chain
*/
public BasicDBObjectBuilder pop(){
if ( _stack.size() <= 1 )
throw new IllegalArgumentException( "can't pop last element" );
_stack.removeLast();
return this;
}
/**
* gets the base object
* @return The base object
*/
public DBObject get(){
return _stack.getFirst();
}
/**
* returns true if no key/value was inserted into base object
* @return True if empty
*/
public boolean isEmpty(){
return ((BasicDBObject) _stack.getFirst()).size() == 0;
}
private DBObject _cur(){
return _stack.getLast();
}
private final LinkedList<DBObject> _stack;
}

View File

@ -1,227 +0,0 @@
// Bytes.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
import java.nio.ByteOrder;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.massivecraft.massivecore.xlib.bson.BSON;
import com.massivecraft.massivecore.xlib.bson.types.BSONTimestamp;
import com.massivecraft.massivecore.xlib.bson.types.Code;
import com.massivecraft.massivecore.xlib.bson.types.CodeWScope;
import com.massivecraft.massivecore.xlib.bson.types.ObjectId;
/**
* Class that hold definitions of the wire protocol
* @author antoine
*/
public class Bytes extends BSON {
static final Logger LOGGER = Logger.getLogger( "com.mongodb" );
static final boolean D = Boolean.getBoolean( "DEBUG.MONGO" );
static {
if ( LOGGER.getLevel() == null ){
if ( D )
LOGGER.setLevel( Level.ALL );
else
LOGGER.setLevel( Level.WARNING );
}
}
/** Little-endian */
public static final ByteOrder ORDER = ByteOrder.LITTLE_ENDIAN;
/** this size is set low to 4MB, but just serves as safe default */
static final int MAX_OBJECT_SIZE = 1024 * 1024 * 4;
/** default target size of an insert batch */
static final int BATCH_INSERT_SIZE = 1024 * 1024 * 8;
static final int CONNECTIONS_PER_HOST = Integer.parseInt( System.getProperty( "MONGO.POOLSIZE" , "10" ) );
// --- network protocol options
/**
* Tailable means cursor is not closed when the last data is retrieved.
* Rather, the cursor marks the final object's position.
* You can resume using the cursor later, from where it was located, if more data were received.
* Like any "latent cursor", the cursor may become invalid at some point (CursorNotFound) for example if the final object it references were deleted.
*/
public static final int QUERYOPTION_TAILABLE = 1 << 1;
/**
* When turned on, read queries will be directed to slave servers instead of the primary server.
*/
public static final int QUERYOPTION_SLAVEOK = 1 << 2;
/**
* Internal replication use only - driver should not set
*/
public static final int QUERYOPTION_OPLOGREPLAY = 1 << 3;
/**
* The server normally times out idle cursors after an inactivity period (10 minutes) to prevent excess memory use.
* Set this option to prevent that.
*/
public static final int QUERYOPTION_NOTIMEOUT = 1 << 4;
/**
* Use with TailableCursor.
* If we are at the end of the data, block for a while rather than returning no data.
* After a timeout period, we do return as normal.
*/
public static final int QUERYOPTION_AWAITDATA = 1 << 5;
/**
* Stream the data down full blast in multiple "more" packages, on the assumption that the client will fully read all data queried.
* Faster when you are pulling a lot of data and know you want to pull it all down.
* Note: the client is not allowed to not read all the data unless it closes the connection.
*/
public static final int QUERYOPTION_EXHAUST = 1 << 6;
/**
* Use with sharding (mongos).
* Allows partial results from a sharded system if any shards are down/missing from the cluster. If not used an error will be returned
* from the mongos server.
*/
public static final int QUERYOPTION_PARTIAL = 1 << 7;
/**
* Set when getMore is called but the cursor id is not valid at the server.
* Returned with zero results.
*/
public static final int RESULTFLAG_CURSORNOTFOUND = 1;
/**
* Set when query failed.
* Results consist of one document containing an "$err" field describing the failure.
*/
public static final int RESULTFLAG_ERRSET = 2;
/**
* Drivers should ignore this.
* Only mongos will ever see this set, in which case, it needs to update config from the server.
*/
public static final int RESULTFLAG_SHARDCONFIGSTALE = 4;
/**
* Set when the server supports the AwaitData Query option.
* If it doesn't, a client should sleep a little between getMore's of a Tailable cursor.
* Mongod version 1.6 supports AwaitData and thus always sets AwaitCapable.
*/
public static final int RESULTFLAG_AWAITCAPABLE = 8;
static class OptionHolder {
OptionHolder( OptionHolder parent ){
_parent = parent;
}
void set( int options ){
_options = options;
_hasOptions = true;
}
int get(){
if ( _hasOptions )
return _options;
if ( _parent == null )
return 0;
return _parent.get();
}
void add( int option ){
set( get() | option );
}
void reset(){
_hasOptions = false;
}
final OptionHolder _parent;
int _options = 0;
boolean _hasOptions = false;
}
/**
* Gets the type byte for a given object.
* @param o the object
* @return the byte value associated with the type, or -1 if no type is matched
*/
@SuppressWarnings("deprecation")
public static byte getType( Object o ){
if ( o == null )
return NULL;
if ( o instanceof DBPointer )
return REF;
if (o instanceof Integer
|| o instanceof Short
|| o instanceof Byte
|| o instanceof AtomicInteger) {
return NUMBER_INT;
}
if (o instanceof Long || o instanceof AtomicLong) {
return NUMBER_LONG;
}
if ( o instanceof Number )
return NUMBER;
if ( o instanceof String )
return STRING;
if ( o instanceof java.util.List )
return ARRAY;
if ( o instanceof byte[] )
return BINARY;
if ( o instanceof ObjectId )
return OID;
if ( o instanceof Boolean )
return BOOLEAN;
if ( o instanceof java.util.Date )
return DATE;
if ( o instanceof BSONTimestamp )
return TIMESTAMP;
if ( o instanceof java.util.regex.Pattern )
return REGEX;
if ( o instanceof DBObject || o instanceof DBRefBase )
return OBJECT;
if ( o instanceof Code )
return CODE;
if ( o instanceof CodeWScope )
return CODE_W_SCOPE;
return -1;
}
static final ObjectId COLLECTION_REF_ID = new ObjectId( -1 , -1 , -1 );
}

View File

@ -1,45 +0,0 @@
/*
* Copyright (c) 2008 - 2013 10gen, Inc. <http://10gen.com>
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
/**
* An exception indicating a failed command.
*/
public class CommandFailureException extends MongoException {
private static final long serialVersionUID = -1180715413196161037L;
private final CommandResult commandResult;
/**
* Construct a new instance with the CommandResult from a failed command
*
* @param commandResult the result
*/
public CommandFailureException(CommandResult commandResult){
super(ServerError.getCode(commandResult), commandResult.toString());
this.commandResult = commandResult;
}
/**
* Gets the getlasterror command result document.
*
* @return the command result
*/
public CommandResult getCommandResult() {
return commandResult;
}
}

View File

@ -1,121 +0,0 @@
// CommandResult.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
/**
* A simple wrapper for the result of getLastError() calls and other commands
*/
public class CommandResult extends BasicDBObject {
CommandResult(ServerAddress srv) {
if (srv == null) {
throw new IllegalArgumentException("server address is null");
}
_host = srv;
//so it is shown in toString/debug
put("serverUsed", srv.toString());
}
/**
* gets the "ok" field which is the result of the command
* @return True if ok
*/
public boolean ok(){
Object o = get( "ok" );
if ( o == null )
throw new IllegalArgumentException( "'ok' should never be null..." );
if ( o instanceof Boolean )
return (Boolean) o;
if ( o instanceof Number )
return ((Number)o).intValue() == 1;
throw new IllegalArgumentException( "can't figure out what to do with: " + o.getClass().getName() );
}
/**
* gets the "errmsg" field which holds the error message
* @return The error message or null
*/
public String getErrorMessage(){
Object errorMessage = get( "errmsg" );
if ( errorMessage == null )
return null;
return errorMessage.toString();
}
/**
* utility method to create an exception with the command name
* @return The mongo exception or null
*/
public MongoException getException() {
if ( !ok() ) { // check for command failure
return new CommandFailureException( this );
} else if ( hasErr() ) { // check for errors reported by getlasterror command
if (getCode() == 11000 || getCode() == 11001 || getCode() == 12582) {
return new MongoException.DuplicateKey(this);
}
else {
return new WriteConcernException(this);
}
}
return null;
}
/**
* returns the "code" field, as an int
* @return -1 if there is no code
*/
int getCode() {
int code = -1;
if ( get( "code" ) instanceof Number )
code = ((Number)get("code")).intValue();
return code;
}
/**
* check the "err" field
* @return if it has it, and isn't null
*/
boolean hasErr(){
Object o = get( "err" );
return (o != null && ( (String) o ).length() > 0 );
}
/**
* throws an exception containing the cmd name, in case the command failed, or the "err/code" information
* @throws MongoException
*/
public void throwOnError() {
if ( !ok() || hasErr() ){
throw getException();
}
}
public ServerAddress getServerUsed() {
return _host;
}
private final ServerAddress _host;
private static final long serialVersionUID = 1L;
}

View File

@ -1,252 +0,0 @@
/**
* Copyright (c) 2008 - 2012 10gen, Inc. <http://10gen.com>
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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 com.massivecraft.massivecore.xlib.mongodb;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Base class for classes that manage connections to mongo instances as background tasks.
*/
abstract class ConnectionStatus {
ConnectionStatus(List<ServerAddress> mongosAddresses, Mongo mongo) {
_mongoOptions = mongoOptionsDefaults.copy();
_mongoOptions.socketFactory = mongo._options.socketFactory;
this._mongosAddresses = new ArrayList<ServerAddress>(mongosAddresses);
this._mongo = mongo;
}
protected BackgroundUpdater _updater;
protected final Mongo _mongo;
protected final List<ServerAddress> _mongosAddresses;
protected volatile boolean _closed;
protected final MongoOptions _mongoOptions;
protected static int updaterIntervalMS;
protected static int updaterIntervalNoMasterMS;
@SuppressWarnings("deprecation")
protected static final MongoOptions mongoOptionsDefaults = new MongoOptions();
protected static final float latencySmoothFactor;
protected static final DBObject isMasterCmd = new BasicDBObject("ismaster", 1);
/**
* Start the updater if there is one
*/
void start() {
if (_updater != null) {
_updater.start();
}
}
/**
* Stop the updater if there is one
*/
void close() {
_closed = true;
if (_updater != null) {
_updater.interrupt();
}
}
/**
* Gets the list of addresses for this connection.
*/
abstract List<ServerAddress> getServerAddressList();
/**
* Whether there is least one server up.
*/
abstract boolean hasServerUp();
/**
* Ensures that we have the current master, if there is one. If the current snapshot of the replica set
* has no master, this method waits one cycle to find a new master, and returns it if found, or null if not.
*
* @return address of the current master, or null if there is none
*/
abstract Node ensureMaster();
/**
* Whether this connection has been closed.
*/
void checkClosed() {
if (_closed)
throw new IllegalStateException("ReplicaSetStatus closed");
}
static {
updaterIntervalMS = Integer.parseInt(System.getProperty("com.mongodb.updaterIntervalMS", "5000"));
updaterIntervalNoMasterMS = Integer.parseInt(System.getProperty("com.mongodb.updaterIntervalNoMasterMS", "10"));
mongoOptionsDefaults.connectTimeout = Integer.parseInt(System.getProperty("com.mongodb.updaterConnectTimeoutMS", "20000"));
mongoOptionsDefaults.socketTimeout = Integer.parseInt(System.getProperty("com.mongodb.updaterSocketTimeoutMS", "20000"));
latencySmoothFactor = Float.parseFloat(System.getProperty("com.mongodb.latencySmoothFactor", "4"));
}
static class Node {
Node(float pingTime, ServerAddress addr, int maxBsonObjectSize, boolean ok) {
this._pingTime = pingTime;
this._addr = addr;
this._maxBsonObjectSize = maxBsonObjectSize;
this._ok = ok;
}
public boolean isOk() {
return _ok;
}
public int getMaxBsonObjectSize() {
return _maxBsonObjectSize;
}
public ServerAddress getServerAddress() {
return _addr;
}
protected final ServerAddress _addr;
protected final float _pingTime;
protected final boolean _ok;
protected final int _maxBsonObjectSize;
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final Node node = (Node) o;
if (_maxBsonObjectSize != node._maxBsonObjectSize) return false;
if (_ok != node._ok) return false;
if (Float.compare(node._pingTime, _pingTime) != 0) return false;
if (!_addr.equals(node._addr)) return false;
return true;
}
@Override
public int hashCode() {
int result = _addr.hashCode();
result = 31 * result + (_pingTime != +0.0f ? Float.floatToIntBits(_pingTime) : 0);
result = 31 * result + (_ok ? 1 : 0);
result = 31 * result + _maxBsonObjectSize;
return result;
}
public String toJSON() {
StringBuilder buf = new StringBuilder();
buf.append("{");
buf.append("address:'").append(_addr).append("', ");
buf.append("ok:").append(_ok).append(", ");
buf.append("ping:").append(_pingTime).append(", ");
buf.append("maxBsonObjectSize:").append(_maxBsonObjectSize).append(", ");
buf.append("}");
return buf.toString();
}
}
static class BackgroundUpdater extends Thread {
public BackgroundUpdater(final String name) {
super(name);
setDaemon(true);
}
}
static abstract class UpdatableNode {
UpdatableNode(final ServerAddress addr, Mongo mongo, MongoOptions mongoOptions) {
this._addr = addr;
this._mongo = mongo;
this._mongoOptions = mongoOptions;
this._port = new DBPort(addr, null, mongoOptions);
}
public CommandResult update() {
CommandResult res = null;
try {
long start = System.nanoTime();
res = _port.runCommand(_mongo.getDB("admin"), isMasterCmd);
long end = System.nanoTime();
float newPingMS = (end - start) / 1000000F;
if (!successfullyContacted)
_pingTimeMS = newPingMS;
else
_pingTimeMS = _pingTimeMS + ((newPingMS - _pingTimeMS) / latencySmoothFactor);
getLogger().log(Level.FINE, "Latency to " + _addr + " actual=" + newPingMS + " smoothed=" + _pingTimeMS);
successfullyContacted = true;
if (res == null) {
throw new MongoInternalException("Invalid null value returned from isMaster");
}
if (!_ok) {
getLogger().log(Level.INFO, "Server seen up: " + _addr);
}
_ok = true;
// max size was added in 1.8
if (res.containsField("maxBsonObjectSize")) {
_maxBsonObjectSize = (Integer) res.get("maxBsonObjectSize");
} else {
_maxBsonObjectSize = Bytes.MAX_OBJECT_SIZE;
}
} catch (Exception e) {
if (!((_ok) ? true : (Math.random() > 0.1))) {
return res;
}
final StringBuilder logError = (new StringBuilder("Server seen down: ")).append(_addr);
if (e instanceof IOException) {
logError.append(" - ").append(IOException.class.getName());
if (e.getMessage() != null) {
logError.append(" - message: ").append(e.getMessage());
}
getLogger().log(Level.WARNING, logError.toString());
} else {
getLogger().log(Level.WARNING, logError.toString(), e);
}
_ok = false;
}
return res;
}
protected abstract Logger getLogger();
final ServerAddress _addr;
final MongoOptions _mongoOptions;
final Mongo _mongo;
DBPort _port; // we have our own port so we can set different socket options and don't have to worry about the pool
boolean successfullyContacted = false;
boolean _ok = false;
float _pingTimeMS = 0;
int _maxBsonObjectSize;
}
}

View File

@ -1,822 +0,0 @@
// DB.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
import com.massivecraft.massivecore.xlib.bson.BSONObject;
import com.massivecraft.massivecore.xlib.mongodb.DBApiLayer.Result;
import com.massivecraft.massivecore.xlib.mongodb.util.Util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* an abstract class that represents a logical database on a server
* @dochub databases
*/
public abstract class DB {
private static final Set<String> _obedientCommands = new HashSet<String>();
static {
_obedientCommands.add("group");
_obedientCommands.add("aggregate");
_obedientCommands.add("collstats");
_obedientCommands.add("dbstats");
_obedientCommands.add("count");
_obedientCommands.add("distinct");
_obedientCommands.add("geonear");
_obedientCommands.add("geosearch");
_obedientCommands.add("geowalk");
}
/**
* @param mongo the mongo instance
* @param name the database name
*/
public DB( Mongo mongo , String name ){
_mongo = mongo;
_name = name;
_options = new Bytes.OptionHolder( _mongo._netOptions );
}
/**
* Determines the read preference that should be used for the given command.
* @param command the <code>DBObject</code> representing the command
* @param requestedPreference the preference requested by the client.
* @return the read preference to use for the given command. It will never return null.
* @see com.massivecraft.massivecore.xlib.mongodb.ReadPreference
*/
ReadPreference getCommandReadPreference(DBObject command, ReadPreference requestedPreference){
String comString = command.keySet().iterator().next();
if (comString.equals("getnonce") || comString.equals("authenticate")) {
return ReadPreference.primaryPreferred();
}
boolean primaryRequired;
// explicitly check mapreduce commands are inline
if(comString.equals("mapreduce")) {
Object out = command.get("out");
if (out instanceof BSONObject ){
BSONObject outMap = (BSONObject) out;
primaryRequired = outMap.get("inline") == null;
}
else
primaryRequired = true;
} else {
primaryRequired = !_obedientCommands.contains(comString.toLowerCase());
}
if (primaryRequired) {
return ReadPreference.primary();
} else if (requestedPreference == null) {
return ReadPreference.primary();
} else {
return requestedPreference;
}
}
/**
* starts a new "consistent request".
* Following this call and until requestDone() is called, all db operations should use the same underlying connection.
* This is useful to ensure that operations happen in a certain order with predictable results.
*/
public abstract void requestStart();
/**
* ends the current "consistent request"
*/
public abstract void requestDone();
/**
* ensure that a connection is assigned to the current "consistent request" (from primary pool, if connected to a replica set)
*/
public abstract void requestEnsureConnection();
/**
* Returns the collection represented by the string &lt;dbName&gt;.&lt;collectionName&gt;.
* @param name the name of the collection
* @return the collection
*/
protected abstract DBCollection doGetCollection( String name );
/**
* Gets a collection with a given name.
* If the collection does not exist, a new collection is created.
* @param name the name of the collection to return
* @return the collection
*/
public DBCollection getCollection( String name ){
DBCollection c = doGetCollection( name );
return c;
}
/**
* Creates a collection with a given name and options.
* If the collection does not exist, a new collection is created.
* Note that if the options parameter is null, the creation will be deferred to when the collection is written to.
* Possible options:
* <dl>
* <dt>capped</dt><dd><i>boolean</i>: if the collection is capped</dd>
* <dt>size</dt><dd><i>int</i>: collection size (in bytes)</dd>
* <dt>max</dt><dd><i>int</i>: max number of documents</dd>
* </dl>
* @param name the name of the collection to return
* @param options options
* @return the collection
* @throws MongoException
*/
public DBCollection createCollection( String name, DBObject options ){
if ( options != null ){
DBObject createCmd = new BasicDBObject("create", name);
createCmd.putAll(options);
CommandResult result = command(createCmd);
result.throwOnError();
}
return getCollection(name);
}
/**
* Returns a collection matching a given string.
* @param s the name of the collection
* @return the collection
*/
public DBCollection getCollectionFromString( String s ){
DBCollection foo = null;
int idx = s.indexOf( "." );
while ( idx >= 0 ){
String b = s.substring( 0 , idx );
s = s.substring( idx + 1 );
if ( foo == null )
foo = getCollection( b );
else
foo = foo.getCollection( b );
idx = s.indexOf( "." );
}
if ( foo != null )
return foo.getCollection( s );
return getCollection( s );
}
/**
* Executes a database command.
* This method calls {@link DB#command(com.massivecraft.massivecore.xlib.mongodb.DBObject, int) } with 0 as query option.
* @see <a href="http://mongodb.onconfluence.com/display/DOCS/List+of+Database+Commands">List of Commands</a>
* @param cmd dbobject representing the command to execute
* @return result of command from the database
* @throws MongoException
* @dochub commands
*/
public CommandResult command( DBObject cmd ){
return command( cmd, 0 );
}
/**
* Executes a database command.
* This method calls {@link DB#command(com.massivecraft.massivecore.xlib.mongodb.DBObject, int, com.massivecraft.massivecore.xlib.mongodb.DBEncoder) } with 0 as query option.
* @see <a href="http://mongodb.onconfluence.com/display/DOCS/List+of+Database+Commands">List of Commands</a>
* @param cmd dbobject representing the command to execute
* @param encoder
* @return result of command from the database
* @throws MongoException
* @dochub commands
*/
public CommandResult command( DBObject cmd, DBEncoder encoder ){
return command( cmd, 0, encoder );
}
/**
* Executes a database command.
* This method calls {@link DB#command(com.massivecraft.massivecore.xlib.mongodb.DBObject, int, com.massivecraft.massivecore.xlib.mongodb.ReadPreference, com.massivecraft.massivecore.xlib.mongodb.DBEncoder) } with a null readPrefs.
* @see <a href="http://mongodb.onconfluence.com/display/DOCS/List+of+Database+Commands">List of Commands</a>
* @param cmd dbobject representing the command to execute
* @param options query options to use
* @param encoder
* @return result of command from the database
* @throws MongoException
* @dochub commands
*/
public CommandResult command( DBObject cmd , int options, DBEncoder encoder ){
return command(cmd, options, getReadPreference(), encoder);
}
/**
* Executes a database command.
* This method calls {@link DB#command(com.massivecraft.massivecore.xlib.mongodb.DBObject, int, com.massivecraft.massivecore.xlib.mongodb.ReadPreference, com.massivecraft.massivecore.xlib.mongodb.DBEncoder) } with a default encoder.
* @see <a href="http://mongodb.onconfluence.com/display/DOCS/List+of+Database+Commands">List of Commands</a>
* @param cmd dbobject representing the command to execute
* @param options query options to use
* @param readPrefs ReadPreferences for this command (nodes selection is the biggest part of this)
* @return result of command from the database
* @throws MongoException
* @dochub commands
*/
public CommandResult command( DBObject cmd , int options, ReadPreference readPrefs ){
return command(cmd, options, readPrefs, DefaultDBEncoder.FACTORY.create());
}
/**
* Executes a database command.
* @see <a href="http://mongodb.onconfluence.com/display/DOCS/List+of+Database+Commands">List of Commands</a>
* @param cmd dbobject representing the command to execute
* @param options query options to use
* @param readPrefs ReadPreferences for this command (nodes selection is the biggest part of this)
* @param encoder
* @return result of command from the database
* @throws MongoException
* @dochub commands
*/
public CommandResult command( DBObject cmd , int options, ReadPreference readPrefs, DBEncoder encoder ){
readPrefs = getCommandReadPreference(cmd, readPrefs);
cmd = wrapCommand(cmd, readPrefs);
Iterator<DBObject> i =
getCollection("$cmd").__find(cmd, new BasicDBObject(), 0, -1, 0, options, readPrefs ,
DefaultDBDecoder.FACTORY.create(), encoder);
if ( i == null || ! i.hasNext() )
return null;
DBObject res = i.next();
ServerAddress sa = (i instanceof Result) ? ((Result) i).getServerAddress() : null;
CommandResult cr = new CommandResult(sa);
cr.putAll( res );
return cr;
}
// Only append $readPreference meta-operator if connected to a mongos, read preference is not primary
// or secondary preferred,
// and command is an instance of BasicDBObject. The last condition is unfortunate, but necessary in case
// the encoder is not capable of encoding a BasicDBObject
// Due to issues with compatibility between different versions of mongos, also wrap the command in a
// $query field, so that the $readPreference is not rejected
private DBObject wrapCommand(DBObject cmd, final ReadPreference readPrefs) {
if (getMongo().isMongosConnection() &&
!(ReadPreference.primary().equals(readPrefs) || ReadPreference.secondaryPreferred().equals(readPrefs)) &&
cmd instanceof BasicDBObject) {
cmd = new BasicDBObject("$query", cmd)
.append(QueryOpBuilder.READ_PREFERENCE_META_OPERATOR, readPrefs.toDBObject());
}
return cmd;
}
/**
* Executes a database command.
* @see <a href="http://mongodb.onconfluence.com/display/DOCS/List+of+Database+Commands">List of Commands</a>
* @param cmd dbobject representing the command to execute
* @param options query options to use
* @return result of command from the database
* @throws MongoException
* @dochub commands
*/
public CommandResult command( DBObject cmd , int options ){
return command(cmd, options, getReadPreference());
}
/**
* Executes a database command.
* This method constructs a simple dbobject and calls {@link DB#command(com.massivecraft.massivecore.xlib.mongodb.DBObject) }
* @see <a href="http://mongodb.onconfluence.com/display/DOCS/List+of+Database+Commands">List of Commands</a>
* @param cmd command to execute
* @return result of command from the database
* @throws MongoException
* @dochub commands
*/
public CommandResult command( String cmd ){
return command( new BasicDBObject( cmd , Boolean.TRUE ) );
}
/**
* Executes a database command.
* This method constructs a simple dbobject and calls {@link DB#command(com.massivecraft.massivecore.xlib.mongodb.DBObject, int) }
* @see <a href="http://mongodb.onconfluence.com/display/DOCS/List+of+Database+Commands">List of Commands</a>
* @param cmd command to execute
* @param options query options to use
* @return result of command from the database
* @throws MongoException
* @dochub commands
*/
public CommandResult command( String cmd, int options ){
return command( new BasicDBObject( cmd , Boolean.TRUE ), options );
}
/**
* evaluates a function on the database.
* This is useful if you need to touch a lot of data lightly, in which case network transfer could be a bottleneck.
* @param code the function in javascript code
* @param args arguments to be passed to the function
* @return The command result
* @throws MongoException
*/
public CommandResult doEval( String code , Object ... args ){
return command( BasicDBObjectBuilder.start()
.add( "$eval" , code )
.add( "args" , args )
.get() );
}
/**
* calls {@link DB#doEval(java.lang.String, java.lang.Object[]) }.
* If the command is successful, the "retval" field is extracted and returned.
* Otherwise an exception is thrown.
* @param code the function in javascript code
* @param args arguments to be passed to the function
* @return The object
* @throws MongoException
*/
public Object eval( String code , Object ... args ){
CommandResult res = doEval( code , args );
res.throwOnError();
return res.get( "retval" );
}
/**
* Returns the result of "dbstats" command
* @return
* @throws MongoException
*/
public CommandResult getStats() {
return command("dbstats");
}
/**
* Returns the name of this database.
* @return the name
*/
public String getName(){
return _name;
}
/**
* Makes this database read-only.
* Important note: this is a convenience setting that is only known on the client side and not persisted.
* @param b if the database should be read-only
*/
public void setReadOnly( Boolean b ){
_readOnly = b;
}
/**
* Returns a set containing the names of all collections in this database.
* @return the names of collections in this database
* @throws MongoException
*/
public Set<String> getCollectionNames(){
DBCollection namespaces = getCollection("system.namespaces");
if (namespaces == null)
throw new RuntimeException("this is impossible");
Iterator<DBObject> i = namespaces.__find(new BasicDBObject(), null, 0, 0, 0, getOptions(), getReadPreference(), null);
if (i == null)
return new HashSet<String>();
List<String> tables = new ArrayList<String>();
for (; i.hasNext();) {
DBObject o = i.next();
if ( o.get( "name" ) == null ){
throw new MongoException( "how is name null : " + o );
}
String n = o.get("name").toString();
int idx = n.indexOf(".");
String root = n.substring(0, idx);
if (!root.equals(_name))
continue;
if (n.indexOf("$") >= 0)
continue;
String table = n.substring(idx + 1);
tables.add(table);
}
Collections.sort(tables);
return new LinkedHashSet<String>(tables);
}
/**
* Checks to see if a collection by name %lt;name&gt; exists.
* @param collectionName The collection to test for existence
* @return false if no collection by that name exists, true if a match to an existing collection was found
* @throws MongoException
*/
public boolean collectionExists(String collectionName)
{
if (collectionName == null || "".equals(collectionName))
return false;
Set<String> collections = getCollectionNames();
if (collections.isEmpty())
return false;
for (String collection : collections)
{
if (collectionName.equalsIgnoreCase(collection))
return true;
}
return false;
}
/**
* Returns the name of this database.
* @return the name
*/
@Override
public String toString(){
return _name;
}
/**
* Gets the the error (if there is one) from the previous operation on this connection.
* The result of this command will look like
*
* <pre>
* { "err" : errorMessage , "ok" : 1.0 }
* </pre>
*
* The value for errorMessage will be null if no error occurred, or a description otherwise.
*
* Important note: when calling this method directly, it is undefined which connection "getLastError" is called on.
* You may need to explicitly use a "consistent Request", see {@link DB#requestStart()}
* For most purposes it is better not to call this method directly but instead use {@link WriteConcern}
*
* @return DBObject with error and status information
* @throws MongoException
*/
public CommandResult getLastError(){
return command(new BasicDBObject("getlasterror", 1));
}
/**
* @see {@link DB#getLastError() }
* @param concern the concern associated with "getLastError" call
* @return
* @throws MongoException
*/
public CommandResult getLastError( com.massivecraft.massivecore.xlib.mongodb.WriteConcern concern ){
return command( concern.getCommand() );
}
/**
* @see {@link DB#getLastError(com.massivecraft.massivecore.xlib.mongodb.WriteConcern) }
* @param w
* @param wtimeout
* @param fsync
* @return The command result
* @throws MongoException
*/
public CommandResult getLastError( int w , int wtimeout , boolean fsync ){
return command( (new com.massivecraft.massivecore.xlib.mongodb.WriteConcern( w, wtimeout , fsync )).getCommand() );
}
/**
* Sets the write concern for this database. It Will be used for
* writes to any collection in this database. See the
* documentation for {@link WriteConcern} for more information.
* @param concern write concern to use
*/
public void setWriteConcern( com.massivecraft.massivecore.xlib.mongodb.WriteConcern concern ){
if (concern == null) throw new IllegalArgumentException();
_concern = concern;
}
/**
* Gets the write concern for this database.
* @return
*/
public com.massivecraft.massivecore.xlib.mongodb.WriteConcern getWriteConcern(){
if ( _concern != null )
return _concern;
return _mongo.getWriteConcern();
}
/**
* Sets the read preference for this database. Will be used as default for
* reads from any collection in this database. See the
* documentation for {@link ReadPreference} for more information.
*
* @param preference Read Preference to use
*/
public void setReadPreference( ReadPreference preference ){
_readPref = preference;
}
/**
* Gets the default read preference
* @return
*/
public ReadPreference getReadPreference(){
if ( _readPref != null )
return _readPref;
return _mongo.getReadPreference();
}
/**
* Drops this database. Removes all data on disk. Use with caution.
* @throws MongoException
*/
public void dropDatabase(){
CommandResult res = command(new BasicDBObject("dropDatabase", 1));
res.throwOnError();
_mongo._dbs.remove(this.getName());
}
/**
* Returns true if a user has been authenticated
*
* @return true if authenticated, false otherwise
* @dochub authenticate
*/
public boolean isAuthenticated() {
return getAuthenticationCredentials() != null;
}
/**
* Authenticates to db with the given credentials. If this method (or {@code authenticateCommand} has already been
* called with the same credentials and the authentication test succeeded, this method will return true. If this method
* has already been called with different credentials and the authentication test succeeded,
* this method will throw an {@code IllegalStateException}. If this method has already been called with any credentials
* and the authentication test failed, this method will re-try the authentication test with the
* given credentials.
*
* @param username name of user for this database
* @param password password of user for this database
* @return true if authenticated, false otherwise
* @throws MongoException if authentication failed due to invalid user/pass, or other exceptions like I/O
* @throws IllegalStateException if authentiation test has already succeeded with different credentials
* @see #authenticateCommand(String, char[])
* @dochub authenticate
*/
public boolean authenticate(String username, char[] password ){
return authenticateCommandHelper(username, password).failure == null;
}
/**
* Authenticates to db with the given credentials. If this method (or {@code authenticate} has already been
* called with the same credentials and the authentication test succeeded, this method will return true. If this method
* has already been called with different credentials and the authentication test succeeded,
* this method will throw an {@code IllegalStateException}. If this method has already been called with any credentials
* and the authentication test failed, this method will re-try the authentication test with the
* given credentials.
*
*
* @param username name of user for this database
* @param password password of user for this database
* @return the CommandResult from authenticate command
* @throws MongoException if authentication failed due to invalid user/pass, or other exceptions like I/O
* @throws IllegalStateException if authentiation test has already succeeded with different credentials
* @see #authenticate(String, char[])
* @dochub authenticate
*/
public synchronized CommandResult authenticateCommand(String username, char[] password ){
CommandResultPair commandResultPair = authenticateCommandHelper(username, password);
if (commandResultPair.failure != null) {
throw commandResultPair.failure;
}
return commandResultPair.result;
}
private CommandResultPair authenticateCommandHelper(String username, char[] password) {
MongoCredential credentials =
MongoCredential.createMongoCRCredential(username, getName(), password);
if (getAuthenticationCredentials() != null) {
if (getAuthenticationCredentials().equals(credentials)) {
if (authenticationTestCommandResult != null) {
return new CommandResultPair(authenticationTestCommandResult);
}
} else {
throw new IllegalStateException("can't authenticate twice on the same database");
}
}
try {
authenticationTestCommandResult = doAuthenticate(credentials);
return new CommandResultPair(authenticationTestCommandResult);
} catch (CommandFailureException commandFailureException) {
return new CommandResultPair(commandFailureException);
}
}
class CommandResultPair {
CommandResult result;
CommandFailureException failure;
public CommandResultPair(final CommandResult result) {
this.result = result;
}
public CommandResultPair(final CommandFailureException failure) {
this.failure = failure;
}
}
abstract CommandResult doAuthenticate(MongoCredential credentials);
/**
* Adds a new user for this db
* @param username
* @param passwd
* @throws MongoException
*/
public WriteResult addUser( String username , char[] passwd ){
return addUser(username, passwd, false);
}
/**
* Adds a new user for this db
* @param username
* @param passwd
* @param readOnly if true, user will only be able to read
* @throws MongoException
*/
public WriteResult addUser( String username , char[] passwd, boolean readOnly ){
DBCollection c = getCollection( "system.users" );
DBObject o = c.findOne( new BasicDBObject( "user" , username ) );
if ( o == null )
o = new BasicDBObject( "user" , username );
o.put( "pwd" , _hash( username , passwd ) );
o.put( "readOnly" , readOnly );
return c.save( o );
}
/**
* Removes a user for this db
* @param username
* @throws MongoException
*/
public WriteResult removeUser( String username ){
DBCollection c = getCollection( "system.users" );
return c.remove(new BasicDBObject( "user" , username ));
}
String _hash( String username , char[] passwd ){
ByteArrayOutputStream bout = new ByteArrayOutputStream( username.length() + 20 + passwd.length );
try {
bout.write( username.getBytes() );
bout.write( ":mongo:".getBytes() );
for ( int i=0; i<passwd.length; i++ ){
if ( passwd[i] >= 128 )
throw new IllegalArgumentException( "can't handle non-ascii passwords yet" );
bout.write( (byte)passwd[i] );
}
}
catch ( IOException ioe ){
throw new RuntimeException( "impossible" , ioe );
}
return Util.hexMD5( bout.toByteArray() );
}
/**
* Returns the last error that occurred since start of database or a call to <code>resetError()</code>
*
* The return object will look like
*
* <pre>
* { err : errorMessage, nPrev : countOpsBack, ok : 1 }
* </pre>
*
* The value for errorMessage will be null of no error has occurred, otherwise the error message.
* The value of countOpsBack will be the number of operations since the error occurred.
*
* Care must be taken to ensure that calls to getPreviousError go to the same connection as that
* of the previous operation.
* See {@link DB#requestStart()} for more information.
*
* @return DBObject with error and status information
* @throws MongoException
*/
public CommandResult getPreviousError(){
return command(new BasicDBObject("getpreverror", 1));
}
/**
* Resets the error memory for this database.
* Used to clear all errors such that {@link DB#getPreviousError()} will return no error.
* @throws MongoException
*/
public void resetError(){
command(new BasicDBObject("reseterror", 1));
}
/**
* For testing purposes only - this method forces an error to help test error handling
* @throws MongoException
*/
public void forceError(){
command(new BasicDBObject("forceerror", 1));
}
/**
* Gets the Mongo instance
* @return
*/
public Mongo getMongo(){
return _mongo;
}
/**
* Gets another database on same server
* @param name name of the database
* @return
*/
public DB getSisterDB( String name ){
return _mongo.getDB( name );
}
/**
* Makes it possible to execute "read" queries on a slave node
*
* @deprecated Replaced with {@code ReadPreference.secondaryPreferred()}
* @see ReadPreference#secondaryPreferred()
*/
@Deprecated
public void slaveOk(){
addOption( Bytes.QUERYOPTION_SLAVEOK );
}
/**
* Adds the give option
* @param option
*/
public void addOption( int option ){
_options.add( option );
}
/**
* Sets the query options
* @param options
*/
public void setOptions( int options ){
_options.set( options );
}
/**
* Resets the query options
*/
public void resetOptions(){
_options.reset();
}
/**
* Gets the query options
* @return
*/
public int getOptions(){
return _options.get();
}
public abstract void cleanCursors( boolean force );
MongoCredential getAuthenticationCredentials() {
return getMongo().getAuthority().getCredentialsStore().get(getName());
}
final Mongo _mongo;
final String _name;
protected boolean _readOnly = false;
private com.massivecraft.massivecore.xlib.mongodb.WriteConcern _concern;
private com.massivecraft.massivecore.xlib.mongodb.ReadPreference _readPref;
final Bytes.OptionHolder _options;
// cached authentication command result, to return in case of multiple calls to authenticateCommand with the
// same credentials
private volatile CommandResult authenticationTestCommandResult;
}

View File

@ -1,187 +0,0 @@
// DBAddress.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* Represents a database address
*/
public class DBAddress extends ServerAddress {
/** Creates a new address
* Accepts as the parameter format:
* <table border="1">
* <tr>
* <td><i>name</i></td>
* <td>"mydb"</td>
* </tr>
* <tr>
* <td><i>&lt;host&gt;/name</i></td>
* <td>"127.0.0.1/mydb"</td>
* </tr>
* <tr>
* <td><i>&lt;host&gt;:&lt;port&gt;/name</i></td>
* <td>"127.0.0.1:8080/mydb"</td>
* </tr>
* </table>
* @param urlFormat
* @throws UnknownHostException
*/
public DBAddress( String urlFormat )
throws UnknownHostException {
super( _getHostSection( urlFormat ) );
_check( urlFormat , "urlFormat" );
_db = _fixName( _getDBSection( urlFormat ) );
_check( _host , "host" );
_check( _db , "db" );
}
static String _getHostSection( String urlFormat ){
if ( urlFormat == null )
throw new NullPointerException( "urlFormat can't be null" );
int idx = urlFormat.indexOf( "/" );
if ( idx >= 0 )
return urlFormat.substring( 0 , idx );
return null;
}
static String _getDBSection( String urlFormat ){
if ( urlFormat == null )
throw new NullPointerException( "urlFormat can't be null" );
int idx = urlFormat.indexOf( "/" );
if ( idx >= 0 )
return urlFormat.substring( idx + 1 );
return urlFormat;
}
static String _fixName( String name ){
name = name.replace( '.' , '-' );
return name;
}
/**
* @param other an existing <code>DBAddress</code> that gives the host and port
* @param dbname the database to which to connect
* @throws UnknownHostException
*/
public DBAddress( DBAddress other , String dbname )
throws UnknownHostException {
this( other._host , other._port , dbname );
}
/**
* @param host host name
* @param dbname database name
* @throws UnknownHostException
*/
public DBAddress( String host , String dbname )
throws UnknownHostException {
this( host , DBPort.PORT , dbname );
}
/**
* @param host host name
* @param port database port
* @param dbname database name
* @throws UnknownHostException
*/
public DBAddress( String host , int port , String dbname )
throws UnknownHostException {
super( host , port );
_db = dbname.trim();
}
/**
* @param addr host address
* @param port database port
* @param dbname database name
*/
public DBAddress( InetAddress addr , int port , String dbname ){
super( addr , port );
_check( dbname , "name" );
_db = dbname.trim();
}
static void _check( String thing , String name ){
if ( thing == null )
throw new NullPointerException( name + " can't be null " );
thing = thing.trim();
if ( thing.length() == 0 )
throw new IllegalArgumentException( name + " can't be empty" );
}
@Override
public int hashCode(){
return super.hashCode() + _db.hashCode();
}
@Override
public boolean equals( Object other ){
if ( other instanceof DBAddress ){
DBAddress a = (DBAddress)other;
return
a._port == _port &&
a._db.equals( _db ) &&
a._host.equals( _host );
} else if ( other instanceof ServerAddress ){
return other.equals(this);
}
return false;
}
/**
* creates a DBAddress pointing to a different database on the same server
* @param name database name
* @return
* @throws MongoException
*/
public DBAddress getSister( String name ){
try {
return new DBAddress( _host , _port , name );
}
catch ( UnknownHostException uh ){
throw new MongoInternalException( "shouldn't be possible" , uh );
}
}
/**
* gets the database name
* @return
*/
public String getDBName(){
return _db;
}
/**
* gets a String representation of address as host:port/dbname.
* @return this address
*/
@Override
public String toString(){
return super.toString() + "/" + _db;
}
final String _db;
}

View File

@ -1,556 +0,0 @@
// DBApiLayer.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
import com.massivecraft.massivecore.xlib.bson.BSONObject;
import com.massivecraft.massivecore.xlib.bson.types.ObjectId;
import com.massivecraft.massivecore.xlib.mongodb.util.JSON;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
/** Database API
* This cannot be directly instantiated, but the functions are available
* through instances of Mongo.
*/
public class DBApiLayer extends DB {
/** The maximum number of cursors allowed */
static final int NUM_CURSORS_BEFORE_KILL = 100;
static final int NUM_CURSORS_PER_BATCH = 20000;
// --- show
static final Logger TRACE_LOGGER = Logger.getLogger( "com.mongodb.TRACE" );
static final Level TRACE_LEVEL = Boolean.getBoolean( "DB.TRACE" ) ? Level.INFO : Level.FINEST;
static boolean willTrace(){
return TRACE_LOGGER.isLoggable( TRACE_LEVEL );
}
static void trace( String s ){
TRACE_LOGGER.log( TRACE_LEVEL , s );
}
static int chooseBatchSize(int batchSize, int limit, int fetched) {
int bs = Math.abs(batchSize);
int remaining = limit > 0 ? limit - fetched : 0;
int res;
if (bs == 0 && remaining > 0)
res = remaining;
else if (bs > 0 && remaining == 0)
res = bs;
else
res = Math.min(bs, remaining);
if (batchSize < 0) {
// force close
res = -res;
}
if (res == 1) {
// optimization: use negative batchsize to close cursor
res = -1;
}
return res;
}
/**
* @param mongo the Mongo instance
* @param name the database name
* @param connector the connector
*/
protected DBApiLayer( Mongo mongo, String name , DBConnector connector ){
super( mongo, name );
if ( connector == null )
throw new IllegalArgumentException( "need a connector: " + name );
_root = name;
_rootPlusDot = _root + ".";
_connector = connector;
}
public void requestStart(){
_connector.requestStart();
}
public void requestDone(){
_connector.requestDone();
}
public void requestEnsureConnection(){
_connector.requestEnsureConnection();
}
protected MyCollection doGetCollection( String name ){
MyCollection c = _collections.get( name );
if ( c != null )
return c;
c = new MyCollection( name );
MyCollection old = _collections.putIfAbsent(name, c);
return old != null ? old : c;
}
/**
* @param force true if should clean regardless of number of dead cursors
* @throws MongoException
*/
public void cleanCursors( boolean force ){
int sz = _deadCursorIds.size();
if ( sz == 0 || ( ! force && sz < NUM_CURSORS_BEFORE_KILL))
return;
Bytes.LOGGER.info( "going to kill cursors : " + sz );
Map<ServerAddress,List<Long>> m = new HashMap<ServerAddress,List<Long>>();
DeadCursor c;
while (( c = _deadCursorIds.poll()) != null ){
List<Long> x = m.get( c.host );
if ( x == null ){
x = new LinkedList<Long>();
m.put( c.host , x );
}
x.add( c.id );
}
for ( Map.Entry<ServerAddress,List<Long>> e : m.entrySet() ){
try {
killCursors( e.getKey() , e.getValue() );
}
catch ( Throwable t ){
Bytes.LOGGER.log( Level.WARNING , "can't clean cursors" , t );
for ( Long x : e.getValue() )
_deadCursorIds.add( new DeadCursor( x , e.getKey() ) );
}
}
}
void killCursors( ServerAddress addr , List<Long> all ){
if ( all == null || all.size() == 0 )
return;
OutMessage om = OutMessage.killCursors(_mongo, Math.min( NUM_CURSORS_PER_BATCH , all.size()));
int soFar = 0;
int totalSoFar = 0;
for (Long l : all) {
om.writeLong(l);
totalSoFar++;
soFar++;
if ( soFar >= NUM_CURSORS_PER_BATCH ){
_connector.say( this , om ,com.massivecraft.massivecore.xlib.mongodb.WriteConcern.NONE );
om = OutMessage.killCursors(_mongo, Math.min( NUM_CURSORS_PER_BATCH , all.size() - totalSoFar));
soFar = 0;
}
}
_connector.say( this , om ,com.massivecraft.massivecore.xlib.mongodb.WriteConcern.NONE , addr );
}
@Override
CommandResult doAuthenticate(MongoCredential credentials) {
return _connector.authenticate(credentials);
}
class MyCollection extends DBCollection {
MyCollection( String name ){
super( DBApiLayer.this , name );
_fullNameSpace = _root + "." + name;
}
public void doapply( DBObject o ){
}
@Override
public void drop(){
_collections.remove(getName());
super.drop();
}
public WriteResult insert(List<DBObject> list, com.massivecraft.massivecore.xlib.mongodb.WriteConcern concern, DBEncoder encoder ){
if (concern == null) {
throw new IllegalArgumentException("Write concern can not be null");
}
return insert(list, true, concern, encoder);
}
protected WriteResult insert(List<DBObject> list, boolean shouldApply , com.massivecraft.massivecore.xlib.mongodb.WriteConcern concern, DBEncoder encoder ){
if (encoder == null)
encoder = DefaultDBEncoder.FACTORY.create();
if ( willTrace() ) {
for (DBObject o : list) {
trace( "save: " + _fullNameSpace + " " + JSON.serialize( o ) );
}
}
if ( shouldApply ){
for (DBObject o : list) {
apply(o);
_checkObject(o, false, false);
Object id = o.get("_id");
if (id instanceof ObjectId) {
((ObjectId) id).notNew();
}
}
}
WriteResult last = null;
int cur = 0;
int maxsize = _mongo.getMaxBsonObjectSize();
while ( cur < list.size() ) {
OutMessage om = OutMessage.insert( this , encoder, concern );
for ( ; cur < list.size(); cur++ ){
DBObject o = list.get(cur);
om.putObject( o );
// limit for batch insert is 4 x maxbson on server, use 2 x to be safe
if ( om.size() > 2 * maxsize ){
cur++;
break;
}
}
last = _connector.say( _db , om , concern );
}
return last;
}
public WriteResult remove( DBObject o , com.massivecraft.massivecore.xlib.mongodb.WriteConcern concern, DBEncoder encoder ){
if (concern == null) {
throw new IllegalArgumentException("Write concern can not be null");
}
if (encoder == null)
encoder = DefaultDBEncoder.FACTORY.create();
if ( willTrace() ) trace( "remove: " + _fullNameSpace + " " + JSON.serialize( o ) );
OutMessage om = OutMessage.remove(this, encoder, o);
return _connector.say( _db , om , concern );
}
@Override
Iterator<DBObject> __find( DBObject ref , DBObject fields , int numToSkip , int batchSize, int limit , int options, ReadPreference readPref, DBDecoder decoder ){
return __find(ref, fields, numToSkip, batchSize, limit, options, readPref, decoder, DefaultDBEncoder.FACTORY.create());
}
@Override
Iterator<DBObject> __find( DBObject ref , DBObject fields , int numToSkip , int batchSize , int limit, int options,
ReadPreference readPref, DBDecoder decoder, DBEncoder encoder ){
if ( ref == null )
ref = new BasicDBObject();
if ( willTrace() ) trace( "find: " + _fullNameSpace + " " + JSON.serialize( ref ) );
OutMessage query = OutMessage.query( this , options , numToSkip , chooseBatchSize(batchSize, limit, 0) , ref , fields, readPref,
encoder);
Response res = _connector.call( _db , this , query , null , 2, readPref, decoder );
if ( res.size() == 1 ){
BSONObject foo = res.get(0);
MongoException e = MongoException.parse( foo );
if ( e != null && ! _name.equals( "$cmd" ) )
throw e;
}
return new Result( this , res , batchSize, limit , options, decoder );
}
@Override
public WriteResult update( DBObject query , DBObject o , boolean upsert , boolean multi , com.massivecraft.massivecore.xlib.mongodb.WriteConcern concern, DBEncoder encoder ){
if (o == null) {
throw new IllegalArgumentException("update can not be null");
}
if (concern == null) {
throw new IllegalArgumentException("Write concern can not be null");
}
if (encoder == null)
encoder = DefaultDBEncoder.FACTORY.create();
if (!o.keySet().isEmpty()) {
// if 1st key doesn't start with $, then object will be inserted as is, need to check it
String key = o.keySet().iterator().next();
if (!key.startsWith("$"))
_checkObject(o, false, false);
}
if ( willTrace() ) {
trace( "update: " + _fullNameSpace + " " + JSON.serialize( query ) + " " + JSON.serialize( o ) );
}
OutMessage om = OutMessage.update(this, encoder, upsert, multi, query, o);
return _connector.say( _db , om , concern );
}
public void createIndex( final DBObject keys, final DBObject options, DBEncoder encoder ){
if (encoder == null)
encoder = DefaultDBEncoder.FACTORY.create();
DBObject full = new BasicDBObject();
for ( String k : options.keySet() )
full.put( k , options.get( k ) );
full.put( "key" , keys );
MyCollection idxs = DBApiLayer.this.doGetCollection( "system.indexes" );
//query first, maybe we should do an update w/upsert? -- need to test performance and lock behavior
if ( idxs.findOne( full ) == null )
idxs.insert(Arrays.asList(full), false, WriteConcern.SAFE, encoder);
}
final String _fullNameSpace;
}
class Result implements Iterator<DBObject> {
Result( MyCollection coll , Response res , int batchSize, int limit , int options, DBDecoder decoder ){
_collection = coll;
_batchSize = batchSize;
_limit = limit;
_options = options;
_host = res._host;
_decoder = decoder;
init( res );
// Only enable finalizer if cursor finalization is enabled and there is actually a cursor that needs killing
_optionalFinalizer = _mongo.getMongoOptions().isCursorFinalizerEnabled() && res.cursor() != 0 ?
new OptionalFinalizer() : null;
}
private void init( Response res ){
if ( ( res._flags & Bytes.RESULTFLAG_CURSORNOTFOUND ) > 0 ){
throw new MongoException.CursorNotFound(_curResult.cursor(), res.serverUsed());
}
_totalBytes += res._len;
_curResult = res;
_cur = res.iterator();
_sizes.add( res.size() );
_numFetched += res.size();
if (res._cursor != 0 && _limit > 0 && _limit - _numFetched <= 0) {
// fetched all docs within limit, close cursor server-side
killCursor();
}
}
public DBObject next(){
if ( _cur.hasNext() ) {
return _cur.next();
}
if ( ! _curResult.hasGetMore( _options ) )
throw new NoSuchElementException("no more");
_advance();
return next();
}
public boolean hasNext(){
boolean hasNext = _cur.hasNext();
while ( !hasNext ) {
if ( ! _curResult.hasGetMore( _options ) )
return false;
_advance();
hasNext = _cur.hasNext();
if (!hasNext) {
if ( ( _options & Bytes.QUERYOPTION_AWAITDATA ) == 0 ) {
// dont block waiting for data if no await
return false;
} else {
// if await, driver should block until data is available
// if server does not support await, driver must sleep to avoid busy loop
if ((_curResult._flags & Bytes.RESULTFLAG_AWAITCAPABLE) == 0) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new MongoInterruptedException(e);
}
}
}
}
}
return hasNext;
}
private void _advance(){
if ( _curResult.cursor() <= 0 )
throw new RuntimeException( "can't advance a cursor <= 0" );
OutMessage m = OutMessage.getMore(_collection, _curResult.cursor(),
chooseBatchSize(_batchSize, _limit, _numFetched));
Response res = _connector.call( DBApiLayer.this , _collection , m , _host, _decoder );
_numGetMores++;
init( res );
}
public void remove(){
throw new RuntimeException( "can't remove this way" );
}
public int getBatchSize(){
return _batchSize;
}
public void setBatchSize(int size){
_batchSize = size;
}
public String toString(){
return "DBCursor";
}
public long totalBytes(){
return _totalBytes;
}
public long getCursorId(){
if ( _curResult == null )
return 0;
return _curResult._cursor;
}
int numGetMores(){
return _numGetMores;
}
List<Integer> getSizes(){
return Collections.unmodifiableList( _sizes );
}
void close(){
// not perfectly thread safe here, may need to use an atomicBoolean
if (_curResult != null) {
killCursor();
_curResult = null;
_cur = null;
}
}
void killCursor() {
if (_curResult == null)
return;
long curId = _curResult.cursor();
if (curId == 0)
return;
List<Long> l = new ArrayList<Long>();
l.add(curId);
try {
killCursors(_host, l);
} catch (Throwable t) {
Bytes.LOGGER.log(Level.WARNING, "can't clean 1 cursor", t);
_deadCursorIds.add(new DeadCursor(curId, _host));
}
_curResult._cursor = 0;
}
public ServerAddress getServerAddress() {
return _host;
}
boolean hasFinalizer() {
return _optionalFinalizer != null;
}
Response _curResult;
Iterator<DBObject> _cur;
int _batchSize;
int _limit;
final DBDecoder _decoder;
final MyCollection _collection;
final int _options;
final ServerAddress _host; // host where first went. all subsequent have to go there
private long _totalBytes = 0;
private int _numGetMores = 0;
private List<Integer> _sizes = new ArrayList<Integer>();
private int _numFetched = 0;
// This allows us to easily enable/disable finalizer for cleaning up un-closed cursors
private final OptionalFinalizer _optionalFinalizer;
private class OptionalFinalizer {
@Override
protected void finalize() {
if (_curResult != null) {
long curId = _curResult.cursor();
_curResult = null;
_cur = null;
if (curId != 0) {
_deadCursorIds.add(new DeadCursor(curId, _host));
}
}
}
}
} // class Result
static class DeadCursor {
DeadCursor( long a , ServerAddress b ){
id = a;
host = b;
}
final long id;
final ServerAddress host;
}
final String _root;
final String _rootPlusDot;
final DBConnector _connector;
final ConcurrentHashMap<String,MyCollection> _collections = new ConcurrentHashMap<String,MyCollection>();
ConcurrentLinkedQueue<DeadCursor> _deadCursorIds = new ConcurrentLinkedQueue<DeadCursor>();
}

View File

@ -1,30 +0,0 @@
// DBCallback.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
import com.massivecraft.massivecore.xlib.bson.BSONCallback;
/**
* The DB callback interface.
*/
public interface DBCallback extends BSONCallback {
}

View File

@ -1,27 +0,0 @@
/**
* Copyright (C) 2011 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
/**
* The DBCallback factory interface.
*/
public interface DBCallbackFactory {
public DBCallback create( DBCollection collection );
}

File diff suppressed because it is too large Load Diff

View File

@ -1,116 +0,0 @@
// DBConnector.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
/**
* Interface that provides the ability to exchange request/response with the database
*/
public interface DBConnector {
/**
* initiates a "consistent request" on the thread.
* Once this has been called, the connector will ensure that the same underlying connection is always used for a given thread.
* This happens until requestStop() is called.
*/
public void requestStart();
/**
* terminates the "consistent request".
*/
public void requestDone();
/**
* Ensures that a connection exists for the "consistent request"
*/
public void requestEnsureConnection();
/**
* does a write operation
* @param db the database
* @param m the request message
* @param concern the write concern
* @return the write result
* @throws MongoException
*/
public WriteResult say( DB db , OutMessage m , WriteConcern concern );
/**
* does a write operation
* @param db the database
* @param m the request message
* @param concern the write concern
* @param hostNeeded specific server to connect to
* @return the write result
* @throws MongoException
*/
public WriteResult say( DB db , OutMessage m , WriteConcern concern , ServerAddress hostNeeded );
/**
* does a read operation on the database
* @param db the database
* @param coll the collection
* @param m the request message
* @param hostNeeded specific server to connect to
* @param decoder the decoder to use
* @return the read result
* @throws MongoException
*/
public Response call( DB db , DBCollection coll , OutMessage m ,
ServerAddress hostNeeded , DBDecoder decoder );
/**
*
* does a read operation on the database
* @param db the database
* @param coll the collection
* @param m the request message
* @param hostNeeded specific server to connect to
* @param retries the number of retries in case of an error
* @return the read result
* @throws MongoException
*/
public Response call( DB db , DBCollection coll , OutMessage m , ServerAddress hostNeeded , int retries );
/**
* does a read operation on the database
* @param db the database
* @param coll the collection
* @param m the request message
* @param hostNeeded specific server to connect to
* @param retries number of retries in case of error
* @param readPref the read preferences
* @param decoder the decoder to use
* @return the read result
* @throws MongoException
*/
public Response call( DB db , DBCollection coll , OutMessage m , ServerAddress hostNeeded , int retries , ReadPreference readPref , DBDecoder decoder );
/**
* returns true if the connector is in a usable state
* @return
*/
public boolean isOpen();
/**
* Authenticate using the given credentials.
*
* @param credentials the credentials.
* @return the result of the authentication command, if successful
* @throws CommandFailureException if the authentication failed
* @since 2.11.0
*/
public CommandResult authenticate(MongoCredential credentials);
}

View File

@ -1,730 +0,0 @@
// DBCursor.java
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
import com.massivecraft.massivecore.xlib.mongodb.DBApiLayer.Result;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/** An iterator over database results.
* Doing a <code>find()</code> query on a collection returns a
* <code>DBCursor</code> thus
*
* <blockquote><pre>
* DBCursor cursor = collection.find( query );
* if( cursor.hasNext() )
* DBObject obj = cursor.next();
* </pre></blockquote>
*
* <p><b>Warning:</b> Calling <code>toArray</code> or <code>length</code> on
* a DBCursor will irrevocably turn it into an array. This
* means that, if the cursor was iterating over ten million results
* (which it was lazily fetching from the database), suddenly there will
* be a ten-million element array in memory. Before converting to an array,
* make sure that there are a reasonable number of results using
* <code>skip()</code> and <code>limit()</code>.
* <p>For example, to get an array of the 1000-1100th elements of a cursor, use
*
* <blockquote><pre>
* List<DBObject> obj = collection.find( query ).skip( 1000 ).limit( 100 ).toArray();
* </pre></blockquote>
*
* @dochub cursors
*/
public class DBCursor implements Iterator<DBObject> , Iterable<DBObject>, Closeable {
/**
* Initializes a new database cursor
* @param collection collection to use
* @param q query to perform
* @param k keys to return from the query
* @param preference the Read Preference for this query
*/
public DBCursor( DBCollection collection , DBObject q , DBObject k, ReadPreference preference ){
if (collection == null) {
throw new IllegalArgumentException("collection is null");
}
_collection = collection;
_query = q == null ? new BasicDBObject() : q;
_keysWanted = k;
_options = _collection.getOptions();
_readPref = preference;
_decoderFact = collection.getDBDecoderFactory();
}
/**
* Types of cursors: iterator or array.
*/
static enum CursorType { ITERATOR , ARRAY };
/**
* Creates a copy of an existing database cursor.
* The new cursor is an iterator, even if the original
* was an array.
*
* @return the new cursor
*/
public DBCursor copy() {
DBCursor c = new DBCursor(_collection, _query, _keysWanted, _readPref);
c._orderBy = _orderBy;
c._hint = _hint;
c._hintDBObj = _hintDBObj;
c._limit = _limit;
c._skip = _skip;
c._options = _options;
c._batchSize = _batchSize;
c._snapshot = _snapshot;
c._explain = _explain;
if ( _specialFields != null )
c._specialFields = new BasicDBObject( _specialFields.toMap() );
return c;
}
/**
* creates a copy of this cursor object that can be iterated.
* Note:
* - you can iterate the DBCursor itself without calling this method
* - no actual data is getting copied.
*
* @return
*/
public Iterator<DBObject> iterator(){
return this.copy();
}
// ---- querty modifiers --------
/**
* Sorts this cursor's elements.
* This method must be called before getting any object from the cursor.
* @param orderBy the fields by which to sort
* @return a cursor pointing to the first element of the sorted results
*/
public DBCursor sort( DBObject orderBy ){
if ( _it != null )
throw new IllegalStateException( "can't sort after executing query" );
_orderBy = orderBy;
return this;
}
/**
* adds a special operator like $maxScan or $returnKey
* e.g. addSpecial( "$returnKey" , 1 )
* e.g. addSpecial( "$maxScan" , 100 )
* @param name
* @param o
* @return
* @dochub specialOperators
*/
public DBCursor addSpecial( String name , Object o ){
if ( _specialFields == null )
_specialFields = new BasicDBObject();
_specialFields.put( name , o );
return this;
}
/**
* Informs the database of indexed fields of the collection in order to improve performance.
* @param indexKeys a <code>DBObject</code> with fields and direction
* @return same DBCursor for chaining operations
*/
public DBCursor hint( DBObject indexKeys ){
if ( _it != null )
throw new IllegalStateException( "can't hint after executing query" );
_hintDBObj = indexKeys;
return this;
}
/**
* Informs the database of an indexed field of the collection in order to improve performance.
* @param indexName the name of an index
* @return same DBCursor for chaining operations
*/
public DBCursor hint( String indexName ){
if ( _it != null )
throw new IllegalStateException( "can't hint after executing query" );
_hint = indexName;
return this;
}
/**
* Use snapshot mode for the query. Snapshot mode assures no duplicates are
* returned, or objects missed, which were present at both the start and end
* of the query's execution (if an object is new during the query, or deleted
* during the query, it may or may not be returned, even with snapshot mode).
* Note that short query responses (less than 1MB) are always effectively snapshotted.
* Currently, snapshot mode may not be used with sorting or explicit hints.
* @return same DBCursor for chaining operations
*/
public DBCursor snapshot() {
if (_it != null)
throw new IllegalStateException("can't snapshot after executing the query");
_snapshot = true;
return this;
}
/**
* Returns an object containing basic information about the
* execution of the query that created this cursor
* This creates a <code>DBObject</code> with the key/value pairs:
* "cursor" : cursor type
* "nScanned" : number of records examined by the database for this query
* "n" : the number of records that the database returned
* "millis" : how long it took the database to execute the query
* @return a <code>DBObject</code>
* @throws MongoException
* @dochub explain
*/
public DBObject explain(){
DBCursor c = copy();
c._explain = true;
if (c._limit > 0) {
// need to pass a negative batchSize as limit for explain
c._batchSize = c._limit * -1;
c._limit = 0;
}
return c.next();
}
/**
* Limits the number of elements returned.
* Note: parameter <tt>n</tt> should be positive, although a negative value is supported for legacy reason.
* Passing a negative value will call {@link DBCursor#batchSize(int)} which is the preferred method.
* @param n the number of elements to return
* @return a cursor to iterate the results
* @dochub limit
*/
public DBCursor limit( int n ){
if ( _it != null )
throw new IllegalStateException( "can't set limit after executing query" );
if (n > 0)
_limit = n;
else if (n < 0)
batchSize(n);
return this;
}
/**
* Limits the number of elements returned in one batch.
* A cursor typically fetches a batch of result objects and store them locally.
*
* If <tt>batchSize</tt> is positive, it represents the size of each batch of objects retrieved.
* It can be adjusted to optimize performance and limit data transfer.
*
* If <tt>batchSize</tt> is negative, it will limit of number objects returned, that fit within the max batch size limit (usually 4MB), and cursor will be closed.
* For example if <tt>batchSize</tt> is -10, then the server will return a maximum of 10 documents and as many as can fit in 4MB, then close the cursor.
* Note that this feature is different from limit() in that documents must fit within a maximum size, and it removes the need to send a request to close the cursor server-side.
*
* The batch size can be changed even after a cursor is iterated, in which case the setting will apply on the next batch retrieval.
*
* @param n the number of elements to return in a batch
* @return
*/
public DBCursor batchSize( int n ){
// check for special case, used to have server bug with 1
if ( n == 1 )
n = 2;
if ( _it != null ) {
if (_it instanceof DBApiLayer.Result)
((DBApiLayer.Result)_it).setBatchSize(n);
}
_batchSize = n;
return this;
}
/**
* Discards a given number of elements at the beginning of the cursor.
* @param n the number of elements to skip
* @return a cursor pointing to the new first element of the results
* @throws IllegalStateException if the cursor has started to be iterated through
*/
public DBCursor skip( int n ){
if ( _it != null )
throw new IllegalStateException( "can't set skip after executing query" );
_skip = n;
return this;
}
/**
* gets the cursor id.
* @return the cursor id, or 0 if there is no active cursor.
*/
public long getCursorId() {
if ( _it instanceof Result )
return ((Result)_it).getCursorId();
return 0;
}
/**
* kills the current cursor on the server.
*/
public void close() {
if ( _it instanceof Result )
((Result)_it).close();
}
/**
* makes this query ok to run on a slave node
*
* @return a copy of the same cursor (for chaining)
*
* @deprecated Replaced with {@code ReadPreference.secondaryPreferred()}
* @see ReadPreference#secondaryPreferred()
*/
@Deprecated
public DBCursor slaveOk(){
return addOption( Bytes.QUERYOPTION_SLAVEOK );
}
/**
* adds a query option - see Bytes.QUERYOPTION_* for list
* @param option
* @return
*/
public DBCursor addOption( int option ){
if ( option == Bytes.QUERYOPTION_EXHAUST )
throw new IllegalArgumentException("The exhaust option is not user settable.");
_options |= option;
return this;
}
/**
* sets the query option - see Bytes.QUERYOPTION_* for list
* @param options
*/
public DBCursor setOptions( int options ){
_options = options;
return this;
}
/**
* resets the query options
*/
public DBCursor resetOptions(){
_options = 0;
return this;
}
/**
* gets the query options
* @return
*/
public int getOptions(){
return _options;
}
// ---- internal stuff ------
private void _check() {
if (_it != null)
return;
_lookForHints();
QueryOpBuilder builder = new QueryOpBuilder()
.addQuery(_query)
.addOrderBy(_orderBy)
.addHint(_hintDBObj)
.addHint(_hint)
.addExplain(_explain)
.addSnapshot(_snapshot)
.addSpecialFields(_specialFields);
if (_collection.getDB().getMongo().isMongosConnection()) {
builder.addReadPreference(_readPref.toDBObject());
}
_it = _collection.__find(builder.get(), _keysWanted, _skip, _batchSize, _limit,
_options, _readPref, getDecoder());
}
// Only create a new decoder if there is a decoder factory explicitly set on the collection. Otherwise return null
// so that the collection can use a cached decoder
private DBDecoder getDecoder() {
return _decoderFact != null ? _decoderFact.create() : null;
}
/**
* if there is a hint to use, use it
*/
private void _lookForHints(){
if ( _hint != null ) // if someone set a hint, then don't do this
return;
if ( _collection._hintFields == null )
return;
Set<String> mykeys = _query.keySet();
for ( DBObject o : _collection._hintFields ){
Set<String> hintKeys = o.keySet();
if ( ! mykeys.containsAll( hintKeys ) )
continue;
hint( o );
return;
}
}
void _checkType( CursorType type ){
if ( _cursorType == null ){
_cursorType = type;
return;
}
if ( type == _cursorType )
return;
throw new IllegalArgumentException( "can't switch cursor access methods" );
}
private DBObject _next() {
if ( _cursorType == null )
_checkType( CursorType.ITERATOR );
_check();
_cur = _it.next();
_num++;
if ( _keysWanted != null && _keysWanted.keySet().size() > 0 ){
_cur.markAsPartialObject();
//throw new UnsupportedOperationException( "need to figure out partial" );
}
if ( _cursorType == CursorType.ARRAY ){
_all.add( _cur );
}
return _cur;
}
/**
* gets the number of times, so far, that the cursor retrieved a batch from the database
* @return
*/
public int numGetMores(){
if ( _it instanceof DBApiLayer.Result )
return ((DBApiLayer.Result)_it).numGetMores();
throw new IllegalArgumentException("_it not a real result" );
}
/**
* gets a list containing the number of items received in each batch
* @return
*/
public List<Integer> getSizes(){
if ( _it instanceof DBApiLayer.Result )
return ((DBApiLayer.Result)_it).getSizes();
throw new IllegalArgumentException("_it not a real result" );
}
private boolean _hasNext() {
_check();
if ( _limit > 0 && _num >= _limit )
return false;
return _it.hasNext();
}
/**
* Returns the number of objects through which the cursor has iterated.
* @return the number of objects seen
*/
public int numSeen(){
return _num;
}
// ----- iterator api -----
/**
* Checks if there is another object available
* @return
* @throws MongoException
*/
public boolean hasNext() {
_checkType( CursorType.ITERATOR );
return _hasNext();
}
/**
* Returns the object the cursor is at and moves the cursor ahead by one.
* @return the next element
* @throws MongoException
*/
public DBObject next() {
_checkType( CursorType.ITERATOR );
return _next();
}
/**
* Returns the element the cursor is at.
* @return the current element
*/
public DBObject curr(){
_checkType( CursorType.ITERATOR );
return _cur;
}
/**
* Not implemented.
*/
public void remove(){
throw new UnsupportedOperationException( "can't remove from a cursor" );
}
// ---- array api -----
void _fill( int n ){
_checkType( CursorType.ARRAY );
while ( n >= _all.size() && _hasNext() )
_next();
}
/**
* pulls back all items into an array and returns the number of objects.
* Note: this can be resource intensive
* @see #count()
* @see #size()
* @return the number of elements in the array
* @throws MongoException
*/
public int length() {
_checkType( CursorType.ARRAY );
_fill( Integer.MAX_VALUE );
return _all.size();
}
/**
* Converts this cursor to an array.
* @return an array of elements
* @throws MongoException
*/
public List<DBObject> toArray(){
return toArray( Integer.MAX_VALUE );
}
/**
* Converts this cursor to an array.
* @param max the maximum number of objects to return
* @return an array of objects
* @throws MongoException
*/
public List<DBObject> toArray( int max ) {
_checkType( CursorType.ARRAY );
_fill( max - 1 );
return _all;
}
/**
* for testing only!
* Iterates cursor and counts objects
* @see #count()
* @return num objects
* @throws MongoException
*/
public int itcount(){
int n = 0;
while ( this.hasNext() ){
this.next();
n++;
}
return n;
}
/**
* Counts the number of objects matching the query
* This does not take limit/skip into consideration
* @see #size()
* @return the number of objects
* @throws MongoException
*/
public int count() {
if ( _collection == null )
throw new IllegalArgumentException( "why is _collection null" );
if ( _collection._db == null )
throw new IllegalArgumentException( "why is _collection._db null" );
return (int)_collection.getCount(this._query, this._keysWanted, getReadPreference());
}
/**
* Counts the number of objects matching the query
* this does take limit/skip into consideration
* @see #count()
* @return the number of objects
* @throws MongoException
*/
public int size() {
if ( _collection == null )
throw new IllegalArgumentException( "why is _collection null" );
if ( _collection._db == null )
throw new IllegalArgumentException( "why is _collection._db null" );
return (int)_collection.getCount(this._query, this._keysWanted, this._limit, this._skip, getReadPreference() );
}
/**
* gets the fields to be returned
* @return
*/
public DBObject getKeysWanted(){
return _keysWanted;
}
/**
* gets the query
* @return
*/
public DBObject getQuery(){
return _query;
}
/**
* gets the collection
* @return
*/
public DBCollection getCollection(){
return _collection;
}
/**
* Gets the Server Address of the server that data is pulled from.
* Note that this information may not be available until hasNext() or next() is called.
* @return
*/
public ServerAddress getServerAddress() {
if (_it != null && _it instanceof DBApiLayer.Result)
return ((DBApiLayer.Result)_it).getServerAddress();
return null;
}
/**
* Sets the read preference for this cursor.
* See the * documentation for {@link ReadPreference}
* for more information.
*
* @param preference Read Preference to use
*/
public DBCursor setReadPreference( ReadPreference preference ){
_readPref = preference;
return this;
}
/**
* Gets the default read preference
* @return
*/
public ReadPreference getReadPreference(){
return _readPref;
}
public DBCursor setDecoderFactory(DBDecoderFactory fact){
_decoderFact = fact;
return this;
}
public DBDecoderFactory getDecoderFactory(){
return _decoderFact;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Cursor id=").append(getCursorId());
sb.append(", ns=").append(getCollection().getFullName());
sb.append(", query=").append(getQuery());
if (getKeysWanted() != null)
sb.append(", fields=").append(getKeysWanted());
sb.append(", numIterated=").append(_num);
if (_skip != 0)
sb.append(", skip=").append(_skip);
if (_limit != 0)
sb.append(", limit=").append(_limit);
if (_batchSize != 0)
sb.append(", batchSize=").append(_batchSize);
ServerAddress addr = getServerAddress();
if (addr != null)
sb.append(", addr=").append(addr);
if (_readPref != null)
sb.append(", readPreference=").append( _readPref.toString() );
return sb.toString();
}
boolean hasFinalizer() {
if (_it == null || ! (_it instanceof Result)) {
return false;
}
return ((Result) _it).hasFinalizer();
}
// ---- query setup ----
private final DBCollection _collection;
private final DBObject _query;
private final DBObject _keysWanted;
private DBObject _orderBy = null;
private String _hint = null;
private DBObject _hintDBObj = null;
private boolean _explain = false;
private int _limit = 0;
private int _batchSize = 0;
private int _skip = 0;
private boolean _snapshot = false;
private int _options = 0;
private ReadPreference _readPref;
private DBDecoderFactory _decoderFact;
private DBObject _specialFields;
// ---- result info ----
private Iterator<DBObject> _it = null;
private CursorType _cursorType = null;
private DBObject _cur = null;
private int _num = 0;
private final ArrayList<DBObject> _all = new ArrayList<DBObject>();
}

View File

@ -1,32 +0,0 @@
/**
* Copyright (C) 2008 10gen Inc.
*
* 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 com.massivecraft.massivecore.xlib.mongodb;
import java.io.IOException;
import java.io.InputStream;
import com.massivecraft.massivecore.xlib.bson.BSONDecoder;
/**
*
*/
public interface DBDecoder extends BSONDecoder {
public DBCallback getDBCallback(DBCollection collection);
public DBObject decode( byte[] b, DBCollection collection );
public DBObject decode( InputStream in, DBCollection collection ) throws IOException;
}

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