/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.jackrabbit.core.query.lucene; import org.apache.jackrabbit.core.query.lucene.directory.IndexInputStream; import org.apache.lucene.store.Directory; import org.slf4j.LoggerFactory; import org.slf4j.Logger; import java.io.IOException; import java.io.InputStream; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Set; import java.util.HashSet; /** * <code>IndexingQueueStore</code> implements a store that keeps the uuids of * nodes that are pending in the indexing queue. Until Jackrabbit 1.4 this store * was also persisted to disk. Starting with 1.5 the pending * nodes are marked directly in the index with a special field. * See {@link FieldNames#REINDEXING_REQUIRED}. */ class IndexingQueueStore { /** * The logger instance for this class. */ private static final Logger log = LoggerFactory.getLogger(IndexingQueueStore.class); /** * Encoding of the indexing queue store. */ private static final String ENCODING = "UTF-8"; /** * Operation identifier for an added node. */ private static final String ADD = "ADD"; /** * Operation identifier for an removed node. */ private static final String REMOVE = "REMOVE"; /** * Name of the file that contains the indexing queue log. */ private static final String INDEXING_QUEUE_FILE = "indexing_queue.log"; /** * The UUID Strings of the pending documents. */ private final Set<String> pending = new HashSet<String>(); /** * The directory from where to read pending document UUIDs. */ private final Directory dir; /** * Creates a new <code>IndexingQueueStore</code> using the given directory. * * @param directory the directory to use. * @throws IOException if an error ocurrs while reading pending UUIDs. */ IndexingQueueStore(Directory directory) throws IOException { this.dir = directory; readStore(); } /** * @return the UUIDs of the pending text extraction jobs. */ public String[] getPending() { return pending.toArray(new String[pending.size()]); } /** * Adds a <code>uuid</code> to the store. * * @param uuid the uuid to add. */ public void addUUID(String uuid) { pending.add(uuid); } /** * Removes a <code>uuid</code> from the store. * * @param uuid the uuid to add. */ public void removeUUID(String uuid) { pending.remove(uuid); } /** * Closes this queue store. */ public void close() { if (pending.isEmpty()) { try { if (dir.fileExists(INDEXING_QUEUE_FILE)) { dir.deleteFile(INDEXING_QUEUE_FILE); } } catch (IOException e) { log.warn("unable to delete " + INDEXING_QUEUE_FILE); } } } //----------------------------< internal >---------------------------------- /** * Reads all pending UUIDs from the file and puts them into {@link * #pending}. * * @throws IOException if an error occurs while reading. */ private void readStore() throws IOException { if (dir.fileExists(INDEXING_QUEUE_FILE)) { InputStream in = new IndexInputStream(dir.openInput(INDEXING_QUEUE_FILE)); BufferedReader reader = new BufferedReader( new InputStreamReader(in, ENCODING)); try { String line; while ((line = reader.readLine()) != null) { int idx = line.indexOf(' '); if (idx == -1) { // invalid line log.warn("invalid line in {}: {}", INDEXING_QUEUE_FILE, line); } else { String cmd = line.substring(0, idx); String uuid = line.substring(idx + 1, line.length()); if (ADD.equals(cmd)) { pending.add(uuid); } else if (REMOVE.equals(cmd)) { pending.remove(uuid); } else { // invalid line log.warn("invalid line in {}: {}", INDEXING_QUEUE_FILE, line); } } } } finally { in.close(); } } } }