org.springframework.integration.syslog.inbound.RFC6587SyslogDeserializer.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.integration.syslog.inbound.RFC6587SyslogDeserializer.java

Source

/*
 * Copyright 2014-2019 the original author or authors.
 *
 * 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
 *
 *      https://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.springframework.integration.syslog.inbound;

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import org.springframework.core.serializer.Deserializer;
import org.springframework.integration.ip.tcp.serializer.ByteArrayLfSerializer;
import org.springframework.integration.ip.tcp.serializer.SoftEndOfStreamException;
import org.springframework.integration.syslog.RFC5424SyslogParser;
import org.springframework.util.Assert;

/**
 * RFC5424/6587 Deserializer. Implemented as a {@link Deserializer} instead of a
 * transformer because we may receive a mixture of octet counting and non-transparent
 * framing - see RFC 6587.
 *
 * @author Duncan McIntyre
 * @author Gary Russell
 * @since 4.1.1
 *
 */
public class RFC6587SyslogDeserializer implements Deserializer<Map<String, ?>> {

    private final Deserializer<byte[]> delimitedDeserializer;

    private RFC5424SyslogParser parser = new RFC5424SyslogParser();

    /**
     * Construct an instance using a {@link ByteArrayLfSerializer} for
     * non-transparent frames.
     */
    public RFC6587SyslogDeserializer() {
        this.delimitedDeserializer = new ByteArrayLfSerializer();
    }

    /**
     * Construct an instance using the specified {@link Deserializer} for
     * non-transparent frames.
     * @param delimitedDeserializer the Deserializer.
     */
    public RFC6587SyslogDeserializer(Deserializer<byte[]> delimitedDeserializer) {
        this.delimitedDeserializer = delimitedDeserializer;
    }

    /**
     * @param parser the parser to set
     */
    public void setParser(RFC5424SyslogParser parser) {
        this.parser = parser;
    }

    @Override
    public Map<String, ?> deserialize(InputStream inputStream) throws IOException {
        DataInputStream stream = new DataInputStream(inputStream);
        String line;
        int octetCount = 0;
        boolean shortRead = false;
        int peek = stream.read();
        if (isDigit(peek)) {
            octetCount = calculateLength(stream, peek);
            Assert.state(octetCount > 0, "Expected length > 0");
            byte[] bytes = new byte[octetCount];
            try {
                stream.readFully(bytes);
            } catch (EOFException e) {
                shortRead = true;
            }
            line = new String(bytes, getCharset());
        } else if (peek == '<') {
            byte[] bytes = this.delimitedDeserializer.deserialize(inputStream);
            line = "<" + new String(bytes, getCharset());
        } else if (peek < 0) {
            throw new SoftEndOfStreamException();
        } else {
            throw new IllegalStateException("Expected a digit or '<', got 0x" + Integer.toHexString(peek));
        }
        return this.parser.parse(line, octetCount, shortRead);
    }

    private boolean isDigit(int peek) {
        return peek >= 0x30 && peek <= 0x39;
    }

    private int calculateLength(DataInputStream stream, int peek) throws IOException {
        int length = peek & 0xf;
        int c = stream.read();
        while (isDigit(c)) {
            length = length * 10 + (c & 0xf);
            c = stream.read();
        }
        return length;
    }

    protected String getCharset() {
        return "UTF-8";
    }

}