jais.messages.StaticAndVoyageRelatedData.java Source code

Java tutorial

Introduction

Here is the source code for jais.messages.StaticAndVoyageRelatedData.java

Source

/*
 * Copyright 2016 Jonathan Machen <jon.machen@gmail.com>.
 *
 * 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 jais.messages;

import jais.AISPacket;
import jais.exceptions.AISException;
import jais.messages.enums.AISMessageType;
import jais.messages.enums.EPFDFixType;
import jais.messages.enums.FieldMap;
import jais.messages.enums.ShipType;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.joda.time.DateTimeZone;
import org.joda.time.MutableDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

/**
 *
 * @author Jonathan Machen
 */
public class StaticAndVoyageRelatedData extends AISMessageBase {

    private final static Logger LOG = LogManager.getLogger(StaticAndVoyageRelatedData.class);

    public final static DateTimeFormatter ETA_FORMATTER = DateTimeFormat.forPattern("yyyy/MM/dd HH:mm");

    private int _version;
    private int _imo;
    private String _callsign;
    private String _shipname;
    private ShipType _shiptype = ShipType.OTHER_NO_INFO;
    private int _toBow;
    private int _toStern;
    private int _toPort;
    private int _toStarboard;
    private EPFDFixType _epfd;
    private int _month = 1;
    private int _day = 1;
    private int _hour;
    private int _minute;
    private float _draught;
    private String _destination;
    private boolean _dte;

    /**
     *
     * @param packets
     */
    public StaticAndVoyageRelatedData(AISPacket... packets) {
        super(packets);
    }

    /**
     *
     * @param type
     * @param packets
     */
    public StaticAndVoyageRelatedData(AISMessageType type, AISPacket... packets) {
        super(type, packets);
    }

    /**
     *
     * @return
     */
    public int getVersion() {
        return _version;
    }

    /**
     *
     * @return
     */
    public int getImo() {
        return _imo;
    }

    /**
     *
     * @return
     */
    public String getCallsign() {
        return _callsign;
    }

    /**
     *
     * @return
     */
    public String getShipname() {
        return _shipname;
    }

    /**
     *
     * @return
     */
    public ShipType getShiptype() {
        return _shiptype;
    }

    /**
     *
     * @return
     */
    public int getToBow() {
        return _toBow;
    }

    /**
     *
     * @return
     */
    public int getToStern() {
        return _toStern;
    }

    /**
     *
     * @return
     */
    public int getToPort() {
        return _toPort;
    }

    /**
     *
     * @return
     */
    public int getToStarboard() {
        return _toStarboard;
    }

    /**
     *
     * @return
     */
    public EPFDFixType getEpfd() {
        return _epfd;
    }

    /**
     *
     * @return
     */
    public int getMonth() {
        return _month;
    }

    /**
     *
     * @return
     */
    public int getDay() {
        return _day;
    }

    /**
     *
     * @return
     */
    public int getHour() {
        return _hour;
    }

    /**
     *
     * @return
     */
    public int getMinute() {
        return _minute;
    }

    /**
     *
     * @return
     */
    public MutableDateTime getETA() {
        StringBuilder eta = new StringBuilder();
        MutableDateTime dt = MutableDateTime.now();
        int year = dt.getYear();
        int month = dt.getMonthOfYear();

        if (_month > 0) {
            // properly formatted month
            if (_month < 10) {
                eta.append("0").append(_month);
            } else if (_month > 12) {
                eta.append("12");
                _month = 12; // use this to validate the days later
            } else {
                eta.append(_month);
            }
            eta.append("/");

            // assume next year
            if (_month < month) {
                year++;
            }

            // prepend datetime string with YYYY/
            eta.insert(0, year).insert(4, "/");

            // recreate the Calendar object based on the validated month
            dt = new MutableDateTime(year, _month, 1, 0, 0, 0, 0, DateTimeZone.UTC);

            // Get the number of days in that month
            int daysInMonth = dt.monthOfYear().getMaximumValue();

            // properly formatted day
            if (_day < 1) {
                eta.append("01");
            } else if (_day < 10) {
                eta.append("0").append(_day);
            } else if (_day >= daysInMonth) {
                eta.append(daysInMonth);
            } else {
                eta.append(_day);
            }
            eta.append(" ");

            // properly formatted hour
            if (_hour < 1) {
                eta.append("00");
            } else if (_hour < 10) {
                eta.append("0").append(_hour);
            } else if (_hour >= 24) {
                eta.append(00);
            } else {
                eta.append(_hour);
            }
            eta.append(":");

            // properly formatted minute
            if (_minute < 1 || _minute > 59) {
                eta.append("00");
            } else if (_minute < 10) {
                eta.append("0").append(_minute);
            } else {
                eta.append(_minute);
            }
        } else {
            // default to epoch if month is invalid
            eta.append("1970/01/01 00:00");
        }

        try {
            dt = MutableDateTime.parse(eta.toString(), ETA_FORMATTER);
        } catch (Exception e) {
            LOG.warn("Invalid ETA, setting to epoch");
            dt = MutableDateTime.parse("1970/01/01 00:00", ETA_FORMATTER);
        }

        return dt;
    }

    /**
     *
     * @return
     */
    public float getDraught() {
        return _draught;
    }

    /**
     *
     * @return
     */
    public String getDestination() {
        return _destination;
    }

    /**
     *
     * @return
     */
    public boolean dteReady() {
        return !_dte;
    }

    /**
     *
     * @throws AISException
     */
    @Override
    public final void decode() throws AISException {
        super.decode();

        for (StaticAndVoyageFieldMap field : StaticAndVoyageFieldMap.values()) {
            switch (field) {
            case VERSION:
                _version = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                break;
            case IMO:
                _imo = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                break;
            case CALL_SIGN:
                _callsign = AISMessageDecoder.decodeString(_bits, field.getStartBit(), field.getEndBit());
                break;
            case SHIP_NAME:
                _shipname = AISMessageDecoder.decodeString(_bits, field.getStartBit(), field.getEndBit());
                break;
            case SHIP_TYPE:
                int shipCode = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                _shiptype = ShipType.getForCode(shipCode);
                if (_shiptype == null) {
                    LOG.error("No ShipType for {}", shipCode);
                    _shiptype = ShipType.OTHER_NO_INFO;
                }
                break;
            case TO_BOW:
                _toBow = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                break;
            case TO_STERN:
                _toStern = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                break;
            case TO_PORT:
                _toPort = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                break;
            case TO_STARBOARD:
                _toStarboard = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                break;
            case EPFD:
                int epfdCode = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                _epfd = EPFDFixType.getForCode(epfdCode);
                break;
            case ETA_MONTH:
                _month = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                break;
            case ETA_DAY:
                _day = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                break;
            case ETA_HOUR:
                _hour = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                break;
            case ETA_MINUTE:
                _minute = AISMessageDecoder.decodeUnsignedInt(_bits, field.getStartBit(), field.getEndBit());
                break;
            case DRAUGHT:
                _draught = AISMessageDecoder.decodeDraught(_bits, field.getStartBit(), field.getEndBit());
                break;
            case DESTINATION:
                _destination = AISMessageDecoder.decodeString(_bits, field.getStartBit(), field.getEndBit());
                break;
            case DTE:
                if (field.getStartBit() < _bits.size()) {
                    _dte = _bits.get(field.getStartBit());
                } else {
                    LOG.debug("Reached end of message before we could retrieve DTE value!");
                }
                break;
            default:
                LOG.debug("Encountered unhandled field type of : {}", field);
            }
        }
    }

    /**
     *
     */
    private enum StaticAndVoyageFieldMap implements FieldMap {

        VERSION(38, 39), IMO(40, 69), CALL_SIGN(70, 111), SHIP_NAME(112, 231), SHIP_TYPE(232, 239), TO_BOW(240,
                248), TO_STERN(249, 257), TO_PORT(258, 263), TO_STARBOARD(264, 269), EPFD(270, 273), ETA_MONTH(274,
                        277), ETA_DAY(278, 282), ETA_HOUR(283, 287), ETA_MINUTE(288,
                                293), DRAUGHT(294, 301), DESTINATION(302, 421), DTE(422, 422), SPARE(423, 423);

        private final int _startBit;
        private final int _endBit;

        /**
         *
         * @param startBit
         * @param endBit
         */
        private StaticAndVoyageFieldMap(int startBit, int endBit) {
            _startBit = startBit;
            _endBit = endBit;
        }

        /**
         *
         * @return
         */
        @Override
        public int getStartBit() {
            return _startBit;
        }

        /**
         *
         * @return
         */
        @Override
        public int getEndBit() {
            return _endBit;
        }
    }
}