Package org.apache.jackrabbit.core.query.lucene

Source Code of org.apache.jackrabbit.core.query.lucene.IndexingQueueStore

/*
* 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.fs.FileSystem;
import org.apache.jackrabbit.core.fs.FileSystemException;
import org.apache.jackrabbit.core.fs.RandomAccessOutputStream;
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.io.OutputStreamWriter;
import java.io.Writer;
import java.io.BufferedOutputStream;
import java.util.Set;
import java.util.HashSet;

/**
* <code>IndexingQueueStore</code> implements the persistent store to keep
* track of pending document in an indexing queue.
*/
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";

    /**
     * The UUID Strings of the pending documents.
     */
    private final Set pending = new HashSet();

    /**
     * The file system where to write the pending document UUIDs.
     */
    private final FileSystem fs;

    /**
     * The name of the file for the pending document UUIDs.
     */
    private final String fileName;

    /**
     * Non-null if we are currently writing to the file.
     */
    private Writer out;

    /**
     * Creates a new <code>IndexingQueueStore</code> using the given file
     * system.
     *
     * @param fs       the file system to use.
     * @param fileName the name of the file where to write the pending UUIDs
     *                 to.
     * @throws FileSystemException if an error ocurrs while reading pending
     *                             UUIDs.
     */
    IndexingQueueStore(FileSystem fs, String fileName) throws FileSystemException {
        this.fs = fs;
        this.fileName = fileName;
        readStore();
    }

    /**
     * @return the UUIDs of the pending text extraction jobs.
     */
    public String[] getPending() {
        return (String[]) pending.toArray(new String[pending.size()]);
    }

    /**
     * Adds a <code>uuid</code> to the store.
     *
     * @param uuid the uuid to add.
     * @throws IOException if an error occurs while writing.
     */
    public void addUUID(String uuid) throws IOException {
        writeEntry(ADD, uuid, getLog());
        pending.add(uuid);
    }

    /**
     * Removes a <code>uuid</code> from the store.
     *
     * @param uuid the uuid to add.
     * @throws IOException if an error occurs while writing.
     */
    public void removeUUID(String uuid) throws IOException {
        writeEntry(REMOVE, uuid, getLog());
        pending.remove(uuid);
    }

    /**
     * Commits the pending changes to the file.
     *
     * @throws IOException if an error occurs while writing.
     */
    public void commit() throws IOException {
        if (out != null) {
            out.flush();
            if (pending.size() == 0) {
                out.close();
                out = null;
                // truncate log
                try {
                    fs.getOutputStream(fileName).close();
                } catch (FileSystemException e) {
                    // ignore
                }
            }
        }
    }

    /**
     * Flushes and closes this queue store.
     *
     * @throws IOException if an error occurs while writing.
     */
    public void close() throws IOException {
        commit();
        if (out != null) {
            out.close();
        }
    }

    //----------------------------< internal >----------------------------------

    /**
     * Reads all pending UUIDs from the file and puts them into {@link
     * #pending}.
     *
     * @throws FileSystemException if an error occurs while reading.
     */
    private void readStore() throws FileSystemException {
        if (fs.exists(fileName)) {
            try {
                InputStream in = fs.getInputStream(fileName);
                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 {}: {}", fileName, 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 {}: {}", fileName, line);
                            }
                        }
                    }
                } finally {
                    in.close();
                }
            } catch (IOException e) {
                throw new FileSystemException(e.getMessage(), e);
            }
        }
    }

    /**
     * Writes an entry to the log file.
     *
     * @param op     the operation. Either {@link #ADD} or {@link #REMOVE}.
     * @param uuid   the uuid of the added or removed node.
     * @param writer the writer where the entry is written to.
     * @throws IOException if an error occurs when writing the entry.
     */
    private static void writeEntry(String op, String uuid, Writer writer) throws IOException {
        StringBuffer buf = new StringBuffer(op);
        buf.append(' ').append(uuid).append('\n');
        writer.write(buf.toString());
    }

    /**
     * Returns the writer to the log file.
     *
     * @return the writer to the log file.
     * @throws IOException if an error occurs while opening the log file.
     */
    private Writer getLog() throws IOException {
        if (out == null) {
            // open file
            try {
                long len = 0;
                if (fs.exists(fileName)) {
                    len = fs.length(fileName);
                }
                RandomAccessOutputStream raos
                        = fs.getRandomAccessOutputStream(fileName);
                raos.seek(len);
                // use buffering
                out = new OutputStreamWriter(
                        new BufferedOutputStream(raos, 1024),
                        ENCODING);
            } catch (FileSystemException e) {
                if (out != null) {
                    out.close();
                    out = null;
                }
                IOException ex = new IOException(e.getMessage());
                ex.initCause(e);
                throw ex;
            }
        }
        return out;
    }
}
TOP

Related Classes of org.apache.jackrabbit.core.query.lucene.IndexingQueueStore

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.