dk.dma.ais.sentence.CommentBlockLine.java Source code

Java tutorial

Introduction

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

import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Class representing a single comment block line The parsing is somewhat relaxed
 */
public class CommentBlockLine {

    private Map<String, String> parameterMap;
    private Integer totalLines;
    private Integer lineNumber;
    private String groupId;
    private int checksum;

    public void parse(String line) throws CommentBlockException {
        parameterMap = new HashMap<>();
        int start = -1;
        int end = -1;
        checksum = 0;
        // Find start, end, checksum and fields
        for (int i = 0; i < line.length(); i++) {
            char c = line.charAt(i);
            if (c == '*') {
                end = i;
                break;
            }
            if (start >= 0) {
                checksum ^= c;
            }
            if (c == '\\') {
                if (start < 0) {
                    start = i;
                }
            }
        }
        if (start < 0) {
            throw new CommentBlockException("No comment block found");
        }
        if (end < 0) {
            throw new CommentBlockException("Malformed comment block");
        }

        // Check checksum
        try {
            String given = line.substring(end + 1, end + 3);
            String calculated = Integer.toString(checksum, 16).toUpperCase();
            if (checksum != Integer.parseInt(given, 16)) {
                throw new CommentBlockException("Wrong checksum " + given + " calculated " + calculated);
            }
        } catch (IndexOutOfBoundsException e) {
            throw new CommentBlockException("Missing checksum in comment block");
        } catch (NumberFormatException e) {
            throw new CommentBlockException("Invalid checksum");
        }

        // Split into fields
        StringBuilder tmpStr = new StringBuilder(16);
        List<String> fields = new ArrayList<>();
        for (int i = start + 1; i < end; i++) {
            if (line.charAt(i) == ',' || line.charAt(i) == ':') {
                fields.add(tmpStr.toString());
                tmpStr.setLength(0);
            } else {
                tmpStr.append(line.charAt(i));
            }
        }
        if (start + 1 < end) {
            fields.add(tmpStr.toString());
        }

        if (fields.size() % 2 != 0) {
            throw new CommentBlockException("Malformed comment block");
        }

        for (int i = 0; i < fields.size(); i += 2) {
            String parameterCode = fields.get(i);
            String value = fields.get(i + 1);

            // Check for grouping parameter code
            int groupCharIndex;
            if ((groupCharIndex = parameterCode.indexOf('G')) >= 0) {
                try {
                    lineNumber = Integer.parseInt(parameterCode.substring(0, groupCharIndex));
                    totalLines = Integer
                            .parseInt(parameterCode.substring(groupCharIndex + 1, parameterCode.length()));
                } catch (NumberFormatException e) {
                    throw new CommentBlockException("Invalid group tag: " + parameterCode);
                }
                groupId = value;
            }
            // Check for tag block group
            if (parameterCode.equals("g")) {
                String[] tagGroupParts = StringUtils.splitPreserveAllTokens(value, '-');
                if (tagGroupParts.length != 3) {
                    throw new CommentBlockException("Invalid TAG block g parameter: " + value);
                }
                try {
                    lineNumber = Integer.parseInt(tagGroupParts[0]);
                    totalLines = Integer.parseInt(tagGroupParts[1]);
                } catch (NumberFormatException e) {
                    throw new CommentBlockException("Invalid TAG block g parameter: " + value);
                }
                groupId = tagGroupParts[2];
            }
            parameterMap.put(parameterCode, value);
        }
    }

    public Integer getTotalLines() {
        return totalLines;
    }

    public Integer getLineNumber() {
        return lineNumber;
    }

    public String getGroupId() {
        return groupId;
    }

    public Map<String, String> getParameterMap() {
        return parameterMap;
    }

}