org.globus.util.Tail.java Source code

Java tutorial

Introduction

Here is the source code for org.globus.util.Tail.java

Source

/*
 * Copyright 1999-2010 University of Chicago
 *
 * 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 org.globus.util;

import java.util.List;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Collections;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.File;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Tail implements Runnable {

    private static final int CHUNK_SIZE = 2048;

    private byte[] buffer;
    private boolean _stop = false;
    private List list = null;
    private Thread _thread;

    private Log _logger;

    public Tail() {
        buffer = new byte[CHUNK_SIZE];
        list = Collections.synchronizedList(new LinkedList());
    }

    public void setLog(Log logger) {
        _logger = logger;
    }

    public void start() {
        _thread = new Thread(this);
        _thread.start();
    }

    class FileWatcher {
        private RandomAccessFile _ras;
        private OutputStream _out;
        private long _pos;

        public FileWatcher(File file, OutputStream out, int pos) throws IOException {
            _ras = new RandomAccessFile(file, "r");
            _out = out;
            _pos = pos;
        }

        public void init() throws IOException {
            _ras.seek(_pos);
        }

        public long getDiff() throws IOException {
            return _ras.length() - _pos;
        }

        public void moveBuffer(byte[] buffer, int size) throws IOException {
            _ras.readFully(buffer, 0, size);
            _pos += size;

            if (_logger.isDebugEnabled()) {
                _logger.debug("[tail] output size: " + size);
            }

            _out.write(buffer, 0, size);
        }

        public void close() {
            try {
                _ras.close();
            } catch (Exception e) {
            }
            try {
                _out.close();
            } catch (Exception e) {
            }
        }
    }

    public void join() throws InterruptedException {
        _thread.join();
    }

    public void addFile(File file, OutputStream out, int pos) throws IOException {
        list.add(new FileWatcher(file, out, pos));
    }

    public void run() {

        _logger.debug("[tail] running...");

        long len;
        int size;

        Iterator iter = null;
        FileWatcher watcher = null;

        try {
            iter = list.iterator();
            while (iter.hasNext()) {
                watcher = (FileWatcher) iter.next();
                watcher.init();
            }

            while (!isDone()) {

                try {
                    Thread.sleep(2000);
                } catch (Exception e) {
                }

                iter = list.iterator();
                while (iter.hasNext()) {
                    watcher = (FileWatcher) iter.next();

                    len = watcher.getDiff();
                    if (len <= 0)
                        continue;

                    while (len > 0) {
                        size = (len > CHUNK_SIZE) ? CHUNK_SIZE : (int) len;
                        watcher.moveBuffer(buffer, size);
                        len -= size;
                    }
                }
            }
        } catch (IOException e) {
            _logger.debug("Unexpected error.", e);
        } finally {
            close();
        }

        _logger.debug("[tail] done.");
    }

    private boolean isDone() throws IOException {
        if (!_stop)
            return false;
        Iterator iter = null;
        FileWatcher watcher = null;

        iter = list.iterator();
        while (iter.hasNext()) {
            watcher = (FileWatcher) iter.next();
            if (watcher.getDiff() > 0)
                return false;
        }

        return true;
    }

    private void close() {
        Iterator iter = null;
        FileWatcher watcher = null;
        iter = list.iterator();
        while (iter.hasNext()) {
            watcher = (FileWatcher) iter.next();
            watcher.close();
        }
    }

    public void stop() {
        _logger.debug("[tail] stop called");
        _stop = true;
    }

}