dk.dma.ais.reader.AisReaderGroup.java Source code

Java tutorial

Introduction

Here is the source code for dk.dma.ais.reader.AisReaderGroup.java

Source

/* Copyright (c) 2011 Danish Maritime Authority.
 *
 * 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 dk.dma.ais.reader;

import static java.util.Objects.requireNonNull;

import java.util.Collections;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.util.concurrent.AbstractIdleService;
import com.google.common.util.concurrent.Service;

import dk.dma.ais.packet.AisPacket;
import dk.dma.ais.packet.AisPacketStream;

/**
 * A reader group organizes a group of readers.
 * 
 * @author Kasper Nielsen
 */
public class AisReaderGroup implements Iterable<AisReader> {

    /** The logger. */
    static final Logger LOG = LoggerFactory.getLogger(AisReaderGroup.class);

    /** A stream of all incoming packets. */
    final AisPacketStream stream = AisPacketStream.newStream();

    final ReentrantLock lock = new ReentrantLock();

    /** All readers configured for this group. */
    final ConcurrentHashMap<String, AisTcpReader> readers = new ConcurrentHashMap<>();

    /** All current subscriptions. */
    final ConcurrentHashMap<AisReader, AisPacketStream.Subscription> subscriptions = new ConcurrentHashMap<>();

    /** The name of the group. */
    final String name;

    AisReaderGroup(String name) {
        this.name = requireNonNull(name);
    }

    void add(AisTcpReader reader) {
        lock.lock();
        try {
            if (readers.containsKey(reader.getSourceId())) {
                throw new IllegalArgumentException(
                        "A reader with the specified source has already been added, id = " + reader.getSourceId());
            }
            readers.put(reader.getSourceId(), reader);
            subscriptions.put(reader, reader.stream().subscribe(new Consumer<AisPacket>() {
                public void accept(AisPacket p) {
                    stream.add(p);
                }
            }));
        } finally {
            lock.unlock();
        }
    }

    public Service asService() {
        return new AbstractIdleService() {
            @Override
            protected void shutDown() throws Exception {
                lock.lock();
                try {
                    for (AisReader r : readers.values()) {
                        LOG.info("Trying to stop reader " + r);
                        r.stopReader();
                    }
                    for (AisReader r : readers.values()) {
                        try {
                            LOG.info("Trying to join reader thread" + r);
                            r.join();
                        } catch (InterruptedException e) {
                            LOG.error("Interrupted while waiting for shutdown", e);
                        }
                    }
                } finally {
                    lock.unlock();
                }
            }

            @Override
            protected void startUp() throws Exception {
                lock.lock();
                try {
                    for (AisReader r : readers.values()) {
                        r.start();
                    }
                } finally {
                    lock.unlock();
                }
            }
        };
    }

    /** {@inheritDoc} */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public Iterator<AisReader> iterator() {
        return (Iterator) Collections.unmodifiableCollection(readers.values()).iterator();
    }

    boolean remove(String name) {
        lock.lock();
        try {
            AisReader reader = readers.get(name);
            if (reader != null) {
                subscriptions.remove(reader).cancel();
            }
            reader.stopReader();
            return reader != null;
        } finally {
            lock.unlock();
        }
    }

    /**
     * Returns a stream of incoming packets for all the readers this group is managing.
     * 
     * @return a stream of incoming packets for all the readers this group is managing
     */
    public AisPacketStream stream() {
        return stream.immutableStream();
    }
}