All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mongodb.internal.connection.ByteBufBsonDocument Maven / Gradle / Ivy

Go to download

The Java operations layer for the MongoDB Java Driver. Third parties can wrap this layer to provide custom higher-level APIs

The newest version!
/*
 * Copyright 2008-present MongoDB, 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.mongodb.internal.connection;

import com.mongodb.lang.Nullable;
import org.bson.BsonBinaryReader;
import org.bson.BsonDocument;
import org.bson.BsonType;
import org.bson.BsonValue;
import org.bson.ByteBuf;
import org.bson.RawBsonDocument;
import org.bson.codecs.BsonDocumentCodec;
import org.bson.codecs.DecoderContext;
import org.bson.io.ByteBufferBsonInput;
import org.bson.json.JsonMode;
import org.bson.json.JsonWriter;
import org.bson.json.JsonWriterSettings;

import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.StringWriter;
import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import static com.mongodb.assertions.Assertions.assertNotNull;
import static com.mongodb.assertions.Assertions.notNull;
import static com.mongodb.internal.connection.ByteBufBsonHelper.readBsonValue;

final class ByteBufBsonDocument extends BsonDocument {
    private static final long serialVersionUID = 2L;

    private final transient ByteBuf byteBuf;

    /**
     * Create a list of ByteBufBsonDocument from a buffer positioned at the start of the first document of an OP_MSG Section
     * of type Document Sequence (Kind 1).
     * 

* The provided buffer will be positioned at the end of the section upon normal completion of the method */ static List createList(final ByteBuf outputByteBuf) { List documents = new ArrayList<>(); while (outputByteBuf.hasRemaining()) { ByteBufBsonDocument curDocument = createOne(outputByteBuf); documents.add(curDocument); } return documents; } /** * Create a ByteBufBsonDocument from a buffer positioned at the start of a BSON document. * The provided buffer will be positioned at the end of the document upon normal completion of the method */ static ByteBufBsonDocument createOne(final ByteBuf outputByteBuf) { int documentStart = outputByteBuf.position(); int documentSizeInBytes = outputByteBuf.getInt(); int documentEnd = documentStart + documentSizeInBytes; ByteBuf slice = outputByteBuf.duplicate().position(documentStart).limit(documentEnd); outputByteBuf.position(documentEnd); return new ByteBufBsonDocument(slice); } @Override public String toJson() { return toJson(JsonWriterSettings.builder().outputMode(JsonMode.RELAXED).build()); } @Override public String toJson(final JsonWriterSettings settings) { StringWriter stringWriter = new StringWriter(); JsonWriter jsonWriter = new JsonWriter(stringWriter, settings); ByteBuf duplicate = byteBuf.duplicate(); try (BsonBinaryReader reader = new BsonBinaryReader(new ByteBufferBsonInput(duplicate))) { jsonWriter.pipe(reader); return stringWriter.toString(); } finally { duplicate.release(); } } @Override public BsonBinaryReader asBsonReader() { return new BsonBinaryReader(new ByteBufferBsonInput(byteBuf.duplicate())); } @SuppressWarnings("MethodDoesntCallSuperMethod") @Override public BsonDocument clone() { byte[] clonedBytes = new byte[byteBuf.remaining()]; byteBuf.get(byteBuf.position(), clonedBytes); return new RawBsonDocument(clonedBytes); } @Nullable T findInDocument(final Finder finder) { ByteBuf duplicateByteBuf = byteBuf.duplicate(); try (BsonBinaryReader bsonReader = new BsonBinaryReader(new ByteBufferBsonInput(duplicateByteBuf))) { bsonReader.readStartDocument(); while (bsonReader.readBsonType() != BsonType.END_OF_DOCUMENT) { T found = finder.find(duplicateByteBuf, bsonReader); if (found != null) { return found; } } bsonReader.readEndDocument(); } finally { duplicateByteBuf.release(); } return finder.notFound(); } BsonDocument toBaseBsonDocument() { ByteBuf duplicateByteBuf = byteBuf.duplicate(); try (BsonBinaryReader bsonReader = new BsonBinaryReader(new ByteBufferBsonInput(duplicateByteBuf))) { return new BsonDocumentCodec().decode(bsonReader, DecoderContext.builder().build()); } finally { duplicateByteBuf.release(); } } ByteBufBsonDocument(final ByteBuf byteBuf) { this.byteBuf = byteBuf; } @Override public void clear() { throw new UnsupportedOperationException("ByteBufBsonDocument instances are immutable"); } @Override public BsonValue put(final String key, final BsonValue value) { throw new UnsupportedOperationException("ByteBufBsonDocument instances are immutable"); } @Override public BsonDocument append(final String key, final BsonValue value) { throw new UnsupportedOperationException("ByteBufBsonDocument instances are immutable"); } @Override public void putAll(final Map m) { throw new UnsupportedOperationException("ByteBufBsonDocument instances are immutable"); } @Override public BsonValue remove(final Object key) { throw new UnsupportedOperationException("ByteBufBsonDocument instances are immutable"); } @Override public boolean isEmpty() { return assertNotNull(findInDocument(new Finder() { @Override public Boolean find(final ByteBuf byteBuf, final BsonBinaryReader bsonReader) { return false; } @Override public Boolean notFound() { return true; } })); } @Override public int size() { return assertNotNull(findInDocument(new Finder() { private int size; @Override @Nullable public Integer find(final ByteBuf byteBuf, final BsonBinaryReader bsonReader) { size++; bsonReader.readName(); bsonReader.skipValue(); return null; } @Override public Integer notFound() { return size; } })); } @Override public Set> entrySet() { return new ByteBufBsonDocumentEntrySet(); } @Override public Collection values() { return new ByteBufBsonDocumentValuesCollection(); } @Override public Set keySet() { return new ByteBufBsonDocumentKeySet(); } @Override public boolean containsKey(final Object key) { if (key == null) { throw new IllegalArgumentException("key can not be null"); } Boolean containsKey = findInDocument(new Finder() { @Override public Boolean find(final ByteBuf byteBuf, final BsonBinaryReader bsonReader) { if (bsonReader.readName().equals(key)) { return true; } bsonReader.skipValue(); return null; } @Override public Boolean notFound() { return false; } }); return containsKey != null ? containsKey : false; } @Override public boolean containsValue(final Object value) { Boolean containsValue = findInDocument(new Finder() { @Override public Boolean find(final ByteBuf byteBuf, final BsonBinaryReader bsonReader) { bsonReader.skipName(); if (readBsonValue(byteBuf, bsonReader).equals(value)) { return true; } return null; } @Override public Boolean notFound() { return false; } }); return containsValue != null ? containsValue : false; } @Nullable @Override public BsonValue get(final Object key) { notNull("key", key); return findInDocument(new Finder() { @Override public BsonValue find(final ByteBuf byteBuf, final BsonBinaryReader bsonReader) { if (bsonReader.readName().equals(key)) { return readBsonValue(byteBuf, bsonReader); } bsonReader.skipValue(); return null; } @Nullable @Override public BsonValue notFound() { return null; } }); } /** * Gets the first key in this document. * * @return the first key in this document * @throws java.util.NoSuchElementException if the document is empty */ public String getFirstKey() { return assertNotNull(findInDocument(new Finder() { @Override public String find(final ByteBuf byteBuf, final BsonBinaryReader bsonReader) { return bsonReader.readName(); } @Override public String notFound() { throw new NoSuchElementException(); } })); } private interface Finder { @Nullable T find(ByteBuf byteBuf, BsonBinaryReader bsonReader); @Nullable T notFound(); } // see https://docs.oracle.com/javase/6/docs/platform/serialization/spec/output.html private Object writeReplace() { return toBaseBsonDocument(); } // see https://docs.oracle.com/javase/6/docs/platform/serialization/spec/input.html private void readObject(final ObjectInputStream stream) throws InvalidObjectException { throw new InvalidObjectException("Proxy required"); } private class ByteBufBsonDocumentEntrySet extends AbstractSet> { @Override public Iterator> iterator() { return new Iterator>() { private final ByteBuf duplicatedByteBuf = byteBuf.duplicate(); private final BsonBinaryReader bsonReader; { bsonReader = new BsonBinaryReader(new ByteBufferBsonInput(duplicatedByteBuf)); bsonReader.readStartDocument(); bsonReader.readBsonType(); } @Override public boolean hasNext() { return bsonReader.getCurrentBsonType() != BsonType.END_OF_DOCUMENT; } @Override public Entry next() { if (!hasNext()) { throw new NoSuchElementException(); } String key = bsonReader.readName(); BsonValue value = readBsonValue(duplicatedByteBuf, bsonReader); bsonReader.readBsonType(); return new AbstractMap.SimpleEntry<>(key, value); } }; } @Override public boolean isEmpty() { return !iterator().hasNext(); } @Override public int size() { return ByteBufBsonDocument.this.size(); } } private class ByteBufBsonDocumentKeySet extends AbstractSet { @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") private final Set> entrySet = new ByteBufBsonDocumentEntrySet(); @Override public Iterator iterator() { final Iterator> entrySetIterator = entrySet.iterator(); return new Iterator() { @Override public boolean hasNext() { return entrySetIterator.hasNext(); } @Override public String next() { return entrySetIterator.next().getKey(); } }; } @Override public boolean isEmpty() { return entrySet.isEmpty(); } @Override public int size() { return entrySet.size(); } } private class ByteBufBsonDocumentValuesCollection extends AbstractCollection { @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") private final Set> entrySet = new ByteBufBsonDocumentEntrySet(); @Override public Iterator iterator() { final Iterator> entrySetIterator = entrySet.iterator(); return new Iterator() { @Override public boolean hasNext() { return entrySetIterator.hasNext(); } @Override public BsonValue next() { return entrySetIterator.next().getValue(); } }; } @Override public boolean isEmpty() { return entrySet.isEmpty(); } @Override public int size() { return entrySet.size(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy