dk.dma.ais.transform.VdmVdoTransformer.java Source code

Java tutorial

Introduction

Here is the source code for dk.dma.ais.transform.VdmVdoTransformer.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.transform;

import dk.dma.ais.message.AisMessage;
import dk.dma.ais.packet.AisPacket;
import dk.dma.ais.sentence.Sentence;
import dk.dma.ais.sentence.SentenceException;
import net.jcip.annotations.ThreadSafe;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Transformer that changes VDM/VDO to either VDM or VDO based on a given MMSI. If talker is given the talker is also
 * changed for own messages.
 */
@ThreadSafe
public class VdmVdoTransformer implements IAisPacketTransformer {

    private static final Pattern VDM_PATTERN = Pattern.compile("!..VD(M|O)", Pattern.DOTALL);

    private final int ownMmsi;
    private final String ownTalker;

    public VdmVdoTransformer(int ownMmsi) {
        this(ownMmsi, null);
    }

    public VdmVdoTransformer(int ownMmsi, String ownTalker) {
        this.ownMmsi = ownMmsi;
        this.ownTalker = ownTalker;
    }

    @Override
    public AisPacket transform(AisPacket packet) {
        AisMessage message = packet.tryGetAisMessage();
        if (message == null) {
            return null;
        }
        boolean own = message.getUserId() == ownMmsi;

        // No need to change
        if (message.getVdm().isOwnMessage() == own) {
            return packet;
        }

        // Split lines
        List<String> lines = packet.getStringMessageLines();
        for (int i = 0; i < lines.size(); i++) {
            // Find where VDO/VDM starts and replace last character
            String line = lines.get(i);
            Matcher matcher = VDM_PATTERN.matcher(line);
            if (!matcher.find()) {
                continue;
            }
            int start = matcher.start();
            line = line.substring(0, start + 5) + (own ? 'O' : 'M') + line.substring(start + 6);

            // Maybe do talker transformation
            if (own && ownTalker != null) {
                line = line.substring(0, start + 1) + ownTalker + line.substring(start + 3);
            }

            // Calculate checksum
            int checksum;
            try {
                checksum = Sentence.getChecksum(line.substring(start));
            } catch (SentenceException e) {
                e.printStackTrace();
                return null;
            }
            String strChecksum = Sentence.getStringChecksum(checksum);

            // Find where checksum starts and replace checksum
            start = line.indexOf('*', start);
            line = line.substring(0, start + 1) + strChecksum + line.substring(start + 3);

            lines.set(i, line);
        }

        return AisPacket.from(StringUtils.join(lines, "\r\n"));
    }

}