/* * Part of the CCNx Java Library. * * Copyright (C) 2008-2012 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.profiles.nameenum; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedList; import org.ccnx.ccn.CCNHandle; import org.ccnx.ccn.impl.CCNFlowControl.SaveType; import org.ccnx.ccn.io.ErrorStateException; import org.ccnx.ccn.io.content.CCNEncodableObject; import org.ccnx.ccn.io.content.Collection; import org.ccnx.ccn.io.content.ContentDecodingException; import org.ccnx.ccn.io.content.ContentGoneException; import org.ccnx.ccn.io.content.ContentNotReadyException; import org.ccnx.ccn.io.content.Link; import org.ccnx.ccn.protocol.CCNTime; import org.ccnx.ccn.protocol.ContentName; import org.ccnx.ccn.protocol.ContentObject; import org.ccnx.ccn.protocol.KeyLocator; import org.ccnx.ccn.protocol.PublisherPublicKeyDigest; /** * NameEnumerationResponse objects are used to respond to incoming NameEnumeration interests. * * NameEnumerationResponses are generated in two ways, in direct response to an interest * where there is new information to return, and where a previous interest was not * satisfied (set the interest flag), but a later save occurs directly under the namespace. * */ public class NameEnumerationResponse { private ContentName _prefix; private ArrayList<ContentName> _names; private CCNTime _version; /** * Inner class to slightly modify the collection type used to respond to NE * requests. Eventually will move to its own message type. */ public static class NameEnumerationResponseMessage extends Collection { public static class NameEnumerationResponseMessageObject extends CCNEncodableObject<NameEnumerationResponseMessage> { public NameEnumerationResponseMessageObject(ContentName name, NameEnumerationResponseMessage data, CCNHandle handle) throws IOException { super(NameEnumerationResponseMessage.class, true, name, data, SaveType.RAW, null, null, handle); } public NameEnumerationResponseMessageObject(ContentName name, java.util.Collection<Link> contents, CCNHandle handle) throws IOException { this(name, new NameEnumerationResponseMessage(contents), handle); } public NameEnumerationResponseMessageObject(ContentName name, Link [] contents, CCNHandle handle) throws IOException { this(name, new NameEnumerationResponseMessage(contents), handle); } public NameEnumerationResponseMessageObject(ContentName name, NameEnumerationResponseMessage data, PublisherPublicKeyDigest publisher, KeyLocator keyLocator, CCNHandle handle) throws IOException { super(NameEnumerationResponseMessage.class, true, name, data, SaveType.RAW, publisher, keyLocator, handle); } public NameEnumerationResponseMessageObject(ContentName name, java.util.Collection<Link> contents, PublisherPublicKeyDigest publisher, KeyLocator keyLocator, CCNHandle handle) throws IOException { this(name, new NameEnumerationResponseMessage(contents), publisher, keyLocator, handle); } public NameEnumerationResponseMessageObject(ContentName name, Link [] contents, PublisherPublicKeyDigest publisher, KeyLocator keyLocator, CCNHandle handle) throws IOException { this(name, new NameEnumerationResponseMessage(contents), publisher, keyLocator, handle); } public NameEnumerationResponseMessageObject(ContentName name, CCNHandle handle) throws ContentDecodingException, IOException { super(NameEnumerationResponseMessage.class, true, name, (PublisherPublicKeyDigest)null, handle); setSaveType(SaveType.RAW); } public NameEnumerationResponseMessageObject(ContentName name, PublisherPublicKeyDigest publisher, CCNHandle handle) throws ContentDecodingException, IOException { super(NameEnumerationResponseMessage.class, true, name, publisher, handle); setSaveType(SaveType.RAW); } public NameEnumerationResponseMessageObject(ContentObject firstBlock, CCNHandle handle) throws ContentDecodingException, IOException { super(NameEnumerationResponseMessage.class, true, firstBlock, handle); setSaveType(SaveType.RAW); } public NameEnumerationResponseMessage responseMessage() throws ContentNotReadyException, ContentGoneException, ErrorStateException { return data(); } public LinkedList<Link> contents() throws ContentNotReadyException, ContentGoneException, ErrorStateException { if (null == data()) return null; return data().contents(); } } /* * Not used yet. */ public static final String NE_RESPONSE_MESSAGE = "NameEnumerationResponse"; public NameEnumerationResponseMessage() { super(); } public NameEnumerationResponseMessage( ArrayList<ContentName> nameContents) { super(nameContents); } public NameEnumerationResponseMessage( java.util.Collection<Link> contents) { super(contents); } public NameEnumerationResponseMessage(Link[] contents) { super(contents); } /* * When we are ready to label this message separately, un-comment this. @Override public String getElementLabel() { return COLLECTION_ELEMENT; } */ } /** * Empty NameEnumerationResponse constructor that sets the variables to null. */ public NameEnumerationResponse() { _prefix = null; _names = new ArrayList<ContentName>(0); _version = null; } /** * NameEnumerationResponse constructor that populates the object's variables. * * @param p ContentName that is the prefix for this response * @param n ArrayList<ContentName> of the names under the prefix * @param ts CCNTime is the timestamp used to create the version component * for the object when it is written out */ public NameEnumerationResponse(ContentName p, ArrayList<ContentName> n, CCNTime ts) { _prefix = p; _names = n; _version = ts; } /** * Builds a NE response from name components -- NE responses contain ContentNames that * only have a single component. Make a friendlier constructor that doesn't require * pre-making names from the components we really want to list. */ public NameEnumerationResponse(ContentName p, byte [][] names, CCNTime ts) { _prefix = p; _version = ts; _names = new ArrayList<ContentName>((null == names) ? 0 : names.length); if (null != names) { for (int i=0; i < names.length; ++i) { _names.add(new ContentName(names[i])); } } } /** * Method to set the NameEnumerationReponse prefix. Right now * forces caller to add the command prefix (e.g. CommandMarkers.COMMAND_MARKER_BASIC_ENUMERATION), * should make this cleverer (even if there are multiple NE protocols). * * @param p ContentName of the prefix for the response * @return void */ public void setPrefix(ContentName p) { _prefix = p; } /** * Method to set the names to return under the prefix. * * @param n ArrayList<ContentName> of the children for the response * @return void */ public void setNameList(ArrayList<ContentName> n) { _names = n; } /** * Add a name to the list */ public void add(ContentName name) { _names.add(name); } /** * Add a single-component name to the list. */ public void add(byte [] name) { _names.add(new ContentName(name)); } /** * Add a single-component name to the list. */ public void add(String name) { _names.add(new ContentName(name)); } /** * Method to get the prefix for the response. * * @return ContentName prefix for the response */ public ContentName getPrefix() { return _prefix; } /** * Method to get the names for the response. * * @return ArrayList<ContentName> Names to return in the response */ public ArrayList<ContentName> getNames() { return _names; } /** * Method to set the timestamp for the response version. * @param ts CCNTime for the ContentObject version * @return void */ public void setTimestamp(CCNTime ts) { _version = ts; } /** * Method to get the timestamp for the response object. * * @return CCNTime for the version component of the object */ public CCNTime getTimestamp() { return _version; } /** * Method to return a Collection object for the names in the response * * @return Collection A collection of the names (as Link objects) to return. */ public NameEnumerationResponseMessage getNamesForResponse() { return new NameEnumerationResponseMessage(_names); } /** * Method to check if the NameEnumerationResponse object has names to return. * * @return boolean True if there are names to return, false if there are no * names or the list of names is null */ public boolean hasNames() { if (_names != null && _names.size() > 0) return true; else return false; } }