taitelman
taitelman

Reputation: 700

Cloudant 1.0.1 Java Client SDK missing loadAttachment() API?

in https://github.com/cloudant/java-cloudant#inline-attachment (v1.0.1) I see API to save standalone attachments. where is the reverse operation ?

In fact I noticed that Cloudant GSONize all values. What If you don't want to use GSON on your classes ? (I guess my only escape is to save the POJO as binary stream using JVM serialization and the above API).

we are getting there: so if we are talking about the standalone attachments: as answered below you can do: InputStream in = db.find(....) but then you really have to work hard to extract the attachment. And even worst: you need to create a new HTTP client of your own (in my snippet assume httpclient is a defined Apache HTTP client instance).

InputStream in = db.find(....)
if (in != null)  {
    // input stream will contain a JSON string
    Object readFromJSON = readBinaryAttachment(in);
}

    private Object readBinaryAttachment(InputStream in) throws IOException {
            Object result = null;
            JSONObject json = JSONObject.parse(in);
            JSONObject attachments = (JSONObject)json.get(ATTACHMENTS_FIELD);
            if (attachments != null) {
                JSONObject attachment = (JSONObject)attachments.get(ATTACHMENT_FIELD_NAME);
                if (attachment != null  && attachment.get(CLOUDANT_ATTACHMENT_LENGTH_KEY) != null) {
                    String id = (String)json.get(CLOUDANT_ID_KEY);
                    HttpGet request = HttpUtil.createAuthenticatedGET(url+ "/"+ databaseName+ "/"+id+"/"+ATTACHMENT_FIELD_NAME, user, pass);
                    HttpResponse response  = httpclient.execute(request);
                    HttpEntity entity = response.getEntity();
                    if (entity != null) {
                        Header contentType = entity.getContentType();
                        ObjectInputStream oins = null;
                        try {
                            if (contentType.getValue().equals(BINARY_MIME_TYPE)) {
                                InputStream ins = entity.getContent();
                                oins = new ObjectInputStream(ins);
                                result = oins.readUnshared();
                            } else {
                                throw new IOException("unexpected content type:"+contentType.getValue());
                            }
                            return result;
                        } catch (ClassNotFoundException ex) {
                            throw new IOException("unexpected object in attachment"+ex.getLocalizedMessage());
                        } finally {
                            EntityUtils.consumeQuietly(entity);
                            IOUtils.closeQuietly(oins);
                        }
                    }
                } else {
                    throw new IOException("could not find attachments");
                }

            }
            return null;
        }

It just seem so long for a short operation...

Upvotes: 0

Views: 271

Answers (3)

taitelman
taitelman

Reputation: 700

you are right: db.find(response.getId() + ATTACHMENT_NAME) will do the work. thanks.

Upvotes: 0

Mario Briggs
Mario Briggs

Reputation: 56

We have not yet looked to add API's above the base Lightcouch for base couch func (we will certainly do in response to user needs... So I can open an issue for you). Take a look at attachmentStandalone() in https://github.com/cloudant/java-cloudant/blob/master/src/test/java/com/cloudant/tests/AttachmentsTest.java if it is of any help

Upvotes: 0

Kim Stebel
Kim Stebel

Reputation: 42047

On the same page under standalone attachments, it tells you how to retrieve an attachment:

InputStream in = db.find( "doc_id/foo.txt");

You can also get the attachment as Base64-encoded data like this:

Foo foo = db.find(Foo.class, "doc-id", new Params().attachments());
String attachmentData = foo.getAttachments().get("attachment.txt").getData();

Upvotes: 2

Related Questions