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

org.springframework.data.couchbase.core.mapping.CouchbaseDocument Maven / Gradle / Ivy

/*
 * Copyright 2012-2015 the original author or authors
 *
 * 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 org.springframework.data.couchbase.core.mapping;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.data.mapping.model.SimpleTypeHolder;

/**
 * A {@link CouchbaseDocument} is an abstract representation of a document stored inside Couchbase Server.
 * 

*

It acts like a {@link HashMap}, but only allows those types to be written that are supported by the underlying * storage format, which is currently JSON. Note that JSON conversion is not happening here, but performed at a * different stage based on the payload stored in the {@link CouchbaseDocument}.

*

*

In addition to the actual content, meta data is also stored. This especially refers to the document ID and its * expiration time. Note that this information is not mandatory, since documents can be nested and therefore only the * topmost document most likely has an ID.

* * @author Michael Nitschinger */ public class CouchbaseDocument implements CouchbaseStorable { /** * Defnes the default expiration time for the document. */ public static final int DEFAULT_EXPIRATION_TIME = 0; /** * Contains the actual data to be stored. */ private HashMap payload; /** * Represents the document ID used to identify the document in the bucket. */ private String id; /** * Contains the expiration time of the document. */ private int expiration; /** * Holds types considered simple and allowed to be stored. */ private SimpleTypeHolder simpleTypeHolder; /** * Creates a completely empty {@link CouchbaseDocument}. */ public CouchbaseDocument() { this(null); } /** * Creates a empty {@link CouchbaseDocument}, and set the ID immediately. * * @param id the document ID. */ public CouchbaseDocument(final String id) { this(id, DEFAULT_EXPIRATION_TIME); } /** * Creates a empty {@link CouchbaseDocument} with ID and expiration time. * * @param id the document ID. * @param expiration the expiration time of the document. */ public CouchbaseDocument(final String id, final int expiration) { this.id = id; this.expiration = expiration; payload = new HashMap(); Set> additionalTypes = new HashSet>(); additionalTypes.add(CouchbaseDocument.class); additionalTypes.add(CouchbaseList.class); simpleTypeHolder = new SimpleTypeHolder(additionalTypes, true); } /** * Store a value with the given key for later retreival. * * @param key the key of the attribute. * @param value the actual content to be stored. * @return the {@link CouchbaseDocument} for chaining. */ public final CouchbaseDocument put(final String key, final Object value) { verifyValueType(value); payload.put(key, value); return this; } /** * Potentially get a value from the payload with the given key. * * @param key the key of the attribute. * @return the value to which the specified key is mapped, or * null if does not contain a mapping for the key. */ public final Object get(final String key) { return payload.get(key); } /** * Returns the current payload, including all recursive elements. *

* It either returns the raw results or makes sure that the recusrive elements * are also exported properly. * * @return */ public final HashMap export() { HashMap toExport = new HashMap(payload); for (Map.Entry entry : payload.entrySet()) { if (entry.getValue() instanceof CouchbaseDocument) { toExport.put(entry.getKey(), ((CouchbaseDocument) entry.getValue()).export()); } else if (entry.getValue() instanceof CouchbaseList) { toExport.put(entry.getKey(), ((CouchbaseList) entry.getValue()).export()); } } return toExport; } /** * Returns true if it contains a payload for the specified key. * * @param key the key of the attribute. * @return true if it contains a payload for the specified key. */ public final boolean containsKey(final String key) { return payload.containsKey(key); } /** * Returns true if it contains the given value. * * @param value the value to check for. * @return true if it contains the specified value. */ public final boolean containsValue(final Object value) { return payload.containsValue(value); } /** * Returns the size of the attributes in this document (not nested). * * @return the size of the attributes in this document (not nested). */ public final int size() { return size(false); } /** * Retruns the size of the attributes in this and recursive documents. * * @param recursive wheter nested attributes should be taken into account. * @return the size of the attributes in this and recursive documents. */ public final int size(final boolean recursive) { int thisSize = payload.size(); if (!recursive || thisSize == 0) { return thisSize; } int totalSize = thisSize; for (Object value : payload.values()) { if (value instanceof CouchbaseDocument) { totalSize += ((CouchbaseDocument) value).size(true); } else if (value instanceof CouchbaseList) { totalSize += ((CouchbaseList) value).size(true); } } return totalSize; } /** * Returns the underlying payload. *

*

Note that unlike {@link #export()}, the nested objects are not converted, so the "raw" map is returned.

* * @return the underlying payload. */ public HashMap getPayload() { return payload; } /** * Returns the expiration time of the document. *

* If the expiration time is 0, then the document will be persisted until * deleted manually ("forever"). * * @return the expiration time of the document. */ public int getExpiration() { return expiration; } /** * Set the expiration time of the document. *

* If the expiration time is 0, then the document will be persisted until * deleted manually ("forever"). *

* Expiration should be expressed as seconds if <= 30 days (30 x 24 x 60 x 60 seconds), * or as an expiry date (UTC, UNIX time ie. seconds form the Epoch) if > 30 days. * * @param expiration * @return the {@link CouchbaseDocument} for chaining. */ public CouchbaseDocument setExpiration(int expiration) { this.expiration = expiration; return this; } /** * Returns the ID of the document. * * @return the ID of the document. */ public String getId() { return id; } /** * Sets the unique ID of the document per bucket. * * @param id the ID of the document. * @return the {@link CouchbaseDocument} for chaining. */ public CouchbaseDocument setId(String id) { this.id = id; return this; } /** * Verifies that only values of a certain and supported type * can be stored. *

*

If this is not the case, a {@link IllegalArgumentException} is * thrown.

* * @param value the object to verify its type. */ private void verifyValueType(final Object value) { if (value == null) { return; } final Class clazz = value.getClass(); if (simpleTypeHolder.isSimpleType(clazz)) { return; } throw new IllegalArgumentException("Attribute of type " + clazz.getCanonicalName() + " cannot be stored and must be converted."); } /** * A string representation of expiration, id and payload. * * @return the string representation of the object. */ @Override public String toString() { return "CouchbaseDocument{" + "id=" + id + ", exp=" + expiration + ", payload=" + payload + '}'; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy