/* * 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 ObjectPathfinder, this subclass searches for a content object 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 object is found, * LatestVersionPathfinder retrieves the latest version of that object. * 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 ObjectPathfinder { 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); } }