org.hibernate.search.testsupport.leakdetection.FileMonitoringDirectory.java Source code

Java tutorial

Introduction

Here is the source code for org.hibernate.search.testsupport.leakdetection.FileMonitoringDirectory.java

Source

/*
 * Hibernate Search, full-text search for your domain model
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.search.testsupport.leakdetection;

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.lucene.store.DataInput;
import org.apache.lucene.store.IOContext;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.RAMDirectory;

/**
 * This Directory keeps track of opened IndexInput and IndexOutput
 * instances, making it possible to verify if any file was left open.
 *
 * @author Sanne Grinovero (C) 2012 Red Hat Inc.
 */
public class FileMonitoringDirectory extends RAMDirectory {

    private final ConcurrentMap<IndexOutput, IndexOutput> openOutputs = new ConcurrentHashMap<IndexOutput, IndexOutput>(
            10);
    private final ConcurrentMap<IndexInput, IndexInput> openInputs = new ConcurrentHashMap<IndexInput, IndexInput>(
            40);

    @Override
    public IndexOutput createOutput(String name, IOContext context) throws IOException {
        IndexOutput indexOutput = super.createOutput(name, context);
        IndexOutputDelegate tracked = new IndexOutputDelegate(indexOutput);
        openOutputs.put(tracked, tracked);
        return tracked;
    }

    @Override
    public IndexInput openInput(String name, IOContext context) throws IOException {
        IndexInput openInput = super.openInput(name, context);
        IndexInputDelegate tracked = new IndexInputDelegate(openInput);
        openInputs.put(tracked, tracked);
        return tracked;
    }

    /**
     * @return true if this Directory was closed
     */
    public boolean isClosed() {
        return isOpen == false;
    }

    /**
     * @return true if all files opened by this Directory were also closed
     */
    public boolean allFilesWereClosed() {
        return openInputs.isEmpty() && openOutputs.isEmpty();
    }

    private class IndexOutputDelegate extends IndexOutput {

        private final IndexOutput delegate;

        public IndexOutputDelegate(IndexOutput delegate) {
            super("Testing Delegate: " + delegate.toString());
            this.delegate = delegate;
        }

        @Override
        public String toString() {
            return "IndexOutputDelegate to " + delegate.toString();
        }

        @Override
        public void close() throws IOException {
            delegate.close();
            openOutputs.remove(IndexOutputDelegate.this);
        }

        // All remaining methods are generated as plain delegators,
        // except equals & hashcode :

        @Override
        public void writeByte(byte b) throws IOException {
            delegate.writeByte(b);
        }

        @Override
        public void writeBytes(byte[] b, int length) throws IOException {
            delegate.writeBytes(b, length);
        }

        @Override
        public long getFilePointer() {
            return delegate.getFilePointer();
        }

        @Override
        public void writeBytes(byte[] b, int offset, int length) throws IOException {
            delegate.writeBytes(b, offset, length);
        }

        @Override
        public void writeInt(int i) throws IOException {
            delegate.writeInt(i);
        }

        @Override
        public void writeShort(short i) throws IOException {
            delegate.writeShort(i);
        }

        @Override
        public void writeLong(long i) throws IOException {
            delegate.writeLong(i);
        }

        @Override
        public void writeString(String s) throws IOException {
            delegate.writeString(s);
        }

        @Override
        public void copyBytes(DataInput input, long numBytes) throws IOException {
            delegate.copyBytes(input, numBytes);
        }

        @Override
        public void writeStringStringMap(Map<String, String> map) throws IOException {
            delegate.writeStringStringMap(map);
        }

        @Override
        public void writeStringSet(Set<String> set) throws IOException {
            delegate.writeStringSet(set);
        }

        @Override
        public long getChecksum() throws IOException {
            return delegate.getChecksum();
        }

    }

    private class IndexInputDelegate extends IndexInput {

        private final IndexInput delegate;

        public IndexInputDelegate(IndexInput delegate) {
            super(delegate.toString());
            this.delegate = delegate;
        }

        @Override
        public void close() throws IOException {
            delegate.close();
            openInputs.remove(IndexInputDelegate.this);
        }

        @Override
        public String toString() {
            return "IndexInputDelegate to " + delegate.toString();
        }

        // All remaining methods are generated as plain delegators,
        // except equals & hashcode :

        @Override
        public byte readByte() throws IOException {
            return delegate.readByte();
        }

        @Override
        public void readBytes(byte[] b, int offset, int len) throws IOException {
            delegate.readBytes(b, offset, len);
        }

        @Override
        public void readBytes(byte[] b, int offset, int len, boolean useBuffer) throws IOException {
            delegate.readBytes(b, offset, len, useBuffer);
        }

        @Override
        public long getFilePointer() {
            return delegate.getFilePointer();
        }

        @Override
        public void seek(long pos) throws IOException {
            delegate.seek(pos);
        }

        @Override
        public long length() {
            return delegate.length();
        }

        @Override
        public short readShort() throws IOException {
            return delegate.readShort();
        }

        @Override
        public int readInt() throws IOException {
            return delegate.readInt();
        }

        @Override
        public int readVInt() throws IOException {
            return delegate.readVInt();
        }

        @Override
        public long readLong() throws IOException {
            return delegate.readLong();
        }

        @Override
        public long readVLong() throws IOException {
            return delegate.readVLong();
        }

        @Override
        public String readString() throws IOException {
            return delegate.readString();
        }

        @Override
        public Map<String, String> readStringStringMap() throws IOException {
            return delegate.readStringStringMap();
        }

        @Override
        public Set<String> readStringSet() throws IOException {
            return delegate.readStringSet();
        }

        @Override
        public IndexInput slice(String sliceDescription, long offset, long length) throws IOException {
            return delegate.slice(sliceDescription, offset, length);
        }

        @Override
        public void skipBytes(final long numBytes) throws IOException {
            delegate.skipBytes(numBytes);
        }

        @Override
        public IndexInput clone() {
            //This is needed to make sure that the cloned instance can seek independently
            IndexInput clonedDelegate = (IndexInput) delegate.clone();
            return new IndexInputDelegate(clonedDelegate);
        }

    }

}