/**
 * Part of the CCNx Java Library.
 *
 * Copyright (C) 2010 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.search;

import java.io.IOException;
import java.util.Set;

import org.ccnx.ccn.CCNHandle;
import org.ccnx.ccn.config.SystemConfiguration;
import org.ccnx.ccn.profiles.VersioningProfile;
import org.ccnx.ccn.protocol.ContentName;
import org.ccnx.ccn.protocol.ContentObject;

/**
 * Like Pathfinder, this subclass searches for content with a specific postfix
 * along the path from a starting point to a stopping point.
 * We can search for matching content that is either closest or furthest from the starting point. 
 * 
 * When the closest (or furthest) matching content is found,
 * LatestVersionPathfinder retrieves the latest version of that content.
 * If the latest version is not GONE (or if goneOK is True), the latest version is returned.
 * Otherwise, we update the starting point or stopping point (depending on _closestOnPath)
 * and start a new search if the new range is non empty.
 *
 */

public class LatestVersionPathfinder extends Pathfinder {

	public LatestVersionPathfinder(ContentName startingPoint, ContentName stoppingPoint, ContentName desiredPostfix, 
			  boolean closestOnPath, boolean goneOK,
			  int timeout, 
			  Set<ContentName> searchedPathCache,
			  CCNHandle handle) throws IOException {
		super(startingPoint, stoppingPoint, desiredPostfix, closestOnPath, goneOK, timeout, searchedPathCache, handle);
	}

	@Override
	public synchronized SearchResults waitForResults() {
		boolean searchSpaceEmpty = false;
		while (! searchSpaceEmpty) {
			SearchResults sr = super.waitForResults();
			ContentObject co = sr.getResult(); 
			if (null != co) {
				try {
					// get the latest version
					ContentObject coLV = 
						VersioningProfile.getFirstBlockOfLatestVersion(co.name(), null, null, 
								SystemConfiguration.getDefaultTimeout(), _handle.defaultVerifier(), _handle);
					if (null != coLV) co = coLV;
					if (goneOK() || (! co.isGone())) {
						sr.setResult(co);
						return sr;
					}
					// the latest version of the ContentObject found is GONE, and goneOK = false
					// so we cancel outstanding interests (if any),
					// we update the starting point or stopping point (depending on _closestOnPath)
					// and start a new search if the new range is non empty
					if (! done()) stopSearch();
					if (_closestOnPath) {
						ContentName icn = sr.getInterestName();
						icn = icn.cut(icn.count() - _postfix.count());
						System.out.println("Stopping point " + _stoppingPoint);
						System.out.println("interest: " + icn);
						if (icn.count() > _stoppingPoint.count()) {
							_startingPoint = icn.cut(icn.count() - 1);
							System.out.println("new starting point: " + _startingPoint);
						}
						else searchSpaceEmpty = true;
					}
					else {
						ContentName icn = sr.getInterestName();
						icn = icn.cut(icn.count() - _postfix.count());
						if (icn.count() < _startingPoint.count()) {
							_stoppingPoint = _startingPoint.cut(icn.count() + 1);												
						}
						else searchSpaceEmpty = true;
					}
					if (! searchSpaceEmpty) {
						startSearch();
					}
				} catch (IOException ioe) {
					ioe.printStackTrace();
					return new SearchResults(null, null);
				}
			}
			else return sr;
		}
		return new SearchResults(null, null);
	}
	
}

@@ -1081,16 +1081,22 @@
  * Like 
+Object
 Pathfind
@@ -1126,24 +1126,26 @@
 hes for 
+a 
 content 
 with a s
@@ -1136,16 +1136,23 @@
 content 
+object 
 with a s
@@ -1382,16 +1382,23 @@
 content 
+object 
 is found
@@ -1463,22 +1463,21 @@
 of that 
-conten
+objec
 t.%0A * If
@@ -1720,16 +1720,16 @@
  *%0A */%0A%0A
-
 public c
@@ -1765,16 +1765,22 @@
 extends 
+Object
 Pathfind

Make LatestVersionPathfinder a subclass of ObjectPathfinder.