/* * Part of the CCNx Java Library. * * Copyright (C) 2008, 2009 Palo Alto Research Center, Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. You should have received * a copy of the GNU Lesser General Public License along with this library; * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, * Fifth Floor, Boston, MA 02110-1301 USA. */ package org.ccnx.ccn.io.content; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.ccnx.ccn.CCNHandle; import org.ccnx.ccn.impl.CCNFlowControl; import org.ccnx.ccn.impl.CCNFlowControl.SaveType; import org.ccnx.ccn.impl.support.DataUtils; import org.ccnx.ccn.io.ErrorStateException; import org.ccnx.ccn.protocol.ContentName; import org.ccnx.ccn.protocol.ContentObject; import org.ccnx.ccn.protocol.KeyLocator; import org.ccnx.ccn.protocol.PublisherPublicKeyDigest; /** * A CCNNetworkObject wrapper around Java Strings, which uses Java serialization * to write those strings. Allows reading and writing of * versioned strings to CCN, and background updating of same. Very useful class * for writing simple tests and applications, but requires both communicating * partners to speak Java Serialization. See CCNStringObject for a more generally * useful string object that serializes the string in pure UTF-8, making * something that can be more easily read from other languages. */ public class CCNStringObject extends CCNNetworkObject<String> { /** * Write constructor. Use this * constructor with null data to avoid an initial blocking call to * update in the constructor, for example if you are going to call updateInBackground. * @param name * @param data Initial value for data. Can be null; but needs to be set with * setData before save is called (or passed as an argument to save). * @param saveType where this object saves its data to; options include * RAW and REPOSITORY * @param handle * @throws IOException */ public CCNStringObject(ContentName name, String data, SaveType saveType, CCNHandle handle) throws IOException { super(String.class, false, name, data, saveType, handle); } /** * Write constructor. * @param name * @param data * @param saveType where this object saves its data to; options include * RAW and REPOSITORY * @param publisher * @param locator * @param handle * @throws IOException */ public CCNStringObject(ContentName name, String data, SaveType saveType, PublisherPublicKeyDigest publisher, KeyLocator locator, CCNHandle handle) throws IOException { super(String.class, false, name, data, saveType, publisher, locator, handle); } /** * Read constructor. * @param name * @param handle * @throws ContentDecodingException * @throws IOException */ public CCNStringObject(ContentName name, CCNHandle handle) throws ContentDecodingException, IOException { super(String.class, false, name, (PublisherPublicKeyDigest)null, handle); } /** * Read constructor. * @param name * @param publisher * @param handle * @throws ContentDecodingException * @throws IOException */ public CCNStringObject(ContentName name, PublisherPublicKeyDigest publisher, CCNHandle handle) throws ContentDecodingException, IOException { super(String.class, false, name, publisher, handle); } /** * Read constructor. * @param firstBlock * @param handle * @throws ContentDecodingException * @throws IOException */ public CCNStringObject(ContentObject firstBlock, CCNHandle handle) throws ContentDecodingException, IOException { super(String.class, false, firstBlock, handle); } /** * Internal constructor used by low-level network operations. Don't use unless you know what * you are doing. * @param name name under which to save data * @param data data to save when save() is called; or null if the next call will be updateInBackground() * @param publisher key (identity) to use to sign the content (null for default) * @param locator key locator to use to tell people where to find our key, should match publisher, (null for default for key) * @param flowControl flow controller to use for network output * @throws IOException */ public CCNStringObject(ContentName name, String data, PublisherPublicKeyDigest publisher, KeyLocator locator, CCNFlowControl flowControl) throws IOException { super(String.class, false, name, data, publisher, locator, flowControl); } /** * Internal constructor used by low-level network operations. Don't use unless you know what * you are doing. * @param name name under which to save data * @param data data to save when save() is called; or null if the next call will be updateInBackground() * @param publisher key (identity) to use to sign the content (null for default) * @param locator key locator to use to tell people where to find our key, should match publisher, (null for default for key) * @param flowControl flow controller to use for network output * @throws IOException */ public CCNStringObject(ContentName name, PublisherPublicKeyDigest publisher, CCNFlowControl flowControl) throws ContentDecodingException, IOException { super(String.class, false, name, publisher, flowControl); } /** * Internal constructor used by low-level network operations. Don't use unless you know what * you are doing. * @param name name under which to save data * @param data data to save when save() is called; or null if the next call will be updateInBackground() * @param publisher key (identity) to use to sign the content (null for default) * @param locator key locator to use to tell people where to find our key, should match publisher, (null for default for key) * @param flowControl flow controller to use for network output * @throws IOException */ public CCNStringObject(ContentObject firstSegment, CCNFlowControl flowControl) throws ContentDecodingException, IOException { super(String.class, false, firstSegment, flowControl); } @Override protected String readObjectImpl(InputStream input) throws ContentDecodingException, IOException { // assume we read until we have all the bytes, then decode. byte [] contentBytes = DataUtils.getBytesFromStream(input); // do something if contentBytes is null? return DataUtils.getUTF8StringFromBytes(contentBytes); } @Override protected void writeObjectImpl(OutputStream output) throws ContentEncodingException, IOException { if (null == data()) throw new ContentNotReadyException("No content available to save for object " + getBaseName()); byte [] stringData = DataUtils.getBytesFromUTF8String(data()); output.write(stringData); } public String string() throws ContentNotReadyException, ContentGoneException, ErrorStateException { return data(); } }