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

com.couchbase.lite.Attachment Maven / Gradle / Ivy

/**
 * Original iOS version by  Jens Alfke
 * Ported to Android by Marty Schoch
 * 

* Copyright (c) 2012 Couchbase, Inc. All rights reserved. *

* 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.couchbase.lite; import com.couchbase.lite.internal.AttachmentInternal; import com.couchbase.lite.internal.InterfaceAudience; import com.couchbase.lite.support.security.SymmetricKeyException; import com.couchbase.lite.util.Log; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * A Couchbase Lite Document Attachment. */ public final class Attachment { /** * The owning document revision. */ private Revision revision = null; /** * The filename. */ private String name = null; /** * The CouchbaseLite metadata about the attachment, that lives in the document. */ private Map metadata = null; /** * The body data. */ private InputStream body = null; /** * Constructor */ @InterfaceAudience.Private public Attachment(InputStream contentStream, String contentType) { this.body = contentStream; metadata = new HashMap(); metadata.put("content_type", contentType); metadata.put("follows", true); } /** * Constructor */ @InterfaceAudience.Private protected Attachment(Revision revision, String name, Map metadata) { this.revision = revision; this.name = name; this.metadata = metadata; } private AttachmentInternal internalAttachment() throws CouchbaseLiteException { return revision.getDatabase().getAttachment(metadata, name); } /** * Get the owning document revision. */ @InterfaceAudience.Public public Revision getRevision() { return revision; } /** * Get the owning document. */ @InterfaceAudience.Public public Document getDocument() { return revision != null ? revision.getDocument() : null; } /** * Get the filename. */ @InterfaceAudience.Public public String getName() { return name; } /** * Get the MIME type of the contents. */ @InterfaceAudience.Public public String getContentType() { return (String) metadata.get("content_type"); } /** * Get the input stream of the content (aka 'body') data. * @throws CouchbaseLiteException */ @InterfaceAudience.Public public InputStream getContent() throws CouchbaseLiteException { if (body != null) { return body; } else { return new ByteArrayInputStream(internalAttachment().getContent()); } } /** * Get the URL of the file containing the contents. * This property is somewhat deprecated and is made available only for use with platform APIs that * require file paths/URLs, e.g. some media playback APIs. Whenever possible, use the `getContent()` * method to get the input stream of the content instead. * The file must be treated as read-only! DO NOT MODIFY OR DELETE IT. * If the database is encrypted, attachment files are also encrypted and not directly readable, * so this property will return null. */ @InterfaceAudience.Public public URL getContentURL() { try { return internalAttachment().getContentURL(); } catch (MalformedURLException e) { Log.w(Database.TAG, e.toString()); } catch (CouchbaseLiteException e) { Log.w(Database.TAG, e.toString()); } return null; } /** * Get the length in bytes of the contents. */ @InterfaceAudience.Public public long getLength() { Number length = (Number) metadata.get("length"); if (length != null) { return length.longValue(); } else { return 0; } } /** * The CouchbaseLite metadata about the attachment, that lives in the document. */ @InterfaceAudience.Public public Map getMetadata() { return Collections.unmodifiableMap(metadata); } @InterfaceAudience.Private protected void setName(String name) { this.name = name; } @InterfaceAudience.Private protected void setRevision(Revision revision) { this.revision = revision; } @InterfaceAudience.Private protected InputStream getBodyIfNew() { return body; } /** * Goes through an _attachments dictionary and replaces any values that are Attachment objects * with proper JSON metadata dicts. It registers the attachment bodies with the blob store and sets * the metadata 'getDigest' and 'follows' properties accordingly. */ @InterfaceAudience.Private protected static Map installAttachmentBodies(Map attachments, Database database) throws CouchbaseLiteException { Map updatedAttachments = new HashMap(); for (String name : attachments.keySet()) { Object value = attachments.get(name); if (value instanceof Attachment) { Attachment attachment = (Attachment) value; Map metadataMutable = new HashMap(); metadataMutable.putAll(attachment.getMetadata()); InputStream body = attachment.getBodyIfNew(); if (body != null) { // Copy attachment body into the database's blob store: BlobStoreWriter writer; try { writer = blobStoreWriterForBody(body, database); } catch (Exception e) { throw new CouchbaseLiteException(e.getMessage(), Status.ATTACHMENT_ERROR); } metadataMutable.put("length", writer.getLength()); metadataMutable.put("digest", writer.mD5DigestString()); metadataMutable.put("follows", true); database.rememberAttachmentWriter(writer); } updatedAttachments.put(name, metadataMutable); } else if (value instanceof AttachmentInternal) { throw new IllegalArgumentException("AttachmentInternal objects not expected here. Could indicate a bug"); } else if (value != null) { updatedAttachments.put(name, value); } } return updatedAttachments; } @InterfaceAudience.Private protected static BlobStoreWriter blobStoreWriterForBody(InputStream body, Database database) throws IOException, SymmetricKeyException { BlobStoreWriter writer = database.getAttachmentWriter(); try { writer.appendInputStream(body); writer.finish(); } catch (IOException e) { writer.cancel(); throw e; } catch (SymmetricKeyException e) { writer.cancel(); throw e; } return writer; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy