// Copyright 2011 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.enterprise.connector.traversal; import com.google.enterprise.connector.spi.Document; import com.google.enterprise.connector.spi.DocumentAcceptor; import com.google.enterprise.connector.spi.DocumentAcceptorException; import com.google.enterprise.connector.spi.Lister; import com.google.enterprise.connector.spi.RepositoryException; import com.google.enterprise.connector.spi.SpiConstants; import com.google.enterprise.connector.spi.Value; import com.google.enterprise.connector.test.ConnectorTestUtils; import java.util.Timer; import java.util.TimerTask; import java.util.logging.Level; import java.util.logging.Logger; /** * Mock implementation for {@link Lister}. */ public class MockLister implements Lister { private static final Logger LOGGER = Logger.getLogger(MockLister.class.getName()); protected DocumentAcceptor documentAcceptor; protected Timer timer; protected final long delayMillis; protected final long maxDocs; protected long documentCount; protected boolean isShutdown; /** * Creates a Lister that feeds a new document with the given delay between * documents until maxDocs is reached or shutdown is called. If delayMillis * is non-zero, documents are fed in a separate thread. */ public MockLister(long maxDocs, long delayMillis) { this.maxDocs = maxDocs; this.delayMillis = delayMillis; isShutdown = false; documentCount = 0; } @Override public void setDocumentAcceptor(DocumentAcceptor documentAcceptor) throws RepositoryException { this.documentAcceptor = documentAcceptor; } /** * {@inheritDoc} * If delayMillis is non-zero, feed documents in a separate thread, * otherwise feed them from here. */ @Override public void start() throws RepositoryException { isShutdown = false; documentCount = 0; // If no interdoc delay, run in this thread for simplicity. if (delayMillis == 0L) { try { while (documentCount < maxDocs) { nextDocument(); } } catch (DocumentAcceptorException e) { LOGGER.log(Level.WARNING, "Caught DocumentAcceptorException", e); } } else { synchronized (this) { // Create a timer with a named thread. timer = new Timer("MockLister"); timer.schedule(new ListerTask(), delayMillis, delayMillis); } } } /** * Shuts down the {@link Lister}. It should cease sending documents to the * {@link DocumentAcceptor}. */ @Override public void shutdown() throws RepositoryException { LOGGER.config("Shutdown Lister"); isShutdown = true; synchronized(this) { if (timer != null) { timer.cancel(); timer = null; } } try { documentAcceptor.flush(); } catch (DocumentAcceptorException e) { LOGGER.log(Level.WARNING, "Caught DocumentAcceptorException", e); } catch (RepositoryException e) { LOGGER.log(Level.WARNING, "Caught RepositoryException", e); } LOGGER.finer("Fed " + documentCount + " documents."); } /** Send the document to the documentAcceptor. */ protected void feedDocument(Document doc) throws DocumentAcceptorException, RepositoryException { try { LOGGER.finer("Feeding document " + Value.getSingleValueString(doc, SpiConstants.PROPNAME_DOCID)); documentAcceptor.take(doc); } catch (DocumentAcceptorException e) { LOGGER.log(Level.WARNING, "Caught DocumentAcceptorException", e); documentAcceptor.cancel(); throw e; } catch (RepositoryException e) { LOGGER.log(Level.WARNING, "Caught RepositoryException", e); throw e; } } /** Return a new document. */ protected synchronized Document newDocument() { String id = Long.toString(documentCount++); return ConnectorTestUtils.createSimpleDocument(id); } /** Return the number of documents fed. */ protected synchronized long getDocumentCount() { return documentCount; } /** Send the next document to the documentAcceptor. */ protected synchronized void nextDocument() throws DocumentAcceptorException, RepositoryException { if (!isShutdown) { feedDocument(newDocument()); if (documentCount >= maxDocs) { shutdown(); } } } protected class ListerTask extends TimerTask { @Override public void run() { try { nextDocument(); } catch (DocumentAcceptorException e) { LOGGER.log(Level.WARNING, "Uncaught DocumentAcceptorException", e); } catch (RepositoryException e) { LOGGER.log(Level.WARNING, "Uncaught RepositoryException", e); } } } }